1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
//===--- 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 T> class SmallVectorImpl;
}
namespace swift {
namespace irgen {
class Address;
class OwnedAddress;
enum class IsaEncoding : unsigned char;
/// A heap layout is the result of laying out a complete structure for
/// heap-allocation.
class HeapLayout : public StructLayout {
SmallVector<SILType, 8> ElementTypes;
NecessaryBindings Bindings;
unsigned BindingsIndex;
mutable llvm::Constant *privateMetadata = nullptr;
public:
HeapLayout(IRGenModule &IGM, LayoutStrategy strategy,
ArrayRef<SILType> elementTypes,
ArrayRef<const TypeInfo *> elementTypeInfos,
llvm::StructType *typeToFill = 0,
NecessaryBindings &&bindings = {}, unsigned bindingsIndex = 0);
/// 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;
}
unsigned getBindingsIndex() const { return BindingsIndex; }
unsigned getIndexAfterBindings() const {
return BindingsIndex + (hasBindings() ? 1 : 0);
}
/// Get the types of the elements.
ArrayRef<SILType> 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<llvm::Value *, 1> 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);
/// Given a heap-object instance, with some heap-object type,
/// produce a reference to its type metadata.
llvm::Value *emitDynamicTypeOfHeapObject(IRGenFunction &IGF,
llvm::Value *object,
MetatypeRepresentation rep,
SILType objectType,
GenericSignature sig,
bool allowArtificialSubclasses = false);
/// Given a non-tagged object pointer, load a pointer to its class object.
llvm::Value *emitLoadOfObjCHeapMetadataRef(IRGenFunction &IGF,
llvm::Value *object);
/// Given a heap-object instance, with some heap-object type, produce a
/// reference to its heap metadata by dynamically asking the runtime for it.
llvm::Value *emitHeapMetadataRefForUnknownHeapObject(IRGenFunction &IGF,
llvm::Value *object);
/// Given a heap-object instance, with some heap-object type,
/// produce a reference to its heap metadata.
llvm::Value *emitHeapMetadataRefForHeapObject(IRGenFunction &IGF,
llvm::Value *object,
CanType objectType,
GenericSignature sig,
bool suppressCast = false);
/// Given a heap-object instance, with some heap-object type,
/// produce a reference to its heap metadata.
llvm::Value *emitHeapMetadataRefForHeapObject(IRGenFunction &IGF,
llvm::Value *object,
SILType objectType,
GenericSignature sig,
bool suppressCast = false);
/// What isa-encoding mechanism does a type use?
IsaEncoding getIsaEncodingForType(IRGenModule &IGM, CanType type,
GenericSignature sig);
} // end namespace irgen
} // end namespace swift
#endif
|