Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
}
benchmark.stopMeasurement()
}

Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
Expand All @@ -105,6 +106,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.clear())
}
benchmark.stopMeasurement()
}

Benchmark("Strings 10") { benchmark in
Expand All @@ -113,6 +115,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str10))
}
benchmark.stopMeasurement()
}

Benchmark("Strings 100") { benchmark in
Expand All @@ -121,6 +124,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str100))
}
benchmark.stopMeasurement()
}

Benchmark("Vector 1 Bytes") { benchmark in
Expand All @@ -129,6 +133,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes))
}
benchmark.stopMeasurement()
}

Benchmark("Vector 1 Ints") { benchmark in
Expand All @@ -137,6 +142,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.createVector(ints))
}
benchmark.stopMeasurement()
}

Benchmark("Vector 100 Ints") { benchmark in
Expand All @@ -145,6 +151,7 @@ let benchmarks = {
for i in benchmark.scaledIterations {
blackHole(fb.createVector(ints))
}
benchmark.stopMeasurement()
}

Benchmark("Vector 100 Bytes") { benchmark in
Expand All @@ -153,6 +160,7 @@ let benchmarks = {
for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes))
}
benchmark.stopMeasurement()
}

Benchmark("Vector 100 ContiguousBytes") { benchmark in
Expand All @@ -161,6 +169,7 @@ let benchmarks = {
for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes))
}
benchmark.stopMeasurement()
}

Benchmark(
Expand All @@ -178,6 +187,7 @@ let benchmarks = {
fb.add(offset: off, at: 8)
blackHole(fb.endTable(at: s))
}
benchmark.stopMeasurement()
}

Benchmark(
Expand All @@ -190,6 +200,7 @@ let benchmarks = {
let s = fb.startTable(with: 4)
blackHole(fb.endTable(at: s))
}
benchmark.stopMeasurement()
}

Benchmark("Struct") { benchmark in
Expand All @@ -198,6 +209,7 @@ let benchmarks = {
for _ in benchmark.scaledIterations {
blackHole(fb.create(struct: array.first!))
}
benchmark.stopMeasurement()
}

Benchmark("Structs") { benchmark in
Expand All @@ -219,6 +231,7 @@ let benchmarks = {
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
Expand All @@ -239,12 +252,15 @@ let benchmarks = {
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()
}
}
2 changes: 1 addition & 1 deletion src/flatc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const static FlatCOption flatc_options[] = {
"Disable generation of MIN and MAX enumerated values for scoped enums "
"and prefixed enums."},
{"", "swift-implementation-only", "",
"Adds a @_implementationOnly to swift imports"},
"Adds a internal to swift imports"},
{"", "gen-includes", "",
"(deprecated), this is the default behavior. If the original behavior is "
"required (no include statements) use --no-includes."},
Expand Down
10 changes: 9 additions & 1 deletion src/idl_gen_swift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class SwiftGenerator : public BaseGenerator {

if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only
? "@_implementationOnly "
? "internal "
: "");
code_ += "#if canImport(Common)";
code_ += "{{IMPLEMENTONLY}}import Common";
Expand Down Expand Up @@ -770,12 +770,20 @@ class SwiftGenerator : public BaseGenerator {
}
}

void GenIsPresent(const FieldDef& field) {
code_.SetValue("OFFSET", namer_.Constant(field.name));
code_ += "{{ACCESS_TYPE}} var " + namer_.Variable(field) +
"IsPresent: Bool { return "
"{{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v) != 0 }";
}

void GenTableReader(const StructDef& struct_def) {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto& field = **it;
if (field.deprecated) continue;
GenTableReaderFields(field);
GenIsPresent(field);
}
}

Expand Down
7 changes: 7 additions & 0 deletions swift/Sources/Common/Scalar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ public let FileIdLength = 4
/// 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.
#if compiler(>=6.0)
public protocol Scalar: Equatable, BitwiseCopyable {
associatedtype NumericValue
var convertedEndian: NumericValue { get }
}
#else
public protocol Scalar: Equatable {
associatedtype NumericValue
var convertedEndian: NumericValue { get }
}
#endif

extension Scalar where Self: FixedWidthInteger {
/// Converts the value from BigEndian to LittleEndian
Expand Down
105 changes: 100 additions & 5 deletions swift/Sources/FlatBuffers/ByteBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ public struct ByteBuffer {
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
@usableFromInline
final class Storage {
#if compiler(>=6.0)
@usableFromInline
enum Blob {
@frozen enum Blob: ~Copyable {
#if !os(WASI)
case data(Data)
case bytes(ContiguousBytes)
Expand All @@ -36,15 +37,73 @@ public struct ByteBuffer {
case byteBuffer(_InternalByteBuffer)
case array([UInt8])
case pointer(UnsafeMutableRawPointer)

init(_ other: borrowing Blob) {
switch other {
case .data(let data):
self = .data(data)
case .bytes(let contiguousBytes):
self = .bytes(contiguousBytes)
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 {
case .data(let data):
"data: \(data)"
case .bytes(let contiguousBytes):
"bytes: \(contiguousBytes)"
case .byteBuffer(let internalByteBuffer):
"byteBuffer: \(internalByteBuffer)"
case .array(let array):
"array: \(array)"
case .pointer(let unsafeMutableRawPointer):
"pointer: \(unsafeMutableRawPointer)"
}
}
}
#else
@usableFromInline
@frozen enum Blob {
#if !os(WASI)
case data(Data)
case bytes(ContiguousBytes)
#endif

case byteBuffer(_InternalByteBuffer)
case array([UInt8])
case pointer(UnsafeMutableRawPointer)

var description: String {
switch self {
case .data(let data):
return "data: \(data)"
case .bytes(let contiguousBytes):
return "bytes: \(contiguousBytes)"
case .byteBuffer(let internalByteBuffer):
return "byteBuffer: \(internalByteBuffer)"
case .array(let array):
return "array: \(array)"
case .pointer(let unsafeMutableRawPointer):
return "pointer: \(unsafeMutableRawPointer)"
}
}
}
#endif

/// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
private let isOwned: Bool
/// Capacity of UInt8 the buffer can hold
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) {
Expand All @@ -56,12 +115,21 @@ public struct ByteBuffer {
isOwned = true
}

#if compiler(>=6.0)
@usableFromInline
init(blob: borrowing Blob, capacity count: Int) {
capacity = count
retainedBlob = .init(blob)
isOwned = false
}
#else
@usableFromInline
init(blob: Blob, capacity count: Int) {
capacity = count
retainedBlob = blob
isOwned = false
}
#endif

deinit {
guard isOwned else { return }
Expand Down Expand Up @@ -150,6 +218,7 @@ public struct ByteBuffer {

@discardableResult
@inline(__always)
@inlinable
func readWithUnsafeRawPointer<T>(
position: Int,
_ body: (UnsafeRawPointer) throws -> T) rethrows -> T
Expand Down Expand Up @@ -276,6 +345,18 @@ public struct ByteBuffer {
/// - memory: Current memory of the buffer
/// - count: count of bytes
/// - removeBytes: Removes a number of bytes from the current size
#if compiler(>=6.0)
@inline(__always)
init(
blob: borrowing Storage.Blob,
count: Int,
removing removeBytes: Int)
{
_storage = Storage(blob: blob, capacity: count)
_readerIndex = removeBytes
capacity = count
}
#else
@inline(__always)
init(
blob: Storage.Blob,
Expand All @@ -286,6 +367,7 @@ public struct ByteBuffer {
_readerIndex = removeBytes
capacity = count
}
#endif

/// Write stores an object into the buffer directly or indirectly.
///
Expand Down Expand Up @@ -317,13 +399,25 @@ public struct ByteBuffer {
/// - Parameters:
/// - def: Type of the object
/// - position: the index of the object in the buffer
#if compiler(>=6.0)
@inline(__always)
@inlinable
public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
_storage.readWithUnsafeRawPointer(position: position) {
$0.bindMemory(to: T.self, capacity: 1)
.pointee
}
}
#else
@inline(__always)
@inlinable
public func read<T>(def: T.Type, position: Int) -> T {
_storage.readWithUnsafeRawPointer(position: position) {
$0.bindMemory(to: T.self, capacity: 1)
.pointee
}
}
#endif

/// Reads a slice from the memory assuming a type of T
/// - Parameters:
Expand Down Expand Up @@ -412,7 +506,7 @@ public struct ByteBuffer {
/// - 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")
Expand Down Expand Up @@ -464,8 +558,9 @@ public struct ByteBuffer {
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) }
Expand Down
Loading
Loading