swift 6.0+ performance tweaks 3x-6x  (#9067)

* start/stop measurements

* tweaks

* add 6.0 annotations

* remove some inlines

* address feedback

* address wasi + let

* adopt flex buffers

* flex buffers benchmarks
diff --git a/benchmarks/swift/Benchmarks/FlatbuffersBenchmarks/FlatbuffersBenchmarks.swift b/benchmarks/swift/Benchmarks/FlatbuffersBenchmarks/FlatbuffersBenchmarks.swift
index 4607f58..aa08568 100644
--- a/benchmarks/swift/Benchmarks/FlatbuffersBenchmarks/FlatbuffersBenchmarks.swift
+++ b/benchmarks/swift/Benchmarks/FlatbuffersBenchmarks/FlatbuffersBenchmarks.swift
@@ -97,6 +97,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
@@ -105,6 +106,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.clear())
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Strings 10") { benchmark in
@@ -113,6 +115,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.create(string: str10))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Strings 100") { benchmark in
@@ -121,6 +124,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.create(string: str100))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector 1 Bytes") { benchmark in
@@ -129,6 +133,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.createVector(bytes: bytes))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector 1 Ints") { benchmark in
@@ -137,6 +142,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.createVector(ints))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector 100 Ints") { benchmark in
@@ -145,6 +151,7 @@
     for i in benchmark.scaledIterations {
       blackHole(fb.createVector(ints))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector 100 Bytes") { benchmark in
@@ -153,6 +160,7 @@
     for i in benchmark.scaledIterations {
       blackHole(fb.createVector(bytes))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector 100 ContiguousBytes") { benchmark in
@@ -161,6 +169,7 @@
     for i in benchmark.scaledIterations {
       blackHole(fb.createVector(bytes: bytes))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark(
@@ -178,6 +187,7 @@
       fb.add(offset: off, at: 8)
       blackHole(fb.endTable(at: s))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark(
@@ -190,6 +200,7 @@
       let s = fb.startTable(with: 4)
       blackHole(fb.endTable(at: s))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Struct") { benchmark in
@@ -198,6 +209,7 @@
     for _ in benchmark.scaledIterations {
       blackHole(fb.create(struct: array.first!))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Structs") { benchmark in
@@ -219,6 +231,7 @@
     fb.add(offset: vector, at: 4)
     let root = Offset(offset: fb.endTable(at: start))
     blackHole(fb.finish(offset: root))
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Vector of Offsets") { benchmark in
@@ -239,12 +252,15 @@
       fb.add(offset: off, at: 2)
       blackHole(fb.endTable(at: s))
     }
+    benchmark.stopMeasurement()
   }
 
   Benchmark("Reading Doubles") { benchmark in
     let byteBuffer = ByteBuffer(data: data)
+    benchmark.startMeasurement()
     for _ in benchmark.scaledIterations {
       blackHole(byteBuffer.read(def: Double.self, position: 0))
     }
+    benchmark.stopMeasurement()
   }
 }
diff --git a/benchmarks/swift/Benchmarks/FlexBuffersBenchmarks/FlexBuffersBenchmarks.swift b/benchmarks/swift/Benchmarks/FlexBuffersBenchmarks/FlexBuffersBenchmarks.swift
new file mode 100644
index 0000000..22d0d54
--- /dev/null
+++ b/benchmarks/swift/Benchmarks/FlexBuffersBenchmarks/FlexBuffersBenchmarks.swift
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2024 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Benchmark
+import FlexBuffers
+import Foundation
+
+let benchmarks = {
+  let data = {
+    var array = [8888.88, 8888.88]
+    var data = Data()
+    array.withUnsafeBytes { ptr in
+      data.append(contentsOf: ptr)
+    }
+    return data
+  }()
+  let ints: [Int32] = Array(repeating: 42, count: 100)
+  let str10 = (0...9).map { _ -> String in "x" }.joined()
+  let str100 = (0...99).map { _ -> String in "x" }.joined()
+
+  // A representative map: 50 keyed scalars, a keyed string and a keyed vector
+  // of 100 scalars. Used for the realistic decode benchmarks.
+  let mapBuffer: ByteBuffer = {
+    var fbx = FlexBuffersWriter(initialSize: 1 << 16)
+    fbx.map {
+      for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
+      $0.add(string: "hello world", key: "s")
+      $0.vector(key: "v") { v in
+        for x in 0..<100 { v.add(int: x) }
+      }
+    }
+    fbx.finish()
+    return fbx.sizedByteBuffer
+  }()
+
+  let metrics: [BenchmarkMetric] = [
+    .cpuTotal,
+    .wallClock,
+    .mallocCountTotal,
+    .releaseCount,
+    .peakMemoryResident,
+  ]
+  let maxIterations = 1_000_000
+  let maxDuration: Duration = .seconds(3)
+  let megaConfiguration: Benchmark.Configuration = .init(
+    metrics: metrics,
+    warmupIterations: 1,
+    scalingFactor: .mega,
+    maxDuration: maxDuration,
+    maxIterations: maxIterations)
+
+  Benchmark.defaultConfiguration = megaConfiguration
+
+  // Decode (read path)
+
+  // Raw scalar read: isolates `read<T: BitwiseCopyable>` and the `let` blob.
+  Benchmark("Reading Doubles") { benchmark in
+    let byteBuffer = ByteBuffer(data: data)
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      blackHole(byteBuffer.read(def: Double.self, position: 0))
+    }
+    benchmark.stopMeasurement()
+  }
+
+  // Realistic decode: resolve root map and read a keyed scalar.
+  Benchmark("Decode Map Scalar") { benchmark in
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      let map = try! getRoot(buffer: mapBuffer)!.map!
+      blackHole(map["i25"]?.int)
+    }
+    benchmark.stopMeasurement()
+  }
+
+  // Realistic decode: resolve root map and read a keyed string.
+  Benchmark("Decode Map String") { benchmark in
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      let map = try! getRoot(buffer: mapBuffer)!.map!
+      blackHole(map["s"]?.string())
+    }
+    benchmark.stopMeasurement()
+  }
+
+  // Realistic decode: resolve a nested vector and sum its scalars.
+  Benchmark("Decode Vector") { benchmark in
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      let map = try! getRoot(buffer: mapBuffer)!.map!
+      let vector = map["v"]!.vector!
+      var sum: Int64 = 0
+      for i in 0..<vector.count {
+        sum &+= vector[i]?.int ?? 0
+      }
+      blackHole(sum)
+    }
+    benchmark.stopMeasurement()
+  }
+
+  // Encode (write path)
+  // Writers are reused with `reset(keepingCapacity:)` so per-iteration
+  // allocation does not dominate and mask the write-path cost (which is what
+  // the `@exclusivity(unchecked)` storage pointer affects).
+
+  Benchmark("Strings 10") { benchmark in
+    var fbx = FlexBuffersWriter(initialSize: 1 << 20)
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      fbx.add(string: str10)
+      fbx.finish()
+      blackHole(fbx.sizedByteBuffer)
+      fbx.reset(keepingCapacity: true)
+    }
+    benchmark.stopMeasurement()
+  }
+
+  Benchmark("Strings 100") { benchmark in
+    var fbx = FlexBuffersWriter(initialSize: 1 << 20)
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      fbx.add(string: str100)
+      fbx.finish()
+      blackHole(fbx.sizedByteBuffer)
+      fbx.reset(keepingCapacity: true)
+    }
+    benchmark.stopMeasurement()
+  }
+
+  Benchmark("Encoding Vector Of Ints") { benchmark in
+    var fbx = FlexBuffersWriter(initialSize: 1 << 20)
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      fbx.vector {
+        $0.create(vector: ints)
+      }
+      fbx.finish()
+      blackHole(fbx.sizedByteBuffer)
+      fbx.reset(keepingCapacity: true)
+    }
+    benchmark.stopMeasurement()
+  }
+
+  Benchmark("Encoding Map") { benchmark in
+    var fbx = FlexBuffersWriter(initialSize: 1 << 20)
+    benchmark.startMeasurement()
+    for _ in benchmark.scaledIterations {
+      fbx.map {
+        for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
+        $0.add(string: "hello world", key: "s")
+        $0.vector(key: "v") { v in
+          for x in 0..<100 { v.add(int: x) }
+        }
+      }
+      fbx.finish()
+      blackHole(fbx.sizedByteBuffer)
+      fbx.reset(keepingCapacity: true)
+    }
+    benchmark.stopMeasurement()
+  }
+}
diff --git a/benchmarks/swift/Package.swift b/benchmarks/swift/Package.swift
index 1187329..41b536c 100644
--- a/benchmarks/swift/Package.swift
+++ b/benchmarks/swift/Package.swift
@@ -39,4 +39,14 @@
       plugins: [
         .plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
       ]),
+    .executableTarget(
+      name: "FlexBuffersBenchmarks",
+      dependencies: [
+        .product(name: "FlexBuffers", package: "flatbuffers"),
+        .product(name: "Benchmark", package: "package-benchmark"),
+      ],
+      path: "Benchmarks/FlexBuffersBenchmarks",
+      plugins: [
+        .plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
+      ]),
   ])
diff --git a/swift/Sources/Common/Scalar.swift b/swift/Sources/Common/Scalar.swift
index 518580a..5c6a6c8 100644
--- a/swift/Sources/Common/Scalar.swift
+++ b/swift/Sources/Common/Scalar.swift
@@ -28,7 +28,7 @@
 /// Protocol that All Scalars should conform to
 ///
 /// Scalar is used to conform all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
-public protocol Scalar: Equatable {
+public protocol Scalar: Equatable, BitwiseCopyable {
   associatedtype NumericValue
   var convertedEndian: NumericValue { get }
 }
diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift
index f8b59ee..f22ecff 100644
--- a/swift/Sources/FlatBuffers/ByteBuffer.swift
+++ b/swift/Sources/FlatBuffers/ByteBuffer.swift
@@ -27,7 +27,7 @@
   @usableFromInline
   final class Storage {
     @usableFromInline
-    enum Blob {
+    @frozen enum Blob: ~Copyable {
       #if !os(WASI)
       case data(Data)
       case bytes(any ContiguousBytes)
@@ -36,6 +36,40 @@
       case byteBuffer(_InternalByteBuffer)
       case array([UInt8])
       case pointer(UnsafeMutableRawPointer)
+
+      init(_ other: borrowing Blob) {
+        switch other {
+        #if !os(WASI)
+        case .data(let data):
+          self = .data(data)
+        case .bytes(let contiguousBytes):
+          self = .bytes(contiguousBytes)
+        #endif
+        case .byteBuffer(let internalByteBuffer):
+          self = .byteBuffer(internalByteBuffer)
+        case .array(let array):
+          self = .array(array)
+        case .pointer(let unsafeMutableRawPointer):
+          self = .pointer(unsafeMutableRawPointer)
+        }
+      }
+
+      var description: String {
+        switch self {
+        #if !os(WASI)
+        case .data(let data):
+          "data: \(data)"
+        case .bytes(let contiguousBytes):
+          "bytes: \(contiguousBytes)"
+        #endif
+        case .byteBuffer(let internalByteBuffer):
+          "byteBuffer: \(internalByteBuffer)"
+        case .array(let array):
+          "array: \(array)"
+        case .pointer(let unsafeMutableRawPointer):
+          "pointer: \(unsafeMutableRawPointer)"
+        }
+      }
     }
 
     /// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
@@ -44,7 +78,7 @@
     private let capacity: Int
     /// Retained blob of data that requires the storage to retain a pointer to.
     @usableFromInline
-    var retainedBlob: Blob
+    let retainedBlob: Blob
 
     @usableFromInline
     init(count: Int) {
@@ -57,9 +91,9 @@
     }
 
     @usableFromInline
-    init(blob: Blob, capacity count: Int) {
+    init(blob: borrowing Blob, capacity count: Int) {
       capacity = count
-      retainedBlob = blob
+      retainedBlob = .init(blob)
       isOwned = false
     }
 
@@ -150,6 +184,7 @@
 
     @discardableResult
     @inline(__always)
+    @inlinable
     func readWithUnsafeRawPointer<T>(
       position: Int,
       _ body: (UnsafeRawPointer) throws -> T) rethrows -> T
@@ -278,7 +313,7 @@
   ///   - removeBytes: Removes a number of bytes from the current size
   @inline(__always)
   init(
-    blob: Storage.Blob,
+    blob: borrowing Storage.Blob,
     count: Int,
     removing removeBytes: Int)
   {
@@ -318,7 +353,8 @@
   ///   - def: Type of the object
   ///   - position: the index of the object in the buffer
   @inline(__always)
-  public func read<T>(def: T.Type, position: Int) -> T {
+  @inlinable
+  public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
     _storage.readWithUnsafeRawPointer(position: position) {
       $0.bindMemory(to: T.self, capacity: 1)
         .pointee
@@ -412,7 +448,7 @@
   /// - Parameter removeBytes: the amount of bytes to remove from the current Size
   @inline(__always)
   public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
-    assert(removeBytes > 0, "Can NOT remove negative bytes")
+    assert(removeBytes >= 0, "Can NOT remove negative bytes")
     assert(
       removeBytes < capacity,
       "Can NOT remove more bytes than the ones allocated")
@@ -464,8 +500,9 @@
 extension ByteBuffer: CustomDebugStringConvertible {
 
   public var debugDescription: String {
-    """
-    buffer located at: \(_storage.retainedBlob), 
+    let blobDescription = _storage.retainedBlob.description
+    return """
+    buffer located at: \(blobDescription), 
     with capacity of \(capacity),
     { writtenSize: \(_readerIndex), readerSize: \(reader), 
     size: \(size) }
diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
index b8e49bd..d9cc0a9 100644
--- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
@@ -47,7 +47,8 @@
   /// A check to see if finish(::) was ever called to retreive data object
   private(set) var finished = false
   /// A check to see if the buffer should serialize Default values
-  private var serializeDefaults: Bool
+  @usableFromInline
+  let serializeDefaults: Bool
 
   /// Current alignment for the buffer
   var _minAlignment: Int = 0 {
@@ -756,6 +757,7 @@
   ///   - offset: ``Offset`` of another object to be written
   ///   - position: The predefined position of the object
   @inline(__always)
+  @inlinable
   mutating public func add(offset: Offset, at position: VOffset) {
     if offset.isEmpty { return }
     add(element: refer(to: offset.o), def: 0, at: position)
@@ -794,6 +796,7 @@
   ///   - def: Default value for that element
   ///   - position: The predefined position of the element
   @inline(__always)
+  @inlinable
   mutating public func add<T: Scalar>(
     element: T,
     def: T,
@@ -813,6 +816,7 @@
   ///   - element: Optional element of type scalar
   ///   - position: The predefined position of the element
   @inline(__always)
+  @inlinable
   mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
     guard let element = element else { return }
     track(offset: push(element: element), at: position)
@@ -825,6 +829,7 @@
   /// - Parameter element: Element to insert
   /// - returns: position of the Element
   @inline(__always)
+  @inlinable
   @discardableResult
   mutating public func push<T: Scalar>(element: T) -> UOffset {
     let size = MemoryLayout<T>.size
@@ -836,7 +841,8 @@
   }
 
   @inline(__always)
-  public func read<T>(def: T.Type, position: Int) -> T {
+  @inlinable
+  public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
     _bb.read(def: def, position: position)
   }
 }
diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift
index a85f107..dce4512 100644
--- a/swift/Sources/FlatBuffers/FlatBufferObject.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift
@@ -18,7 +18,7 @@
 
 /// NativeStruct is a protocol that indicates if the struct is a native `swift` struct
 /// since now we will be serializing native structs into the buffer.
-public protocol NativeStruct {}
+public protocol NativeStruct: BitwiseCopyable {}
 
 public protocol FlatBufferVerifiableNativeStruct: NativeStruct, Verifiable {}
 
diff --git a/swift/Sources/FlatBuffers/Table.swift b/swift/Sources/FlatBuffers/Table.swift
index f29a51e..de87626 100644
--- a/swift/Sources/FlatBuffers/Table.swift
+++ b/swift/Sources/FlatBuffers/Table.swift
@@ -82,7 +82,7 @@
   /// - Parameters:
   ///   - type: Type of Element that needs to be read from the buffer
   ///   - o: Offset of the Element
-  public func readBuffer<T>(of type: T.Type, at o: Int32) -> T {
+  public func readBuffer<T: BitwiseCopyable>(of type: T.Type, at o: Int32) -> T {
     bb.read(def: T.self, position: Int(o &+ position))
   }
 
diff --git a/swift/Sources/FlatBuffers/Verifier.swift b/swift/Sources/FlatBuffers/Verifier.swift
index b0ef396..525e149 100644
--- a/swift/Sources/FlatBuffers/Verifier.swift
+++ b/swift/Sources/FlatBuffers/Verifier.swift
@@ -163,7 +163,7 @@
   /// - Parameter position: Current position to be read
   /// - Throws: `inBuffer` errors
   /// - Returns: a value of type `T` usually a `VTable` or a table offset
-  internal func getValue<T>(at position: Int) throws -> T {
+  internal func getValue<T: BitwiseCopyable>(at position: Int) throws -> T {
     try inBuffer(position: position, of: T.self)
     return _buffer.read(def: T.self, position: position)
   }
diff --git a/swift/Sources/FlatBuffers/_InternalByteBuffer.swift b/swift/Sources/FlatBuffers/_InternalByteBuffer.swift
index e4ed2f0..a3d7308 100644
--- a/swift/Sources/FlatBuffers/_InternalByteBuffer.swift
+++ b/swift/Sources/FlatBuffers/_InternalByteBuffer.swift
@@ -30,7 +30,7 @@
   @usableFromInline
   final class Storage {
     /// pointer to the start of the buffer object in memory
-    private(set) var memory: UnsafeMutableRawPointer
+    @exclusivity(unchecked) private(set) var memory: UnsafeMutableRawPointer
 
     @usableFromInline
     init(count: Int, alignment: Int) {
@@ -333,6 +333,7 @@
 
   @discardableResult
   @inline(__always)
+  @usableFromInline
   func readWithUnsafeRawPointer<T>(
     position: Int,
     _ body: (UnsafeRawPointer) throws -> T) rethrows -> T
diff --git a/swift/Sources/FlexBuffers/ByteBuffer.swift b/swift/Sources/FlexBuffers/ByteBuffer.swift
index f4dd2ad..6789618 100644
--- a/swift/Sources/FlexBuffers/ByteBuffer.swift
+++ b/swift/Sources/FlexBuffers/ByteBuffer.swift
@@ -27,7 +27,7 @@
   @usableFromInline
   final class Storage {
     @usableFromInline
-    enum Blob {
+    @frozen enum Blob: ~Copyable {
       #if !os(WASI)
       case data(Data)
       case bytes(any ContiguousBytes)
@@ -36,6 +36,23 @@
       case byteBuffer(_InternalByteBuffer)
       case array([UInt8])
       case pointer(UnsafeMutableRawPointer)
+
+      init(_ other: borrowing Blob) {
+        switch other {
+        #if !os(WASI)
+        case .data(let data):
+          self = .data(data)
+        case .bytes(let contiguousBytes):
+          self = .bytes(contiguousBytes)
+        #endif
+        case .byteBuffer(let internalByteBuffer):
+          self = .byteBuffer(internalByteBuffer)
+        case .array(let array):
+          self = .array(array)
+        case .pointer(let unsafeMutableRawPointer):
+          self = .pointer(unsafeMutableRawPointer)
+        }
+      }
     }
 
     /// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
@@ -44,7 +61,7 @@
     private let capacity: Int
     /// Retained blob of data that requires the storage to retain a pointer to.
     @usableFromInline
-    var retainedBlob: Blob
+    let retainedBlob: Blob
 
     @usableFromInline
     init(count: Int) {
@@ -57,9 +74,9 @@
     }
 
     @usableFromInline
-    init(blob: Blob, capacity count: Int) {
+    init(blob: borrowing Blob, capacity count: Int) {
       capacity = count
-      retainedBlob = blob
+      retainedBlob = .init(blob)
       isOwned = false
     }
 
@@ -276,7 +293,7 @@
   ///   - removeBytes: Removes a number of bytes from the current size
   @inline(__always)
   init(
-    blob: Storage.Blob,
+    blob: borrowing Storage.Blob,
     count: Int,
     removing removeBytes: Int)
   {
@@ -316,7 +333,7 @@
   ///   - def: Type of the object
   ///   - position: the index of the object in the buffer
   @inline(__always)
-  public func read<T>(def: T.Type, position: Int) -> T {
+  public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
     _storage.readWithUnsafeRawPointer(position: position) {
       $0.bindMemory(to: T.self, capacity: 1)
         .pointee
@@ -360,10 +377,10 @@
   @inline(__always)
   func readSizedScalar<
     T: BinaryInteger,
-    T1: BinaryInteger,
-    T2: BinaryInteger,
-    T3: BinaryInteger,
-    T4: BinaryInteger
+    T1: BinaryInteger & BitwiseCopyable,
+    T2: BinaryInteger & BitwiseCopyable,
+    T3: BinaryInteger & BitwiseCopyable,
+    T4: BinaryInteger & BitwiseCopyable
   >(
     def: T.Type,
     t1: T1.Type,
diff --git a/swift/Sources/FlexBuffers/_InternalByteBuffer.swift b/swift/Sources/FlexBuffers/_InternalByteBuffer.swift
index 5df4ff3..e99f95a 100644
--- a/swift/Sources/FlexBuffers/_InternalByteBuffer.swift
+++ b/swift/Sources/FlexBuffers/_InternalByteBuffer.swift
@@ -31,7 +31,7 @@
   @usableFromInline
   final class Storage {
     /// pointer to the start of the buffer object in memory
-    var memory: UnsafeMutableRawPointer
+    @exclusivity(unchecked) private(set) var memory: UnsafeMutableRawPointer
 
     @usableFromInline
     init(count: Int, alignment: Int) {