//===--- GenHeap.h - Heap-object layout and management ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 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 // //===----------------------------------------------------------------------===// // // This file defines some routines that are useful for emitting // operations on heap objects and their metadata. // //===----------------------------------------------------------------------===// #ifndef SWIFT_IRGEN_GENHEAP_H #define SWIFT_IRGEN_GENHEAP_H #include "NecessaryBindings.h" #include "StructLayout.h" namespace llvm { class Constant; template class SmallVectorImpl; } namespace swift { namespace irgen { class Address; class OwnedAddress; /// A heap layout is the result of laying out a complete structure for /// heap-allocation. class HeapLayout : public StructLayout { SmallVector ElementTypes; NecessaryBindings Bindings; mutable llvm::Constant *privateMetadata = nullptr; public: HeapLayout(IRGenModule &IGM, LayoutStrategy strategy, ArrayRef elementTypes, ArrayRef elementTypeInfos, llvm::StructType *typeToFill = 0, NecessaryBindings &&bindings = {}); /// True if the heap object carries type bindings. /// /// If true, the first element of the heap layout will be the type metadata /// buffer. bool hasBindings() const { return !Bindings.empty(); } const NecessaryBindings &getBindings() const { return Bindings; } /// Get the types of the elements. ArrayRef getElementTypes() const { return ElementTypes; } /// Build a size function for this layout. llvm::Constant *createSizeFn(IRGenModule &IGM) const; /// As a convenience, build a metadata object with internal linkage /// consisting solely of the standard heap metadata. llvm::Constant *getPrivateMetadata(IRGenModule &IGM, llvm::Constant *captureDescriptor) const; }; class HeapNonFixedOffsets : public NonFixedOffsetsImpl { SmallVector Offsets; llvm::Value *TotalSize; llvm::Value *TotalAlignMask; public: HeapNonFixedOffsets(IRGenFunction &IGF, const HeapLayout &layout); llvm::Value *getOffsetForIndex(IRGenFunction &IGF, unsigned index) override { auto result = Offsets[index]; assert(result != nullptr && "fixed-layout field doesn't need NonFixedOffsets"); return result; } // The total size of the heap object. llvm::Value *getSize() const { return TotalSize; } // The total alignment of the heap object. llvm::Value *getAlignMask() const { return TotalAlignMask; } }; /// Emit a heap object deallocation. void emitDeallocateHeapObject(IRGenFunction &IGF, llvm::Value *object, llvm::Value *size, llvm::Value *alignMask); /// Emit a class instance deallocation. void emitDeallocateClassInstance(IRGenFunction &IGF, llvm::Value *object, llvm::Value *size, llvm::Value *alignMask); /// Emit a partial class instance deallocation from a failing constructor. void emitDeallocatePartialClassInstance(IRGenFunction &IGF, llvm::Value *object, llvm::Value *metadata, llvm::Value *size, llvm::Value *alignMask); /// Allocate a boxed value. /// /// The interface type is required for emitting reflection metadata. OwnedAddress emitAllocateBox(IRGenFunction &IGF, CanSILBoxType boxType, GenericEnvironment *env, const llvm::Twine &name); /// Deallocate a box whose value is uninitialized. void emitDeallocateBox(IRGenFunction &IGF, llvm::Value *box, CanSILBoxType boxType); /// Project the address of the value inside a box. Address emitProjectBox(IRGenFunction &IGF, llvm::Value *box, CanSILBoxType boxType); /// Allocate a boxed value based on the boxed type. Returns the address of the /// storage for the value. Address emitAllocateExistentialBoxInBuffer(IRGenFunction &IGF, SILType boxedType, Address destBuffer, GenericEnvironment *env, const llvm::Twine &name, bool isOutlined); } // end namespace irgen } // end namespace swift #endif