/src/jsonnet/core/state.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright 2015 Google Inc. All rights reserved. |
3 | | |
4 | | Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | you may not use this file except in compliance with the License. |
6 | | You may obtain a copy of the License at |
7 | | |
8 | | http://www.apache.org/licenses/LICENSE-2.0 |
9 | | |
10 | | Unless required by applicable law or agreed to in writing, software |
11 | | distributed under the License is distributed on an "AS IS" BASIS, |
12 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | See the License for the specific language governing permissions and |
14 | | limitations under the License. |
15 | | */ |
16 | | |
17 | | #ifndef JSONNET_STATE_H |
18 | | #define JSONNET_STATE_H |
19 | | |
20 | | namespace jsonnet::internal { |
21 | | namespace { |
22 | | |
23 | | /** Mark & sweep: advanced by 1 each GC cycle. |
24 | | */ |
25 | | typedef unsigned char GarbageCollectionMark; |
26 | | |
27 | | /** Supertype of everything that is allocated on the heap. |
28 | | */ |
29 | | struct HeapEntity { |
30 | | enum Type : unsigned char { |
31 | | THUNK, |
32 | | ARRAY, |
33 | | CLOSURE, |
34 | | STRING, |
35 | | SIMPLE_OBJECT, |
36 | | COMPREHENSION_OBJECT, |
37 | | EXTENDED_OBJECT, |
38 | | }; |
39 | | GarbageCollectionMark mark; |
40 | | Type type; |
41 | 312M | HeapEntity(Type type_) : type(type_) {} |
42 | 312M | virtual ~HeapEntity() {} |
43 | | }; |
44 | | |
45 | | /** Tagged union of all values. |
46 | | * |
47 | | * Primitives (<= 8 bytes) are copied by value. Otherwise a pointer to a HeapEntity is used. |
48 | | */ |
49 | | struct Value { |
50 | | enum Type { |
51 | | NULL_TYPE = 0x0, // Unfortunately NULL is a macro in C. |
52 | | BOOLEAN = 0x1, |
53 | | NUMBER = 0x2, |
54 | | |
55 | | ARRAY = 0x10, |
56 | | FUNCTION = 0x11, |
57 | | OBJECT = 0x12, |
58 | | STRING = 0x13 |
59 | | }; |
60 | | Type t; |
61 | | union { |
62 | | HeapEntity *h; |
63 | | double d; |
64 | | bool b; |
65 | | } v; |
66 | | bool isHeap(void) const |
67 | 174M | { |
68 | 174M | return t & 0x10; |
69 | 174M | } |
70 | | }; |
71 | | |
72 | | /** Convert the type into a string, for error messages. */ |
73 | | std::string type_str(Value::Type t) |
74 | 3.16k | { |
75 | 3.16k | switch (t) { |
76 | 20 | case Value::NULL_TYPE: return "null"; |
77 | 652 | case Value::BOOLEAN: return "boolean"; |
78 | 711 | case Value::NUMBER: return "number"; |
79 | 132 | case Value::ARRAY: return "array"; |
80 | 3 | case Value::FUNCTION: return "function"; |
81 | 473 | case Value::OBJECT: return "object"; |
82 | 1.17k | case Value::STRING: return "string"; |
83 | 0 | default: |
84 | 0 | std::cerr << "INTERNAL ERROR: Unknown type: " << t << std::endl; |
85 | 0 | std::abort(); |
86 | 0 | return ""; // Quiet, compiler. |
87 | 3.16k | } |
88 | 3.16k | } |
89 | | |
90 | | /** Convert the value's type into a string, for error messages. */ |
91 | | std::string type_str(const Value &v) |
92 | 1.13k | { |
93 | 1.13k | return type_str(v.t); |
94 | 1.13k | } |
95 | | |
96 | | struct HeapThunk; |
97 | | |
98 | | /** Stores the values bound to variables. |
99 | | * |
100 | | * Each nested local statement, function call, and field access has its own binding frame to |
101 | | * give the values for the local variable, function parameters, or upValues. |
102 | | */ |
103 | | typedef std::map<const Identifier *, HeapThunk *> BindingFrame; |
104 | | |
105 | | /** Supertype of all objects. Types of Value::OBJECT will point at these. */ |
106 | | struct HeapObject : public HeapEntity { |
107 | 10.1M | HeapObject(Type type) : HeapEntity(type) {} |
108 | | }; |
109 | | |
110 | | /** Hold an unevaluated expression. This implements lazy semantics. |
111 | | */ |
112 | | struct HeapThunk : public HeapEntity { |
113 | | /** Whether or not the thunk was forced. */ |
114 | | bool filled; |
115 | | |
116 | | /** The result when the thunk was forced, if filled == true. */ |
117 | | Value content; |
118 | | |
119 | | /** Used in error tracebacks. */ |
120 | | const Identifier *name; |
121 | | |
122 | | /** The captured environment. |
123 | | * |
124 | | * Note, this is non-const because we have to add cyclic references to it. |
125 | | */ |
126 | | BindingFrame upValues; |
127 | | |
128 | | /** The captured self variable, or nullptr if there was none. \see CallFrame. */ |
129 | | HeapObject *self; |
130 | | |
131 | | /** The offset from the captured self variable. \see CallFrame. */ |
132 | | unsigned offset; |
133 | | |
134 | | /** Evaluated to force the thunk. */ |
135 | | const AST *body; |
136 | | |
137 | | HeapThunk(const Identifier *name, HeapObject *self, unsigned offset, const AST *body) |
138 | 139M | : HeapEntity(THUNK), filled(false), name(name), self(self), offset(offset), body(body) |
139 | 139M | { |
140 | 139M | } |
141 | | |
142 | | void fill(const Value &v) |
143 | 83.4M | { |
144 | 83.4M | content = v; |
145 | 83.4M | filled = true; |
146 | 83.4M | self = nullptr; |
147 | 83.4M | upValues.clear(); |
148 | 83.4M | } |
149 | | }; |
150 | | |
151 | | struct HeapArray : public HeapEntity { |
152 | | // It is convenient for this to not be const, so that we can add elements to it one at a |
153 | | // time after creation. Thus, elements are not GCed as the array is being |
154 | | // created. |
155 | | std::vector<HeapThunk *> elements; |
156 | | HeapArray(const std::vector<HeapThunk *> &elements) |
157 | 3.32M | : HeapEntity(ARRAY), elements(elements) |
158 | 3.32M | { |
159 | 3.32M | } |
160 | | }; |
161 | | |
162 | | /** Supertype of all objects that are not super objects or extended objects. */ |
163 | | struct HeapLeafObject : public HeapObject { |
164 | 5.88M | HeapLeafObject(Type type) : HeapObject(type) {} |
165 | | }; |
166 | | |
167 | | /** Objects created via the simple object constructor construct. */ |
168 | | struct HeapSimpleObject : public HeapLeafObject { |
169 | | /** The captured environment. */ |
170 | | const BindingFrame upValues; |
171 | | |
172 | | struct Field { |
173 | | /** Will the field appear in output? */ |
174 | | ObjectField::Hide hide; |
175 | | /** Expression that is evaluated when indexing this field. */ |
176 | | AST *body; |
177 | | }; |
178 | | |
179 | | /** The fields. |
180 | | * |
181 | | * These are evaluated in the captured environment and with self and super bound |
182 | | * dynamically. |
183 | | */ |
184 | | const std::map<const Identifier *, Field> fields; |
185 | | |
186 | | /** The object's invariants. |
187 | | * |
188 | | * These are evaluated in the captured environment with self and super bound. |
189 | | */ |
190 | | ASTs asserts; |
191 | | |
192 | | HeapSimpleObject(const BindingFrame &up_values, |
193 | | const std::map<const Identifier *, Field> fields, ASTs asserts) |
194 | 5.88M | : HeapLeafObject(SIMPLE_OBJECT), upValues(up_values), fields(fields), asserts(asserts) |
195 | 5.88M | { |
196 | 5.88M | } |
197 | | }; |
198 | | |
199 | | /** Objects created by the + construct. */ |
200 | | struct HeapExtendedObject : public HeapObject { |
201 | | /** The left hand side of the construct. */ |
202 | | HeapObject *left; |
203 | | |
204 | | /** The right hand side of the construct. */ |
205 | | HeapObject *right; |
206 | | |
207 | | HeapExtendedObject(HeapObject *left, HeapObject *right) |
208 | 4.25M | : HeapObject(EXTENDED_OBJECT), left(left), right(right) |
209 | 4.25M | { |
210 | 4.25M | } |
211 | | }; |
212 | | |
213 | | /** Objects created by the ObjectComprehensionSimple construct. */ |
214 | | struct HeapComprehensionObject : public HeapLeafObject { |
215 | | /** The captured environment. */ |
216 | | const BindingFrame upValues; |
217 | | |
218 | | /** The expression used to compute the field values. */ |
219 | | const AST *value; |
220 | | |
221 | | /** The identifier of bound variable in that construct. */ |
222 | | const Identifier *const id; |
223 | | |
224 | | /** Binding for id. |
225 | | * |
226 | | * For each field, holds the value that should be bound to id. This is the corresponding |
227 | | * array element from the original array used to define this object. This should not really |
228 | | * be a thunk, but it makes the implementation easier. |
229 | | * |
230 | | * It is convenient to make this non-const to allow building up the values one by one, so that |
231 | | * the garbage collector can see them at each intermediate point. |
232 | | */ |
233 | | std::map<const Identifier *, HeapThunk *> compValues; |
234 | | |
235 | | HeapComprehensionObject(const BindingFrame &up_values, const AST *value, const Identifier *id, |
236 | | const std::map<const Identifier *, HeapThunk *> &comp_values) |
237 | 0 | : HeapLeafObject(COMPREHENSION_OBJECT), upValues(up_values), value(value), id(id), compValues(comp_values) |
238 | 0 | { |
239 | 0 | } |
240 | | }; |
241 | | |
242 | | /** Stores the function itself and also the captured environment. |
243 | | * |
244 | | * Either body is non-null and builtinName is "", or body is null and builtin refers to a built-in |
245 | | * function. In the former case, the closure represents a user function, otherwise calling it |
246 | | * will trigger the builtin function to execute. Params is empty when the function is a |
247 | | * builtin. |
248 | | */ |
249 | | struct HeapClosure : public HeapEntity { |
250 | | /** The captured environment. */ |
251 | | const BindingFrame upValues; |
252 | | /** The captured self variable, or nullptr if there was none. \see Frame. */ |
253 | | HeapObject *self; |
254 | | /** The offset from the captured self variable. \see Frame.*/ |
255 | | unsigned offset; |
256 | | struct Param { |
257 | | const Identifier *id; |
258 | | const AST *def; |
259 | 57.1M | Param(const Identifier *id, const AST *def) : id(id), def(def) {} |
260 | | }; |
261 | | typedef std::vector<Param> Params; |
262 | | const Params params; |
263 | | const AST *body; |
264 | | std::string builtinName; |
265 | | HeapClosure(const BindingFrame &up_values, HeapObject *self, unsigned offset, |
266 | | const Params ¶ms, const AST *body, const std::string &builtin_name) |
267 | 34.8M | : HeapEntity(CLOSURE), |
268 | 34.8M | upValues(up_values), |
269 | 34.8M | self(self), |
270 | 34.8M | offset(offset), |
271 | 34.8M | params(params), |
272 | 34.8M | body(body), |
273 | 34.8M | builtinName(builtin_name) |
274 | 34.8M | { |
275 | 34.8M | } |
276 | | }; |
277 | | |
278 | | /** Stores a simple string on the heap. */ |
279 | | struct HeapString : public HeapEntity { |
280 | | const UString value; |
281 | 124M | HeapString(const UString &value) : HeapEntity(STRING), value(value) {} |
282 | | }; |
283 | | |
284 | | /** The heap does memory management, i.e. garbage collection. */ |
285 | | class Heap { |
286 | | /** How many objects must exist in the heap before we bother doing garbage collection? |
287 | | */ |
288 | | unsigned gcTuneMinObjects; |
289 | | |
290 | | /** How much must the heap have grown since the last cycle to trigger a collection? |
291 | | */ |
292 | | double gcTuneGrowthTrigger; |
293 | | |
294 | | /** Value used to mark entities at the last garbage collection cycle. */ |
295 | | GarbageCollectionMark lastMark; |
296 | | |
297 | | /** The heap entities (strings, arrays, objects, functions, etc). |
298 | | * |
299 | | * Not all may be reachable, all should have o->mark == this->lastMark. Entities are |
300 | | * removed from the heap via O(1) swap with last element, so the ordering of entities is |
301 | | * arbitrary and changes every garbage collection cycle. |
302 | | */ |
303 | | std::vector<HeapEntity *> entities; |
304 | | |
305 | | /** The number of heap entities at the last garbage collection cycle. */ |
306 | | unsigned long lastNumEntities; |
307 | | |
308 | | /** The number of heap entities now. */ |
309 | | unsigned long numEntities; |
310 | | |
311 | | /** Add the HeapEntity inside v to vec, if the value exists on the heap. |
312 | | */ |
313 | | void addIfHeapEntity(Value v, std::vector<HeapEntity *> &vec) |
314 | 0 | { |
315 | 0 | if (v.isHeap()) |
316 | 0 | vec.push_back(v.v.h); |
317 | 0 | } |
318 | | |
319 | | /** Add the HeapEntity inside v to vec, if the value exists on the heap. |
320 | | */ |
321 | | void addIfHeapEntity(HeapEntity *v, std::vector<HeapEntity *> &vec) |
322 | 273M | { |
323 | 273M | vec.push_back(v); |
324 | 273M | } |
325 | | |
326 | | public: |
327 | | Heap(unsigned gc_tune_min_objects, double gc_tune_growth_trigger) |
328 | 9.81k | : gcTuneMinObjects(gc_tune_min_objects), |
329 | 9.81k | gcTuneGrowthTrigger(gc_tune_growth_trigger), |
330 | 9.81k | lastMark(0), |
331 | 9.81k | lastNumEntities(0), |
332 | 9.81k | numEntities(0) |
333 | 9.81k | { |
334 | 9.81k | } |
335 | | |
336 | | ~Heap(void) |
337 | 9.81k | { |
338 | | // Nothing is marked, everything will be collected. |
339 | 9.81k | sweep(); |
340 | 9.81k | } |
341 | | |
342 | | /** Garbage collection: Mark v, and entities reachable from v. */ |
343 | | void markFrom(Value v) |
344 | 138M | { |
345 | 138M | if (v.isHeap()) |
346 | 35.7M | markFrom(v.v.h); |
347 | 138M | } |
348 | | |
349 | | /** Garbage collection: Mark heap entities reachable from the given heap entity. */ |
350 | | void markFrom(HeapEntity *from) |
351 | 263M | { |
352 | 263M | assert(from != nullptr); |
353 | 263M | const GarbageCollectionMark thisMark = lastMark + 1; |
354 | 263M | struct State { |
355 | 263M | HeapEntity *ent; |
356 | 263M | std::vector<HeapEntity *> children; |
357 | 537M | State(HeapEntity *ent) : ent(ent) {} |
358 | 263M | }; |
359 | | |
360 | 263M | std::vector<State> stack; |
361 | 263M | stack.emplace_back(from); |
362 | | |
363 | 1.07G | while (stack.size() > 0) { |
364 | 811M | size_t curr_index = stack.size() - 1; |
365 | 811M | State &s = stack[curr_index]; |
366 | 811M | HeapEntity *curr = s.ent; |
367 | 811M | if (curr->mark != thisMark) { |
368 | 208M | curr->mark = thisMark; |
369 | | |
370 | 208M | switch(curr->type) { |
371 | 30.0M | case HeapEntity::SIMPLE_OBJECT: { |
372 | 30.0M | assert(dynamic_cast<HeapSimpleObject *>(curr)); |
373 | 30.0M | auto *obj = static_cast<HeapSimpleObject *>(curr); |
374 | 30.0M | for (auto upv : obj->upValues) |
375 | 24.5M | addIfHeapEntity(upv.second, s.children); |
376 | 30.0M | break; |
377 | 30.0M | } |
378 | 20.6M | case HeapEntity::EXTENDED_OBJECT: { |
379 | 20.6M | assert(dynamic_cast<HeapExtendedObject *>(curr)); |
380 | 20.6M | auto *obj = static_cast<HeapExtendedObject *>(curr); |
381 | 20.6M | addIfHeapEntity(obj->left, s.children); |
382 | 20.6M | addIfHeapEntity(obj->right, s.children); |
383 | 20.6M | break; |
384 | 20.6M | } |
385 | 0 | case HeapEntity::COMPREHENSION_OBJECT: { |
386 | 0 | assert(dynamic_cast<HeapComprehensionObject *>(curr)); |
387 | 0 | auto *obj = static_cast<HeapComprehensionObject *>(curr); |
388 | 0 | for (auto upv : obj->upValues) |
389 | 0 | addIfHeapEntity(upv.second, s.children); |
390 | 0 | for (auto upv : obj->compValues) |
391 | 0 | addIfHeapEntity(upv.second, s.children); |
392 | 0 | break; |
393 | 0 | } |
394 | 3.65M | case HeapEntity::ARRAY: { |
395 | 3.65M | assert(dynamic_cast<HeapArray *>(curr)); |
396 | 3.65M | auto *arr = static_cast<HeapArray *>(curr); |
397 | 3.65M | for (auto el : arr->elements) |
398 | 39.5M | addIfHeapEntity(el, s.children); |
399 | 3.65M | break; |
400 | 3.65M | } |
401 | 5.66M | case HeapEntity::CLOSURE: { |
402 | 5.66M | assert(dynamic_cast<HeapClosure *>(curr)); |
403 | 5.66M | auto *func = static_cast<HeapClosure *>(curr); |
404 | 5.66M | for (auto upv : func->upValues) |
405 | 13.2M | addIfHeapEntity(upv.second, s.children); |
406 | 5.66M | if (func->self) |
407 | 4.91M | addIfHeapEntity(func->self, s.children); |
408 | 5.66M | break; |
409 | 5.66M | } |
410 | 140M | case HeapEntity::THUNK: { |
411 | 140M | assert(dynamic_cast<HeapThunk *>(curr)); |
412 | 140M | auto *thunk = static_cast<HeapThunk *>(curr); |
413 | 140M | if (thunk->filled) { |
414 | 34.2M | if (thunk->content.isHeap()) |
415 | 24.1M | addIfHeapEntity(thunk->content.v.h, s.children); |
416 | 105M | } else { |
417 | 105M | for (auto upv : thunk->upValues) |
418 | 24.5M | addIfHeapEntity(upv.second, s.children); |
419 | 105M | if (thunk->self) |
420 | 101M | addIfHeapEntity(thunk->self, s.children); |
421 | 105M | } |
422 | 140M | break; |
423 | 140M | } |
424 | 8.19M | case HeapEntity::STRING: |
425 | 8.19M | assert(dynamic_cast<HeapString *>(curr)); |
426 | 8.19M | break; |
427 | 8.19M | default: |
428 | 0 | assert(false); |
429 | 0 | break; |
430 | 208M | } |
431 | 208M | } |
432 | | |
433 | 811M | if (s.children.size() > 0) { |
434 | 273M | HeapEntity *next = s.children[s.children.size() - 1]; |
435 | 273M | s.children.pop_back(); |
436 | 273M | stack.emplace_back(next); // CAUTION: s invalidated here |
437 | 537M | } else { |
438 | 537M | stack.pop_back(); // CAUTION: s invalidated here |
439 | 537M | } |
440 | 811M | } |
441 | 263M | } |
442 | | |
443 | | /** Delete everything that was not marked since the last collection. */ |
444 | | void sweep(void) |
445 | 373k | { |
446 | 373k | lastMark++; |
447 | | // Heap shrinks during this loop. Do not cache entities.size(). |
448 | 521M | for (unsigned long i = 0; i < entities.size(); ++i) { |
449 | 521M | HeapEntity *x = entities[i]; |
450 | 521M | if (x->mark != lastMark) { |
451 | 312M | delete x; |
452 | 312M | if (i != entities.size() - 1) { |
453 | | // Swap it with the back. |
454 | 312M | entities[i] = entities[entities.size() - 1]; |
455 | 312M | } |
456 | 312M | entities.pop_back(); |
457 | 312M | --i; |
458 | 312M | } |
459 | 521M | } |
460 | 373k | lastNumEntities = numEntities = entities.size(); |
461 | 373k | } |
462 | | |
463 | | /** Is it time to initiate a GC cycle? */ |
464 | | bool checkHeap(void) |
465 | 312M | { |
466 | 312M | return numEntities > gcTuneMinObjects && |
467 | 312M | numEntities > gcTuneGrowthTrigger * lastNumEntities; |
468 | 312M | } |
469 | | |
470 | | /** Allocate a heap entity. |
471 | | * |
472 | | * If the heap is large enough (\see gcTuneMinObjects) and has grown by enough since the |
473 | | * last collection cycle (\see gcTuneGrowthTrigger), a collection cycle should be performed. |
474 | | */ |
475 | | template <class T, class... Args> |
476 | | T *makeEntity(Args &&... args) |
477 | 312M | { |
478 | 312M | T *r = new T(std::forward<Args>(args)...); |
479 | 312M | entities.push_back(r); |
480 | 312M | r->mark = lastMark; |
481 | 312M | numEntities = entities.size(); |
482 | 312M | return r; |
483 | 312M | } Unexecuted instantiation: vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject* const&, unsigned int const&, jsonnet::internal::AST const* const&>(jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject* const&, unsigned int const&, jsonnet::internal::AST const* const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const* const&, decltype(nullptr), int, decltype(nullptr)>(jsonnet::internal::Identifier const* const&, decltype(nullptr)&&, int&&, decltype(nullptr)&&) vm.cpp:jsonnet::internal::(anonymous namespace)::HeapArray* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapArray, std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapThunk*> > const&>(std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapThunk*> > const&) Line | Count | Source | 477 | 3.32M | { | 478 | 3.32M | T *r = new T(std::forward<Args>(args)...); | 479 | 3.32M | entities.push_back(r); | 480 | 3.32M | r->mark = lastMark; | 481 | 3.32M | numEntities = entities.size(); | 482 | 3.32M | return r; | 483 | 3.32M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapString* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapString, std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > const&>(std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > const&) Line | Count | Source | 477 | 124M | { | 478 | 124M | T *r = new T(std::forward<Args>(args)...); | 479 | 124M | entities.push_back(r); | 480 | 124M | r->mark = lastMark; | 481 | 124M | numEntities = entities.size(); | 482 | 124M | return r; | 483 | 124M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, decltype(nullptr), int, decltype(nullptr)>(jsonnet::internal::Identifier const*&, decltype(nullptr)&&, int&&, decltype(nullptr)&&) Line | Count | Source | 477 | 1.37M | { | 478 | 1.37M | T *r = new T(std::forward<Args>(args)...); | 479 | 1.37M | entities.push_back(r); | 480 | 1.37M | r->mark = lastMark; | 481 | 1.37M | numEntities = entities.size(); | 482 | 1.37M | return r; | 483 | 1.37M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapClosure* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapClosure, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >, decltype(nullptr), int, std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapClosure::Param, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapClosure::Param> > const&, jsonnet::internal::AST*&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&&, decltype(nullptr)&&, int&&, std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapClosure::Param, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapClosure::Param> > const&, jsonnet::internal::AST*&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 477 | 28.3M | { | 478 | 28.3M | T *r = new T(std::forward<Args>(args)...); | 479 | 28.3M | entities.push_back(r); | 480 | 28.3M | r->mark = lastMark; | 481 | 28.3M | numEntities = entities.size(); | 482 | 28.3M | return r; | 483 | 28.3M | } |
Unexecuted instantiation: vm.cpp:jsonnet::internal::(anonymous namespace)::HeapComprehensionObject* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapComprehensionObject, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, jsonnet::internal::AST const*&, jsonnet::internal::Identifier const*&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&>(std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, jsonnet::internal::AST const*&, jsonnet::internal::Identifier const*&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&) vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, decltype(nullptr), decltype(nullptr), int, jsonnet::internal::AST const*>(decltype(nullptr)&&, decltype(nullptr)&&, int&&, jsonnet::internal::AST const*&&) Line | Count | Source | 477 | 9.81k | { | 478 | 9.81k | T *r = new T(std::forward<Args>(args)...); | 479 | 9.81k | entities.push_back(r); | 480 | 9.81k | r->mark = lastMark; | 481 | 9.81k | numEntities = entities.size(); | 482 | 9.81k | return r; | 483 | 9.81k | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier*, jsonnet::internal::(anonymous namespace)::HeapObject*&, int, jsonnet::internal::AST* const&>(jsonnet::internal::Identifier*&&, jsonnet::internal::(anonymous namespace)::HeapObject*&, int&&, jsonnet::internal::AST* const&) Line | Count | Source | 477 | 1.56M | { | 478 | 1.56M | T *r = new T(std::forward<Args>(args)...); | 479 | 1.56M | entities.push_back(r); | 480 | 1.56M | r->mark = lastMark; | 481 | 1.56M | numEntities = entities.size(); | 482 | 1.56M | return r; | 483 | 1.56M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST* const&>(jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST* const&) Line | Count | Source | 477 | 74.8M | { | 478 | 74.8M | T *r = new T(std::forward<Args>(args)...); | 479 | 74.8M | entities.push_back(r); | 480 | 74.8M | r->mark = lastMark; | 481 | 74.8M | numEntities = entities.size(); | 482 | 74.8M | return r; | 483 | 74.8M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapClosure* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapClosure, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > > const&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapClosure::Param, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapClosure::Param> > const&, jsonnet::internal::AST*&, char const (&) [1]>(std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > > const&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, std::__1::vector<jsonnet::internal::(anonymous namespace)::HeapClosure::Param, std::__1::allocator<jsonnet::internal::(anonymous namespace)::HeapClosure::Param> > const&, jsonnet::internal::AST*&, char const (&) [1]) Line | Count | Source | 477 | 6.55M | { | 478 | 6.55M | T *r = new T(std::forward<Args>(args)...); | 479 | 6.55M | entities.push_back(r); | 480 | 6.55M | r->mark = lastMark; | 481 | 6.55M | numEntities = entities.size(); | 482 | 6.55M | return r; | 483 | 6.55M | } |
Unexecuted instantiation: vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, decltype(nullptr), int, jsonnet::internal::AST*&>(jsonnet::internal::Identifier const*&, decltype(nullptr)&&, int&&, jsonnet::internal::AST*&) vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const* const&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST* const&>(jsonnet::internal::Identifier const* const&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST* const&) Line | Count | Source | 477 | 60.6M | { | 478 | 60.6M | T *r = new T(std::forward<Args>(args)...); | 479 | 60.6M | entities.push_back(r); | 480 | 60.6M | r->mark = lastMark; | 481 | 60.6M | numEntities = entities.size(); | 482 | 60.6M | return r; | 483 | 60.6M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapSimpleObject* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapSimpleObject, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapSimpleObject::Field, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapSimpleObject::Field> > >&, std::__1::list<jsonnet::internal::AST*, std::__1::allocator<jsonnet::internal::AST*> >&>(std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapSimpleObject::Field, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapSimpleObject::Field> > >&, std::__1::list<jsonnet::internal::AST*, std::__1::allocator<jsonnet::internal::AST*> >&) Line | Count | Source | 477 | 5.88M | { | 478 | 5.88M | T *r = new T(std::forward<Args>(args)...); | 479 | 5.88M | entities.push_back(r); | 480 | 5.88M | r->mark = lastMark; | 481 | 5.88M | numEntities = entities.size(); | 482 | 5.88M | return r; | 483 | 5.88M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST const* const&>(jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST const* const&) Line | Count | Source | 477 | 250 | { | 478 | 250 | T *r = new T(std::forward<Args>(args)...); | 479 | 250 | entities.push_back(r); | 480 | 250 | r->mark = lastMark; | 481 | 250 | numEntities = entities.size(); | 482 | 250 | return r; | 483 | 250 | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapExtendedObject* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapExtendedObject, jsonnet::internal::(anonymous namespace)::HeapObject*&, jsonnet::internal::(anonymous namespace)::HeapObject*&>(jsonnet::internal::(anonymous namespace)::HeapObject*&, jsonnet::internal::(anonymous namespace)::HeapObject*&) Line | Count | Source | 477 | 4.25M | { | 478 | 4.25M | T *r = new T(std::forward<Args>(args)...); | 479 | 4.25M | entities.push_back(r); | 480 | 4.25M | r->mark = lastMark; | 481 | 4.25M | numEntities = entities.size(); | 482 | 4.25M | return r; | 483 | 4.25M | } |
vm.cpp:jsonnet::internal::(anonymous namespace)::HeapThunk* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapThunk, jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST*&>(jsonnet::internal::Identifier const*&, jsonnet::internal::(anonymous namespace)::HeapObject*&, unsigned int&, jsonnet::internal::AST*&) Line | Count | Source | 477 | 1.13M | { | 478 | 1.13M | T *r = new T(std::forward<Args>(args)...); | 479 | 1.13M | entities.push_back(r); | 480 | 1.13M | r->mark = lastMark; | 481 | 1.13M | numEntities = entities.size(); | 482 | 1.13M | return r; | 483 | 1.13M | } |
Unexecuted instantiation: vm.cpp:jsonnet::internal::(anonymous namespace)::HeapComprehensionObject* jsonnet::internal::(anonymous namespace)::Heap::makeEntity<jsonnet::internal::(anonymous namespace)::HeapComprehensionObject, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, jsonnet::internal::AST*&, jsonnet::internal::Identifier const*&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&>(std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&, jsonnet::internal::AST*&, jsonnet::internal::Identifier const*&, std::__1::map<jsonnet::internal::Identifier const*, jsonnet::internal::(anonymous namespace)::HeapThunk*, std::__1::less<jsonnet::internal::Identifier const*>, std::__1::allocator<std::__1::pair<jsonnet::internal::Identifier const* const, jsonnet::internal::(anonymous namespace)::HeapThunk*> > >&) |
484 | | }; |
485 | | |
486 | | } // namespace |
487 | | } // namespace jsonnet::internal |
488 | | |
489 | | #endif // JSONNET_STATE_H |