Skip to content

[NFC] Factor out ASTContext operator news #38948

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
Aug 20, 2021
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
73 changes: 73 additions & 0 deletions include/swift/AST/ASTAllocated.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===--- ASTAllocated.h - Allocation in the AST Context ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_ASTALLOCATED_H
#define SWIFT_AST_ASTALLOCATED_H

#include <cassert>
#include <cstddef>

namespace swift {
class ASTContext;

/// The arena in which a particular ASTContext allocation will go.
enum class AllocationArena {
/// The permanent arena, which is tied to the lifetime of
/// the ASTContext.
///
/// All global declarations and types need to be allocated into this arena.
/// At present, everything that is not a type involving a type variable is
/// allocated in this arena.
Permanent,
/// The constraint solver's temporary arena, which is tied to the
/// lifetime of a particular instance of the constraint solver.
///
/// Any type involving a type variable is allocated in this arena.
ConstraintSolver
};

namespace detail {
void *allocateInASTContext(size_t bytes, const ASTContext &ctx,
AllocationArena arena, unsigned alignment);
}

/// Types inheriting from this class are intended to be allocated in an
/// \c ASTContext allocator; you cannot allocate them by using a normal \c new,
/// and instead you must either provide an \c ASTContext or use a placement
/// \c new.
///
/// The template parameter is a type with the desired alignment. It is usually,
/// but not always, the type that is inheriting \c ASTAllocated.
template <typename AlignTy>
class ASTAllocated {
public:
// Make vanilla new/delete illegal.
void *operator new(size_t Bytes) throw() = delete;
void operator delete(void *Data) throw() = delete;

// Only allow allocation using the allocator in ASTContext
// or by doing a placement new.
void *operator new(size_t bytes, const ASTContext &ctx,
AllocationArena arena = AllocationArena::Permanent,
unsigned alignment = alignof(AlignTy)) {
return detail::allocateInASTContext(bytes, ctx, arena, alignment);
}

void *operator new(size_t Bytes, void *Mem) throw() {
assert(Mem && "placement new into failed allocation");
return Mem;
}
};

}

#endif
17 changes: 1 addition & 16 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef SWIFT_AST_ASTCONTEXT_H
#define SWIFT_AST_ASTCONTEXT_H

#include "swift/AST/ASTAllocated.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/Identifier.h"
Expand Down Expand Up @@ -145,22 +146,6 @@ namespace syntax {
class SyntaxArena;
}

/// The arena in which a particular ASTContext allocation will go.
enum class AllocationArena {
/// The permanent arena, which is tied to the lifetime of
/// the ASTContext.
///
/// All global declarations and types need to be allocated into this arena.
/// At present, everything that is not a type involving a type variable is
/// allocated in this arena.
Permanent,
/// The constraint solver's temporary arena, which is tied to the
/// lifetime of a particular instance of the constraint solver.
///
/// Any type involving a type variable is allocated in this arena.
ConstraintSolver
};

/// Lists the set of "known" Foundation entities that are used in the
/// compiler.
///
Expand Down
26 changes: 2 additions & 24 deletions include/swift/AST/ASTScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ SourceLoc extractNearestSourceLoc(std::tuple<ASTScopeImpl *, ScopeCreator *>);
/// \code
/// -dump-scope-maps expanded
/// \endcode
class ASTScopeImpl {
class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
friend class NodeAdder;
friend class Portion;
friend class GenericTypeOrExtensionWholePortion;
Expand Down Expand Up @@ -159,20 +159,9 @@ class ASTScopeImpl {
ASTScopeImpl(const ASTScopeImpl &) = delete;
ASTScopeImpl &operator=(const ASTScopeImpl &) = delete;

// Make vanilla new illegal for ASTScopes.
void *operator new(size_t bytes) = delete;
// Need this because have virtual destructors
void operator delete(void *data) {}

// Only allow allocation of scopes using the allocator of a particular source
// file.
void *operator new(size_t bytes, const ASTContext &ctx,
unsigned alignment = alignof(ASTScopeImpl));
void *operator new(size_t Bytes, void *Mem) {
ASTScopeAssert(Mem, "Allocation failed");
return Mem;
}

#pragma mark - tree declarations
protected:
NullablePtr<ASTScopeImpl> getParent() {
Expand Down Expand Up @@ -425,26 +414,15 @@ class ASTSourceFileScope final : public ASTScopeImpl {
expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);
};

class Portion {
class Portion : public ASTAllocated<ASTScopeImpl> {
public:
const char *portionName;
Portion(const char *n) : portionName(n) {}
virtual ~Portion() {}

// Make vanilla new illegal for ASTScopes.
void *operator new(size_t bytes) = delete;
// Need this because have virtual destructors
void operator delete(void *data) {}

// Only allow allocation of scopes using the allocator of a particular source
// file.
void *operator new(size_t bytes, const ASTContext &ctx,
unsigned alignment = alignof(ASTScopeImpl));
void *operator new(size_t Bytes, void *Mem) {
ASTScopeAssert(Mem, "Allocation failed");
return Mem;
}

/// Return the new insertion point
virtual ASTScopeImpl *expandScope(GenericTypeOrExtensionScope *,
ScopeCreator &) const = 0;
Expand Down
15 changes: 3 additions & 12 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "swift/Basic/OptimizationMode.h"
#include "swift/Basic/Version.h"
#include "swift/Basic/Located.h"
#include "swift/AST/ASTAllocated.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/AttrKind.h"
#include "swift/AST/AutoDiff.h"
Expand Down Expand Up @@ -60,7 +61,8 @@ class PatternBindingInitializer;
class TrailingWhereClause;
class TypeExpr;

class alignas(1 << AttrAlignInBits) AttributeBase {
class alignas(1 << AttrAlignInBits) AttributeBase
: public ASTAllocated<AttributeBase> {
public:
/// The location of the '@'.
const SourceLoc AtLoc;
Expand All @@ -80,17 +82,6 @@ class alignas(1 << AttrAlignInBits) AttributeBase {
return Range;
}

// Only allow allocation of attributes using the allocator in ASTContext
// or by doing a placement new.
void *operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(AttributeBase));

void operator delete(void *Data) throw() { }
void *operator new(size_t Bytes, void *Mem) throw() { return Mem; }

// Make vanilla new/delete illegal for attributes.
void *operator new(size_t Bytes) throw() = delete;

AttributeBase(const AttributeBase &) = delete;

protected:
Expand Down
17 changes: 7 additions & 10 deletions include/swift/AST/AvailabilitySpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ enum class AvailabilitySpecKind {

/// The root class for specifications of API availability in availability
/// queries.
class AvailabilitySpec {
class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
AvailabilitySpecKind Kind;

public:
Expand All @@ -53,12 +53,6 @@ class AvailabilitySpec {
AvailabilitySpecKind getKind() const { return Kind; }

SourceRange getSourceRange() const;

void *
operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(AvailabilitySpec));
void *operator new(size_t Bytes) throw() = delete;
void operator delete(void *Data) throw() = delete;
};

/// An availability specification that guards execution based on the
Expand Down Expand Up @@ -133,7 +127,8 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
void *
operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(PlatformVersionConstraintAvailabilitySpec)){
return AvailabilitySpec::operator new(Bytes, C, Alignment);
return AvailabilitySpec::operator new(Bytes, C, AllocationArena::Permanent,
Alignment);
}
};

Expand Down Expand Up @@ -180,7 +175,8 @@ class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpe
void *
operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(PlatformAgnosticVersionConstraintAvailabilitySpec)){
return AvailabilitySpec::operator new(Bytes, C, Alignment);
return AvailabilitySpec::operator new(Bytes, C, AllocationArena::Permanent,
Alignment);
}
};

Expand Down Expand Up @@ -214,7 +210,8 @@ class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
void *
operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(OtherPlatformAvailabilitySpec)) {
return AvailabilitySpec::operator new(Bytes, C, Alignment);
return AvailabilitySpec::operator new(Bytes, C, AllocationArena::Permanent,
Alignment);
}
};

Expand Down
21 changes: 7 additions & 14 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ enum class ArtificialMainKind : uint8_t {
};

/// Decl - Base class for all declarations in Swift.
class alignas(1 << DeclAlignInBits) Decl {
class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
protected:
union { uint64_t OpaqueBits;

Expand Down Expand Up @@ -1015,19 +1015,6 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Retrieve the diagnostic engine for diagnostics emission.
LLVM_READONLY
DiagnosticEngine &getDiags() const;

// Make vanilla new/delete illegal for Decls.
void *operator new(size_t Bytes) = delete;
void operator delete(void *Data) = delete;

// Only allow allocation of Decls using the allocator in ASTContext
// or by doing a placement new.
void *operator new(size_t Bytes, const ASTContext &C,
unsigned Alignment = alignof(Decl));
void *operator new(size_t Bytes, void *Mem) {
assert(Mem);
return Mem;
}
};

/// Allocates memory for a Decl with the given \p baseSize. If necessary,
Expand Down Expand Up @@ -1410,6 +1397,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
}

using DeclContext::operator new;
using DeclContext::operator delete;
};

/// Iterator that walks the extensions of a particular type.
Expand Down Expand Up @@ -1964,6 +1952,7 @@ class TopLevelCodeDecl : public DeclContext, public Decl {
}

using DeclContext::operator new;
using DeclContext::operator delete;
};

/// SerializedTopLevelCodeDeclContext - This represents what was originally a
Expand Down Expand Up @@ -2614,6 +2603,7 @@ class GenericTypeDecl : public GenericContext, public TypeDecl {
// Resolve ambiguity due to multiple base classes.
using TypeDecl::getASTContext;
using DeclContext::operator new;
using DeclContext::operator delete;
using TypeDecl::getDeclaredInterfaceType;

static bool classof(const DeclContext *C) {
Expand Down Expand Up @@ -5732,6 +5722,7 @@ class SubscriptDecl : public GenericContext, public AbstractStorageDecl {
}

using DeclContext::operator new;
using DeclContext::operator delete;
using Decl::getASTContext;
};

Expand Down Expand Up @@ -6244,6 +6235,7 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
bool hasKnownUnsafeSendableFunctionParams() const;

using DeclContext::operator new;
using DeclContext::operator delete;
using Decl::getASTContext;
};

Expand Down Expand Up @@ -6775,6 +6767,7 @@ class EnumElementDecl : public DeclContext, public ValueDecl {
}

using DeclContext::operator new;
using DeclContext::operator delete;
using Decl::getASTContext;
};

Expand Down
8 changes: 3 additions & 5 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef SWIFT_DECLCONTEXT_H
#define SWIFT_DECLCONTEXT_H

#include "swift/AST/ASTAllocated.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/LookupKinds.h"
#include "swift/AST/ResilienceExpansion.h"
Expand Down Expand Up @@ -221,7 +222,8 @@ struct FragileFunctionKind {
/// and therefore can safely access trailing memory. If you need to create a
/// macro context, please see GenericContext for how to minimize new entries in
/// the ASTHierarchy enum below.
class alignas(1 << DeclContextAlignInBits) DeclContext {
class alignas(1 << DeclContextAlignInBits) DeclContext
: public ASTAllocated<DeclContext> {
enum class ASTHierarchy : unsigned {
Decl,
Expr,
Expand Down Expand Up @@ -628,10 +630,6 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
SWIFT_DEBUG_DUMPER(dumpContext());
unsigned printContext(llvm::raw_ostream &OS, unsigned indent = 0,
bool onlyAPartialLine = false) const;

// Only allow allocation of DeclContext using the allocator in ASTContext.
void *operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(DeclContext));

// Some Decls are DeclContexts, but not all. See swift/AST/Decl.h
static bool classof(const Decl *D);
Expand Down
17 changes: 2 additions & 15 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ enum class AccessSemantics : uint8_t {
};

/// Expr - Base class for all expressions in swift.
class alignas(8) Expr {
class alignas(8) Expr : public ASTAllocated<Expr> {
Expr(const Expr&) = delete;
void operator=(const Expr&) = delete;

Expand Down Expand Up @@ -567,20 +567,6 @@ class alignas(8) Expr {
unsigned Indent = 0) const;

void print(ASTPrinter &Printer, const PrintOptions &Opts) const;

// Only allow allocation of Exprs using the allocator in ASTContext
// or by doing a placement new.
void *operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignof(Expr));

// Make placement new and vanilla new/delete illegal for Exprs.
void *operator new(size_t Bytes) throw() = delete;
void operator delete(void *Data) throw() = delete;

void *operator new(size_t Bytes, void *Mem) {
assert(Mem);
return Mem;
}
};

/// ErrorExpr - Represents a semantically erroneous subexpression in the AST,
Expand Down Expand Up @@ -3864,6 +3850,7 @@ class AbstractClosureExpr : public DeclContext, public Expr {
}

using DeclContext::operator new;
using DeclContext::operator delete;
using Expr::dump;
};

Expand Down
Loading