forked from facebook/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMetadata.cpp
More file actions
151 lines (130 loc) · 4.27 KB
/
Metadata.cpp
File metadata and controls
151 lines (130 loc) · 4.27 KB
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
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "hermes/VM/Metadata.h"
#include "hermes/VM/SymbolID.h"
namespace hermes {
namespace vm {
using std::size_t;
using std::uintptr_t;
using ArrayData = Metadata::ArrayData;
using ArrayType = ArrayData::ArrayType;
std::array<Metadata, kNumCellKinds> Metadata::metadataTable{};
Metadata::Metadata(Builder &&mb) : vtp(mb.vtp_) {
offsets.array = mb.array_;
size_t i = 0;
#define SLOT_TYPE(type) \
for (const auto &p : mb.map##type##_) { \
offsets.fields[i] = p.first; \
names[i] = p.second; \
i++; \
} \
offsets.end##type = i;
#include "hermes/VM/SlotKinds.def"
#undef SLOT_TYPE
assert(i <= kMaxNumFields && "Number of fields exceeds max.");
assert(vtp->isValid() && "Must initialize VTable pointer for metadata.");
}
Metadata::Builder::Builder(const void *base)
: base_(reinterpret_cast<const char *>(base)) {}
Metadata::offset_t Metadata::Builder::getOffset(const void *fieldLocation) {
const size_t offset = reinterpret_cast<const char *>(fieldLocation) - base_;
const offset_t ret = offset;
assert(ret == offset && "Offset overflowed.");
return ret;
}
#define SLOT_TYPE(type) \
void Metadata::Builder::addField(const type *fieldLocation) { \
addField(nullptr, fieldLocation); \
}
#include "hermes/VM/SlotKinds.def"
#undef SLOT_TYPE
#define SLOT_TYPE(type) \
void Metadata::Builder::addField( \
const char *name, const type *fieldLocation) { \
offset_t offset = getOffset(fieldLocation); \
assert( \
!fieldConflicts(offset, sizeof(type)) && "fields should not overlap"); \
map##type##_[offset] = name; \
}
#include "hermes/VM/SlotKinds.def"
#undef SLOT_TYPE
void Metadata::Builder::addArray(
const char *name,
ArrayData::ArrayType type,
const void *startLocation,
const AtomicIfConcurrentGC<uint32_t> *lengthLocation,
std::size_t stride) {
const uint8_t stride8 = stride;
assert(stride8 == stride && "Stride overflowed");
array_ = ArrayData(
type, getOffset(startLocation), getOffset(lengthLocation), stride8);
}
Metadata Metadata::Builder::build() {
return Metadata(std::move(*this));
}
#ifndef NDEBUG
bool Metadata::Builder::fieldConflicts(offset_t offset, size_t size) {
size_t end = offset + size;
coveredOffsets_.resize(std::max(coveredOffsets_.size(), end));
for (offset_t i = offset; i < end; ++i) {
if (coveredOffsets_[i])
return true;
coveredOffsets_[i] = true;
}
return false;
}
#endif
/// @name Formatters
/// @{
llvh::raw_ostream &operator<<(llvh::raw_ostream &os, const Metadata &meta) {
os << "Metadata: {\n\tfieldsAndNames: [";
bool first = true;
size_t end;
#define SLOT_TYPE(type) end = meta.offsets.end##type;
#include "hermes/VM/SlotKinds.def"
#undef SLOT_TYPE
for (size_t i = 0; i < end; ++i) {
if (!first) {
os << ",";
} else {
first = false;
}
os << "\n\t\t";
os << "{ offset: " << meta.offsets.fields[i] << ", name: " << meta.names[i]
<< "}";
}
if (!first) {
os << "\n\t";
}
os << "]";
if (meta.offsets.array) {
os << ",\n\tarray: " << *meta.offsets.array << ",\n";
} else {
os << "\n";
}
return os << "}";
}
llvh::raw_ostream &operator<<(llvh::raw_ostream &os, ArrayData array) {
return os << "ArrayData: {type: {" << array.type
<< "}, lengthOffset: " << array.lengthOffset
<< ", stride: " << array.stride << "}";
}
llvh::raw_ostream &operator<<(llvh::raw_ostream &os, ArrayType arraytype) {
os << "ArrayType: {";
switch (arraytype) {
#define SLOT_TYPE(type) \
case ArrayType::type: \
os << #type; \
break;
#include "hermes/VM/SlotKinds.def"
#undef SLOT_TYPE
}
return os << "}";
}
/// @}
} // namespace vm
} // namespace hermes