-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathdeferred_objects.h
256 lines (182 loc) · 6.8 KB
/
deferred_objects.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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_DEFERRED_OBJECTS_H_
#define RUNTIME_VM_DEFERRED_OBJECTS_H_
#include "platform/globals.h"
#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
class Object;
class DeoptContext;
// Used by the deoptimization infrastructure to defer allocation of
// unboxed objects until frame is fully rewritten and GC is safe.
// Describes a stack slot that should be populated with a reference to
// the materialized object.
class DeferredSlot {
public:
DeferredSlot(ObjectPtr* slot, DeferredSlot* next)
: slot_(slot), next_(next) {}
virtual ~DeferredSlot() {}
ObjectPtr* slot() const { return slot_; }
DeferredSlot* next() const { return next_; }
virtual void Materialize(DeoptContext* deopt_context) = 0;
private:
ObjectPtr* const slot_;
DeferredSlot* const next_;
DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
};
class DeferredDouble : public DeferredSlot {
public:
DeferredDouble(double value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
double value() const { return value_; }
private:
const double value_;
DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
};
class DeferredMint : public DeferredSlot {
public:
DeferredMint(int64_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
int64_t value() const { return value_; }
private:
const int64_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredMint);
};
class DeferredFloat32x4 : public DeferredSlot {
public:
DeferredFloat32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
};
class DeferredFloat64x2 : public DeferredSlot {
public:
DeferredFloat64x2(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredFloat64x2);
};
class DeferredInt32x4 : public DeferredSlot {
public:
DeferredInt32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredInt32x4);
};
// Describes a slot that contains a reference to an object that had its
// allocation removed by AllocationSinking pass.
// Object itself is described and materialized by DeferredObject.
class DeferredObjectRef : public DeferredSlot {
public:
DeferredObjectRef(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
};
class DeferredRetAddr : public DeferredSlot {
public:
DeferredRetAddr(intptr_t index,
intptr_t deopt_id,
ObjectPtr* slot,
DeferredSlot* next)
: DeferredSlot(slot, next), index_(index), deopt_id_(deopt_id) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
const intptr_t deopt_id_;
DISALLOW_COPY_AND_ASSIGN(DeferredRetAddr);
};
class DeferredPcMarker : public DeferredSlot {
public:
DeferredPcMarker(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredPcMarker);
};
class DeferredPp : public DeferredSlot {
public:
DeferredPp(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredPp);
};
// Describes an object which allocation was removed by AllocationSinking pass.
// Arguments for materialization are stored as a part of expression stack
// for the bottommost deoptimized frame so that GC could discover them.
// They will be removed from the stack at the very end of deoptimization.
class DeferredObject {
public:
DeferredObject(intptr_t field_count, intptr_t* args)
: field_count_(field_count),
args_(reinterpret_cast<ObjectPtr*>(args)),
object_(nullptr) {}
intptr_t ArgumentCount() const {
return kFieldsStartIndex + kFieldEntrySize * field_count_;
}
ObjectPtr object();
// Fill object with actual field values.
void Fill();
private:
enum {
kClassIndex = 0,
// For contexts: number of context variables.
// For arrays and typed data objects: number of elements.
// For records: shape.
// -1 otherwise.
kLengthOrShapeIndex,
kFieldsStartIndex
};
enum {
kOffsetIndex = 0,
kValueIndex,
kFieldEntrySize,
};
// Allocate the object but keep its fields null-initialized. Actual field
// values will be filled later by the Fill method. This separation between
// allocation and filling is needed because dematerialized objects form
// a graph which can contain cycles.
void Create();
ObjectPtr GetArg(intptr_t index) const { return args_[index]; }
ObjectPtr GetClass() const { return GetArg(kClassIndex); }
ObjectPtr GetLengthOrShape() const { return GetArg(kLengthOrShapeIndex); }
ObjectPtr GetFieldOffset(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex);
}
ObjectPtr GetValue(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kValueIndex);
}
// Amount of fields that have to be initialized.
const intptr_t field_count_;
// Pointer to the first materialization argument on the stack.
// The first argument is Class of the instance to materialize followed by
// Field, value pairs.
ObjectPtr* args_;
// Object materialized from this description.
const Object* object_;
DISALLOW_COPY_AND_ASSIGN(DeferredObject);
};
} // namespace dart
#endif // RUNTIME_VM_DEFERRED_OBJECTS_H_