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