Move hashmap creation to runtime
Этот коммит содержится в:
родитель
ae2fc3c8a7
коммит
005665aee6
2 изменённых файлов: 17 добавлений и 36 удалений
41
compiler.go
41
compiler.go
|
@ -1529,44 +1529,13 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
switch keyType := mapType.Key().Underlying().(type) {
|
switch keyType := mapType.Key().Underlying().(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
if keyType.Kind() == types.String {
|
if keyType.Kind() == types.String {
|
||||||
// Create hashmap
|
|
||||||
llvmType := c.mod.GetTypeByName("runtime.hashmap")
|
|
||||||
size := llvm.ConstInt(c.uintptrType, c.targetData.TypeAllocSize(llvmType), false)
|
|
||||||
buf := c.builder.CreateCall(c.allocFunc, []llvm.Value{size}, "")
|
|
||||||
buf = c.builder.CreateBitCast(buf, llvm.PointerType(llvmType, 0), "")
|
|
||||||
|
|
||||||
// Set keySize
|
|
||||||
keySize := c.targetData.TypeAllocSize(llvmKeyType)
|
keySize := c.targetData.TypeAllocSize(llvmKeyType)
|
||||||
keyIndices := []llvm.Value{
|
|
||||||
llvm.ConstInt(llvm.Int32Type(), 0, false),
|
|
||||||
llvm.ConstInt(llvm.Int32Type(), 3, false), // keySize uint8
|
|
||||||
}
|
|
||||||
keySizePtr := c.builder.CreateGEP(buf, keyIndices, "hashmap.keySize")
|
|
||||||
c.builder.CreateStore(llvm.ConstInt(llvm.Int8Type(), keySize, false), keySizePtr)
|
|
||||||
|
|
||||||
// Set valueSize
|
|
||||||
valueSize := c.targetData.TypeAllocSize(llvmValueType)
|
valueSize := c.targetData.TypeAllocSize(llvmValueType)
|
||||||
valueIndices := []llvm.Value{
|
hashmapMake := c.mod.NamedFunction("runtime.hashmapMake")
|
||||||
llvm.ConstInt(llvm.Int32Type(), 0, false),
|
llvmKeySize := llvm.ConstInt(llvm.Int8Type(), keySize, false)
|
||||||
llvm.ConstInt(llvm.Int32Type(), 4, false), // valueSize uint8
|
llvmValueSize := llvm.ConstInt(llvm.Int8Type(), valueSize, false)
|
||||||
}
|
hashmap := c.builder.CreateCall(hashmapMake, []llvm.Value{llvmKeySize, llvmValueSize}, "")
|
||||||
valueSizePtr := c.builder.CreateGEP(buf, valueIndices, "hashmap.valueSize")
|
return hashmap, nil
|
||||||
c.builder.CreateStore(llvm.ConstInt(llvm.Int8Type(), valueSize, false), valueSizePtr)
|
|
||||||
|
|
||||||
// Create initial bucket
|
|
||||||
bucketType := c.mod.GetTypeByName("runtime.hashmapBucket")
|
|
||||||
bucketSize := c.targetData.TypeAllocSize(bucketType) + keySize*8 + valueSize*8
|
|
||||||
bucketSizeValue := llvm.ConstInt(c.uintptrType, bucketSize, false)
|
|
||||||
bucket := c.builder.CreateCall(c.allocFunc, []llvm.Value{bucketSizeValue}, "")
|
|
||||||
|
|
||||||
// Set initial bucket
|
|
||||||
bucketIndices := []llvm.Value{
|
|
||||||
llvm.ConstInt(llvm.Int32Type(), 0, false),
|
|
||||||
llvm.ConstInt(llvm.Int32Type(), 1, false), // buckets unsafe.Pointer
|
|
||||||
}
|
|
||||||
bucketsElementPtr := c.builder.CreateGEP(buf, bucketIndices, "hashmap.buckets")
|
|
||||||
c.builder.CreateStore(bucket, bucketsElementPtr)
|
|
||||||
return buf, nil
|
|
||||||
} else {
|
} else {
|
||||||
return llvm.Value{}, errors.New("todo: map key type: " + keyType.String())
|
return llvm.Value{}, errors.New("todo: map key type: " + keyType.String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,18 @@ func stringhash(s *string) uint32 {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new hashmap with the given keySize and valueSize.
|
||||||
|
func hashmapMake(keySize, valueSize uint8) *hashmap {
|
||||||
|
bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + uintptr(keySize)*8 + uintptr(valueSize)*8
|
||||||
|
bucket := alloc(bucketBufSize)
|
||||||
|
return &hashmap{
|
||||||
|
buckets: bucket,
|
||||||
|
keySize: keySize,
|
||||||
|
valueSize: valueSize,
|
||||||
|
bucketBits: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set a specified key to a given value. Grow the map if necessary.
|
// Set a specified key to a given value. Grow the map if necessary.
|
||||||
func hashmapSet(m *hashmap, key string, value unsafe.Pointer) {
|
func hashmapSet(m *hashmap, key string, value unsafe.Pointer) {
|
||||||
hash := stringhash(&key)
|
hash := stringhash(&key)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче