forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClassLayout.h
124 lines (97 loc) · 3.9 KB
/
ClassLayout.h
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
//===--- ClassLayout.h - Class instance layout ------------------*- 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 calculating class
// instance layout.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_CLASSLAYOUT_H
#define SWIFT_IRGEN_CLASSLAYOUT_H
#include "llvm/ADT/ArrayRef.h"
#include "IRGen.h"
#include "StructLayout.h"
namespace swift {
namespace irgen {
/// Different policies for accessing a physical field.
enum class FieldAccess : uint8_t {
/// Instance variable offsets are constant.
ConstantDirect,
/// Instance variable offsets must be loaded from "direct offset"
/// global variables.
NonConstantDirect,
/// Instance variable offsets are kept in fields in metadata, but
/// the offsets of those fields within the metadata are constant.
ConstantIndirect
};
class ClassLayout {
/// The statically-known minimum bound on the alignment.
Alignment MinimumAlign;
/// The statically-known minimum bound on the size.
Size MinimumSize;
/// Whether this layout is fixed in size. If so, the size and
/// alignment are exact.
bool IsFixedLayout;
/// Do instances of this class have a size and layout known at compile time?
///
/// Note: This is a stronger condition than having a fixed layout. The latter
/// is true even when the class requires sliding ivars by the Objective-C
/// runtime.
bool IsFixedSize;
/// Does the class metadata require initialization?
bool MetadataRequiresInitialization;
/// Does the class metadata require relocation?
bool MetadataRequiresRelocation;
/// The LLVM type for instances of this class.
llvm::Type *Ty;
/// Lazily-initialized array of all fragile stored properties directly defined
/// in the class itself.
ArrayRef<VarDecl *> AllStoredProperties;
/// Lazily-initialized array of all field access methods.
ArrayRef<FieldAccess> AllFieldAccesses;
/// Fixed offsets of fields, if known (does not take Objective-C sliding into
/// account).
ArrayRef<ElementLayout> AllElements;
public:
ClassLayout(const StructLayoutBuilder &builder,
bool isFixedSize,
bool metadataRequiresInitialization,
bool metadataRequiresRelocation,
llvm::Type *classTy,
ArrayRef<VarDecl *> allStoredProps,
ArrayRef<FieldAccess> allFieldAccesses,
ArrayRef<ElementLayout> allElements);
Size getInstanceStart() const;
llvm::Type *getType() const { return Ty; }
Size getSize() const { return MinimumSize; }
Alignment getAlignment() const { return MinimumAlign; }
Size getAlignMask() const { return getAlignment().asSize() - Size(1); }
bool isFixedLayout() const { return IsFixedLayout; }
bool isFixedSize() const { return IsFixedSize; }
bool doesMetadataRequireInitialization() const {
return MetadataRequiresInitialization;
}
bool doesMetadataRequireRelocation() const {
return MetadataRequiresRelocation;
}
std::pair<FieldAccess, ElementLayout>
getFieldAccessAndElement(VarDecl *field) const {
// FIXME: This is algorithmically terrible.
auto found = std::find(AllStoredProperties.begin(),
AllStoredProperties.end(), field);
assert(found != AllStoredProperties.end() && "didn't find field in type?!");
unsigned index = found - AllStoredProperties.begin();
return std::make_pair(AllFieldAccesses[index], AllElements[index]);
}
};
} // end namespace irgen
} // end namespace swift
#endif