Skip to content

[Runtime] Create an external generic metadata builder. #70771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 11, 2024
Merged
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
55 changes: 31 additions & 24 deletions include/swift/ABI/ValueWitnessTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@

namespace swift {

struct TypeLayout;
template <typename Runtime>
struct TargetTypeLayout;
template <class Runtime> struct TargetEnumValueWitnessTable;
template <typename Runtime> struct TargetMetadata;
using Metadata = TargetMetadata<InProcess>;
Expand Down Expand Up @@ -120,7 +121,7 @@ class TargetValueWitnessTypes {
// types for the flags enums.
typedef size_t size;
typedef size_t stride;
typedef ValueWitnessFlags flags;
typedef TargetValueWitnessFlags<typename Runtime::StoredSize> flags;
typedef uint32_t extraInhabitantCount;
};

Expand Down Expand Up @@ -214,8 +215,8 @@ template <typename Runtime> struct TargetValueWitnessTable {
const TargetEnumValueWitnessTable<Runtime> *_asEVWT() const;

/// Get the type layout record within this value witness table.
const TypeLayout *getTypeLayout() const {
return reinterpret_cast<const TypeLayout *>(&size);
const TargetTypeLayout<Runtime> *getTypeLayout() const {
return reinterpret_cast<const TargetTypeLayout<Runtime> *>(&size);
}

/// Check whether this metadata is complete.
Expand All @@ -224,7 +225,7 @@ template <typename Runtime> struct TargetValueWitnessTable {
/// "Publish" the layout of this type to other threads. All other stores
/// to the value witness table (including its extended header) should have
/// happened before this is called.
void publishLayout(const TypeLayout &layout);
void publishLayout(const TargetTypeLayout<Runtime> &layout);
};

/// A value-witness table with enum entry points.
Expand Down Expand Up @@ -275,23 +276,27 @@ TargetValueWitnessTable<Runtime>::_asEVWT() const {
/// necessary to perform dependent layout of generic value types. It excludes
/// the value witness functions and includes only the size, alignment,
/// extra inhabitants, and miscellaneous flags about the type.
struct TypeLayout {
ValueWitnessTypes::size size;
ValueWitnessTypes::stride stride;
ValueWitnessTypes::flags flags;
ValueWitnessTypes::extraInhabitantCount extraInhabitantCount;
template <typename Runtime>
struct TargetTypeLayout {
typename TargetValueWitnessTypes<Runtime>::size size;
typename TargetValueWitnessTypes<Runtime>::stride stride;
typename TargetValueWitnessTypes<Runtime>::flags flags;
typename TargetValueWitnessTypes<Runtime>::extraInhabitantCount
extraInhabitantCount;

private:
void _static_assert_layout();
public:
TypeLayout() = default;
constexpr TypeLayout(ValueWitnessTypes::size size,
ValueWitnessTypes::stride stride,
ValueWitnessTypes::flags flags,
ValueWitnessTypes::extraInhabitantCount xiCount)
: size(size), stride(stride), flags(flags), extraInhabitantCount(xiCount) {}
TargetTypeLayout() = default;
constexpr TargetTypeLayout(
typename TargetValueWitnessTypes<Runtime>::size size,
typename TargetValueWitnessTypes<Runtime>::stride stride,
typename TargetValueWitnessTypes<Runtime>::flags flags,
typename TargetValueWitnessTypes<Runtime>::extraInhabitantCount xiCount)
: size(size), stride(stride), flags(flags),
extraInhabitantCount(xiCount) {}

const TypeLayout *getTypeLayout() const { return this; }
const TargetTypeLayout *getTypeLayout() const { return this; }

/// The number of extra inhabitants, that is, bit patterns that do not form
/// valid values of the type, in this type's binary representation.
Expand All @@ -303,14 +308,16 @@ struct TypeLayout {
return extraInhabitantCount != 0;
}
};
using TypeLayout = TargetTypeLayout<InProcess>;

inline void TypeLayout::_static_assert_layout() {
#define CHECK_TYPE_LAYOUT_OFFSET(FIELD) \
static_assert(offsetof(ValueWitnessTable, FIELD) \
- offsetof(ValueWitnessTable, size) \
== offsetof(TypeLayout, FIELD), \
"layout of " #FIELD " in TypeLayout doesn't match " \
"value witness table")
template <typename Runtime>
inline void TargetTypeLayout<Runtime>::_static_assert_layout() {
#define CHECK_TYPE_LAYOUT_OFFSET(FIELD) \
static_assert(offsetof(TargetValueWitnessTable<Runtime>, FIELD) - \
offsetof(TargetValueWitnessTable<Runtime>, size) == \
offsetof(TargetTypeLayout<Runtime>, FIELD), \
"layout of " #FIELD " in TypeLayout doesn't match " \
"value witness table")
CHECK_TYPE_LAYOUT_OFFSET(size);
CHECK_TYPE_LAYOUT_OFFSET(flags);
CHECK_TYPE_LAYOUT_OFFSET(extraInhabitantCount);
Expand Down
38 changes: 38 additions & 0 deletions include/swift/Basic/MathUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===--- GenericMetadataBuilder.h - Math utilities. -------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Utility functions for math operations.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_MATH_UTILS_H
#define SWIFT_BASIC_MATH_UTILS_H

#include <cstddef>

namespace swift {

/// Round the given value up to the given alignment, as a power of two.
template <class T>
static inline constexpr T roundUpToAlignment(T offset, T alignment) {
return (offset + alignment - 1) & ~(alignment - 1);
}

/// Round the given value up to the given alignment, expressed as a mask (a
/// power of two minus one).
static inline size_t roundUpToAlignMask(size_t size, size_t alignMask) {
return (size + alignMask) & ~alignMask;
}

} // namespace swift

#endif // #ifndef SWIFT_BASIC_MATH_UTILS_H
4 changes: 2 additions & 2 deletions include/swift/Demangling/TypeLookupError.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ class TypeLookupError {
/// Get the error string from the error value. The value must be passed to
/// `freeErrorString` when done. (Unless you're just calling a `fatalError`
/// in which case there's no point.)
char *copyErrorString() {
char *copyErrorString() const {
return reinterpret_cast<char *>(
Fn(Context, Command::CopyErrorString, nullptr));
}

/// Free an error string previously obtained from `copyErrorString`.
void freeErrorString(char *str) {
void freeErrorString(char *str) const {
Fn(Context, Command::DestroyErrorString, str);
}
};
Expand Down
6 changes: 1 addition & 5 deletions include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "swift/Demangling/TypeDecoder.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/ExternalUnion.h"
#include "swift/Basic/MathUtils.h"
#include "swift/Basic/Range.h"
#include "swift/Basic/LLVM.h"
#include "swift/ABI/TypeIdentity.h"
Expand Down Expand Up @@ -3419,11 +3420,6 @@ class MetadataReader {

return finish(TaggedPointerEncodingKind::Extended);
}

template <class T>
static constexpr T roundUpToAlignment(T offset, T alignment) {
return (offset + alignment - 1) & ~(alignment - 1);
}
};

} // end namespace remote
Expand Down
4 changes: 3 additions & 1 deletion include/swift/Runtime/Enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ using Metadata = TargetMetadata<InProcess>;

template <typename Runtime> struct TargetEnumMetadata;
using EnumMetadata = TargetEnumMetadata<InProcess>;
struct TypeLayout;
template <typename Runtime>
struct TargetTypeLayout;
using TypeLayout = TargetTypeLayout<InProcess>;

/// Initialize the type metadata for a single-case enum type.
///
Expand Down
Loading