Coverage Report

Created: 2023-02-22 06:51

/src/hermes/include/hermes/VM/Runtime.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) Meta Platforms, Inc. and affiliates.
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
8
#ifndef HERMES_VM_RUNTIME_H
9
#define HERMES_VM_RUNTIME_H
10
11
#include "hermes/Public/DebuggerTypes.h"
12
#include "hermes/Public/RuntimeConfig.h"
13
#include "hermes/Support/Compiler.h"
14
#include "hermes/Support/ErrorHandling.h"
15
#include "hermes/VM/AllocOptions.h"
16
#include "hermes/VM/AllocResult.h"
17
#include "hermes/VM/BasicBlockExecutionInfo.h"
18
#include "hermes/VM/CallResult.h"
19
#include "hermes/VM/Casting.h"
20
#include "hermes/VM/Debugger/Debugger.h"
21
#include "hermes/VM/GC.h"
22
#include "hermes/VM/GCBase-inline.h"
23
#include "hermes/VM/GCStorage.h"
24
#include "hermes/VM/Handle-inline.h"
25
#include "hermes/VM/HandleRootOwner-inline.h"
26
#include "hermes/VM/IdentifierTable.h"
27
#include "hermes/VM/InternalProperty.h"
28
#include "hermes/VM/InterpreterState.h"
29
#include "hermes/VM/PointerBase.h"
30
#include "hermes/VM/Predefined.h"
31
#include "hermes/VM/Profiler.h"
32
#include "hermes/VM/Profiler/SamplingProfilerDefs.h"
33
#include "hermes/VM/PropertyCache.h"
34
#include "hermes/VM/PropertyDescriptor.h"
35
#include "hermes/VM/RegExpMatch.h"
36
#include "hermes/VM/RuntimeModule.h"
37
#include "hermes/VM/StackFrame.h"
38
#include "hermes/VM/StackTracesTree-NoRuntime.h"
39
#include "hermes/VM/SymbolRegistry.h"
40
#include "hermes/VM/TimeLimitMonitor.h"
41
#include "hermes/VM/TwineChar16.h"
42
#include "hermes/VM/VMExperiments.h"
43
44
#ifdef HERMESVM_PROFILER_BB
45
#include "hermes/VM/Profiler/InlineCacheProfiler.h"
46
#endif
47
48
#include "llvh/ADT/DenseMap.h"
49
#include "llvh/ADT/SmallVector.h"
50
51
#include <atomic>
52
#include <chrono>
53
#include <functional>
54
#include <memory>
55
#include <type_traits>
56
#include <vector>
57
58
namespace hermes {
59
// Forward declaration.
60
class JSONEmitter;
61
62
namespace inst {
63
struct Inst;
64
enum class OpCode : uint8_t;
65
} // namespace inst
66
67
namespace hbc {
68
class BytecodeModule;
69
struct CompileFlags;
70
} // namespace hbc
71
72
namespace vm {
73
74
// External forward declarations.
75
class CodeBlock;
76
class Environment;
77
class Interpreter;
78
class JSObject;
79
class PropertyAccessor;
80
struct RuntimeCommonStorage;
81
struct RuntimeOffsets;
82
class ScopedNativeDepthReducer;
83
class ScopedNativeDepthTracker;
84
class ScopedNativeCallFrame;
85
class CodeCoverageProfiler;
86
struct MockedEnvironment;
87
struct StackTracesTree;
88
89
#if HERMESVM_SAMPLING_PROFILER_AVAILABLE
90
class SamplingProfiler;
91
#endif // HERMESVM_SAMPLING_PROFILER_AVAILABLE
92
93
#ifdef HERMESVM_PROFILER_BB
94
class JSArray;
95
#endif
96
97
/// Number of stack words after the top of frame that we always ensure are
98
/// available. This is necessary so we can perform native calls with small
99
/// number of arguments without checking.
100
static const unsigned STACK_RESERVE = 32;
101
102
/// Type used to assign object unique integer identifiers.
103
using ObjectID = uint32_t;
104
105
#define PROP_CACHE_IDS(V) V(RegExpLastIndex, Predefined::lastIndex)
106
107
/// Fixed set of ids used by the property cache in Runtime.
108
enum class PropCacheID {
109
#define V(id, predef) id,
110
  PROP_CACHE_IDS(V)
111
#undef V
112
      _COUNT
113
};
114
115
/// Trace of the last few instructions for debugging crashes.
116
class CrashTraceImpl {
117
  /// Record of the last executed instruction.
118
  struct Record {
119
    /// Offset from start of bytecode file.
120
    uint32_t ipOffset;
121
    /// Opcode of last executed instruction.
122
    inst::OpCode opCode;
123
  };
124
125
 public:
126
  /// Record the currently executing module, replacing the info of the
127
  /// previous one.
128
  inline void recordModule(
129
      uint32_t segmentID,
130
      llvh::StringRef sourceURL,
131
      llvh::StringRef sourceHash);
132
133
  /// Add a record to the circular trace buffer.
134
0
  void recordInst(uint32_t ipOffset, inst::OpCode opCode) {
135
0
    static_assert(
136
0
        kTraceLength && (kTraceLength & (kTraceLength - 1)) == 0,
137
0
        "kTraceLength must be a power of 2");
138
0
    unsigned n = (last_ + 1) & (kTraceLength - 1);
139
0
    last_ = n;
140
0
    Record *p = trace_ + n;
141
0
    p->ipOffset = ipOffset;
142
0
    p->opCode = opCode;
143
0
  }
144
145
 private:
146
  /// Size of the circular buffer.
147
  static constexpr unsigned kTraceLength = 8;
148
  /// The index of the last entry written to the buffer.
149
  unsigned last_ = kTraceLength - 1;
150
  /// A circular buffer of Record.
151
  Record trace_[kTraceLength] = {};
152
153
  /// Current segmentID.
154
  uint32_t segmentID_ = 0;
155
  /// Source URL, truncated, zero terminated.
156
  char sourceURL_[16] = {};
157
  /// SHA1 source hash.
158
  uint8_t sourceHash_[20] = {};
159
};
160
161
inline void CrashTraceImpl::recordModule(
162
    uint32_t segmentID,
163
    llvh::StringRef sourceURL,
164
0
    llvh::StringRef sourceHash) {
165
0
  segmentID_ = segmentID;
166
0
  size_t len = std::min(sizeof(sourceURL_) - 1, sourceURL.size());
167
0
  ::memcpy(sourceURL_, sourceURL.data(), len);
168
0
  sourceURL_[len] = 0;
169
0
  ::memcpy(
170
0
      sourceHash_,
171
0
      sourceHash.data(),
172
0
      std::min(sizeof(sourceHash_), sourceHash.size()));
173
0
}
174
175
class CrashTraceNoop {
176
 public:
177
  void recordModule(
178
      uint32_t segmentID,
179
      llvh::StringRef sourceURL,
180
0
      llvh::StringRef sourceHash) {}
181
182
  /// Add a record to the circular trace buffer.
183
0
  void recordInst(uint32_t ipOffset, inst::OpCode opCode) {}
184
};
185
186
#ifndef HERMESVM_CRASH_TRACE
187
// Make sure it is 0 or 1 so it can be checked in C++.
188
310
#define HERMESVM_CRASH_TRACE 0
189
#endif
190
191
#if HERMESVM_CRASH_TRACE
192
using CrashTrace = CrashTraceImpl;
193
#else
194
using CrashTrace = CrashTraceNoop;
195
#endif
196
197
/// The Runtime encapsulates the entire context of a VM. Multiple instances can
198
/// exist and are completely independent from each other.
199
class HERMES_EMPTY_BASES Runtime : public PointerBase,
200
                                   public HandleRootOwner,
201
                                   private GCBase::GCCallbacks {
202
 public:
203
  static std::shared_ptr<Runtime> create(const RuntimeConfig &runtimeConfig);
204
205
  ~Runtime() override;
206
207
  /// Add a custom function that will be executed at the start of every garbage
208
  /// collection to mark additional GC roots that may not be known to the
209
  /// Runtime.
210
  void addCustomRootsFunction(
211
      std::function<void(GC *, RootAcceptor &)> markRootsFn);
212
213
  /// Add a custom function that will be executed sometime during garbage
214
  /// collection to mark additional weak GC roots that may not be known to the
215
  /// Runtime.
216
  void addCustomWeakRootsFunction(
217
      std::function<void(GC *, WeakRootAcceptor &)> markRootsFn);
218
219
  /// Add a custom function that will be executed when a heap snapshot is taken,
220
  /// to add any extra nodes.
221
  /// \param nodes Use snap.beginNode() and snap.endNode() to create nodes in
222
  ///   snapshot graph.
223
  /// \param edges Use snap.addNamedEdge() or snap.addIndexedEdge() to create
224
  ///   edges to the nodes defined in \p nodes.
225
  void addCustomSnapshotFunction(
226
      std::function<void(HeapSnapshot &)> nodes,
227
      std::function<void(HeapSnapshot &)> edges);
228
229
  /// Make the runtime read from \p env to replay its environment-dependent
230
  /// behavior.
231
  void setMockedEnvironment(const MockedEnvironment &env);
232
233
  /// Runs the given UTF-8 \p code in a new RuntimeModule as top-level code.
234
  /// Note that if compileFlags.lazy is set, the code string will be copied.
235
  /// \param sourceURL the location of the source that's being run.
236
  /// \param compileFlags Flags controlling compilation.
237
  /// \return the status of the execution.
238
  CallResult<HermesValue> run(
239
      llvh::StringRef code,
240
      llvh::StringRef sourceURL,
241
      const hbc::CompileFlags &compileFlags);
242
243
  /// Runs the given UTF-8 \p code in a new RuntimeModule as top-level code.
244
  /// \param sourceURL the location of the source that's being run.
245
  /// \param compileFlags Flags controlling compilation.
246
  /// \return the status of the execution.
247
  CallResult<HermesValue> run(
248
      std::unique_ptr<Buffer> code,
249
      llvh::StringRef sourceURL,
250
      const hbc::CompileFlags &compileFlags);
251
252
  /// Runs the given \p bytecode with the given \p runtimeModuleFlags. The \p
253
  /// sourceURL, if not empty, is reported as the file name in backtraces. If \p
254
  /// environment is not null, set it as the environment associated with the
255
  /// initial JSFunction, which enables local eval. \p thisArg the "this"
256
  /// argument to use initially. \p isPersistent indicates whether the created
257
  /// runtime module should persist in memory.
258
  CallResult<HermesValue> runBytecode(
259
      std::shared_ptr<hbc::BCProvider> &&bytecode,
260
      RuntimeModuleFlags runtimeModuleFlags,
261
      llvh::StringRef sourceURL,
262
      Handle<Environment> environment,
263
      Handle<> thisArg);
264
265
  /// Runs the given \p bytecode. If \p environment is not null, set it as the
266
  /// environment associated with the initial JSFunction, which enables local
267
  /// eval.
268
  /// Uses global_ as the "this" value initially.
269
  /// \p isPersistent indicates whether the created runtime module should
270
  /// persist in memory.
271
  CallResult<HermesValue> runBytecode(
272
      std::shared_ptr<hbc::BCProvider> &&bytecode,
273
      RuntimeModuleFlags runtimeModuleFlags,
274
      llvh::StringRef sourceURL,
275
155
      Handle<Environment> environment) {
276
155
    getHeap().runtimeWillExecute();
277
155
    return runBytecode(
278
155
        std::move(bytecode),
279
155
        runtimeModuleFlags,
280
155
        sourceURL,
281
155
        environment,
282
155
        Handle<>(&global_));
283
155
  }
284
285
  ExecutionStatus loadSegment(
286
      std::shared_ptr<hbc::BCProvider> &&bytecode,
287
      Handle<RequireContext> requireContext,
288
      RuntimeModuleFlags flags = {});
289
290
  /// Runs the internal bytecode. This is called once during initialization.
291
  /// \return the completion value of internal bytecode IIFE.
292
  Handle<JSObject> runInternalBytecode();
293
294
  /// A convenience function to print an exception to a stream.
295
  void printException(llvh::raw_ostream &os, Handle<> valueHandle);
296
297
  /// @name Heap management
298
  /// @{
299
300
  /// Create a fixed size object of type T.
301
  /// If necessary perform a GC cycle, which may potentially move
302
  /// allocated objects.
303
  /// \return a pointer to the newly created object in the GC heap.
304
  template <
305
      typename T,
306
      HasFinalizer hasFinalizer = HasFinalizer::No,
307
      LongLived longLived = LongLived::No,
308
      class... Args>
309
  T *makeAFixed(Args &&...args);
310
311
  /// Create a variable size object of type T and size \p size.
312
  /// If necessary perform a GC cycle, which may potentially move
313
  /// allocated objects.
314
  /// \return a pointer to the newly created object in the GC heap.
315
  template <
316
      typename T,
317
      HasFinalizer hasFinalizer = HasFinalizer::No,
318
      LongLived longLived = LongLived::No,
319
      class... Args>
320
  T *makeAVariable(uint32_t size, Args &&...args);
321
322
  /// Used as a placeholder for places where we should be checking for OOM
323
  /// but aren't yet.
324
  /// TODO: do something when there is an uncaught exception, e.g. print
325
  /// stack traces.
326
  template <typename T>
327
  T ignoreAllocationFailure(CallResult<T> res);
328
329
  /// Used as a placeholder for places where we should be checking for OOM
330
  /// but aren't yet.
331
  void ignoreAllocationFailure(ExecutionStatus status);
332
333
  // Inform the VM that TTI has been reached.  (In case, for example, the
334
  // runtime should change its behavior at that point.)
335
  void ttiReached();
336
337
  /// Force a garbage collection cycle.
338
133
  void collect(std::string cause) {
339
133
    getHeap().collect(std::move(cause));
340
133
  }
341
342
  /// Potentially move the heap if handle sanitization is on.
343
  void potentiallyMoveHeap();
344
345
  using HandleRootOwner::makeHandle;
346
  using HandleRootOwner::makeMutableHandle;
347
348
  /// Convenience function to create a Handle from a GCPointer.
349
  template <class T>
350
  inline Handle<T> makeHandle(const GCPointer<T> &p);
351
352
  /// Convenience function to create a MutableHandle from a GCPointer.
353
  template <class T>
354
  MutableHandle<T> makeMutableHandle(const GCPointer<T> &p);
355
356
  /// \return the \c StringPrimitive of a predefined string.
357
  StringPrimitive *getPredefinedString(Predefined::Str predefined);
358
  StringPrimitive *getPredefinedString(Predefined::Sym predefined);
359
360
  /// \return a \c Handle<StringPrimitive> to a predefined string.
361
  Handle<StringPrimitive> getPredefinedStringHandle(Predefined::Str predefined);
362
  Handle<StringPrimitive> getPredefinedStringHandle(Predefined::Sym predefined);
363
364
  /// \return the \c StringPrimitive given a symbol ID \p id.
365
  inline StringPrimitive *getStringPrimFromSymbolID(SymbolID id);
366
367
  /// \return true if a symbol specified by \p id has the same string content
368
  /// as a given string primitive \p strPrim.
369
  bool symbolEqualsToStringPrim(SymbolID id, StringPrimitive *strPrim);
370
371
  /// A wrapper to facilitate printing the name of a SymbolID to a stream.
372
  struct FormatSymbolID {
373
    Runtime &runtime;
374
    SymbolID const symbolID;
375
376
    FormatSymbolID(Runtime &runtime, SymbolID symbolID)
377
0
        : runtime(runtime), symbolID(symbolID) {}
378
  };
379
380
  /// Create an object that when serialized to a stream will print the contents
381
  /// of a SymbolID.
382
  FormatSymbolID formatSymbolID(SymbolID id);
383
384
16.2M
  GC &getHeap() {
385
16.2M
    return *heapStorage_.get();
386
16.2M
  }
387
388
  /// @}
389
390
  /// Return a pointer to a callable builtin identified by id.
391
  /// Unfortunately we can't use the enum here, since we don't want to include
392
  /// the builtins header header.
393
  inline Callable *getBuiltinCallable(unsigned builtinMethodID);
394
395
  /// ES6-ES11 8.4.1 EnqueueJob ( queueName, job, arguments )
396
  /// See \c jobQueue_ for how the Jobs and Job Queues are set up in Hermes.
397
  inline void enqueueJob(Callable *job);
398
399
  /// ES6-ES11 8.6 RunJobs ( )
400
  /// Draining the job queue by invoking the queued jobs in FIFO order.
401
  ///
402
  /// \return ExecutionStatus::RETURNED if the job queue is emptied and no
403
  /// exception was thrown from any job. Otherwise, ExecutionStatus::EXCEPTION
404
  /// if an exception was thrown and the draining is stopped.
405
  /// It's the caller's responsibility to check the status and re-invoke this
406
  /// function to resume the draining to fulfill the microtask requirements.
407
  ///
408
  /// Note that ECMA-262 Promise Jobs always handle internal abruptCompletion
409
  /// by returning a rejected Promise. However, the capability of propagating
410
  /// exception per job is required by `queueMicrotask` to properly "report the
411
  /// exception" (https://html.spec.whatwg.org/C#microtask-queuing).
412
  ExecutionStatus drainJobs();
413
414
  // ES2021 9.12 "When the abstract operation AddToKeptObjects is called with a
415
  // target object reference, it adds the target to a list that will point
416
  // strongly at the target until ClearKeptObjects is called."
417
  ExecutionStatus addToKeptObjects(Handle<JSObject> obj);
418
419
  // ES2021 9.11 "ECMAScript implementations are
420
  // expected to call ClearKeptObjects when a synchronous sequence of ECMAScript
421
  // executions completes." This method clears all kept WeakRefs and allows
422
  // their targets to be eligible for garbage collection again.
423
  void clearKeptObjects();
424
425
466k
  IdentifierTable &getIdentifierTable() {
426
466k
    return identifierTable_;
427
466k
  }
428
429
0
  SymbolRegistry &getSymbolRegistry() {
430
0
    return symbolRegistry_;
431
0
  }
432
433
  /// Return a StringPrimitive representation of a single character. The first
434
  /// 256 characters are pre-allocated. The rest are allocated every time.
435
  Handle<StringPrimitive> getCharacterString(char16_t ch);
436
437
0
  CodeBlock *getEmptyCodeBlock() const {
438
0
    assert(emptyCodeBlock_ && "Invalid empty code block");
439
0
    return emptyCodeBlock_;
440
0
  }
441
442
0
  CodeBlock *getReturnThisCodeBlock() const {
443
0
    assert(returnThisCodeBlock_ && "Invalid return this code block");
444
0
    return returnThisCodeBlock_;
445
0
  }
446
447
  /// \return the next unique object ID.
448
0
  ObjectID generateNextObjectID() {
449
0
    return ++nextObjectID_;
450
0
  }
451
452
  /// Compute a hash value of a given HermesValue that is guaranteed to
453
  /// be stable with a moving GC. It however does not guarantee to be
454
  /// a perfect hash for strings.
455
  uint64_t gcStableHashHermesValue(Handle<HermesValue> value);
456
457
  /// @name Public VM State
458
  /// @{
459
460
  /// \return the current stack pointer.
461
407k
  PinnedHermesValue *getStackPointer() {
462
407k
    return stackPointer_;
463
407k
  }
464
465
  /// Pop the register stack down to a previously saved stack pointer.
466
  inline void popToSavedStackPointer(PinnedHermesValue *stackPointer);
467
468
  /// \return the number of elements in the stack.
469
  inline uint32_t getStackLevel() const;
470
471
  /// Return the available stack size (in registers).
472
  inline uint32_t availableStackSize() const;
473
474
  /// \return true if there is space to allocate <tt>count + STACK_RESERVE</tt>
475
  /// registers.
476
  inline bool checkAvailableStack(uint32_t count);
477
478
  /// Allocate stack space for \p registers, but keep it uninitialized. The
479
  /// caller should initialize it ASAP.
480
  /// \return the new stack pointer.
481
  inline PinnedHermesValue *allocUninitializedStack(uint32_t count);
482
483
  /// Allocate stack space for \p registers and initialize them with
484
  /// \p initValue.
485
  /// See implementation for why this is not inlined.
486
  LLVM_ATTRIBUTE_NOINLINE
487
  void allocStack(uint32_t count, HermesValue initValue);
488
489
  /// Check whether <tt>count + STACK_RESERVE</tt> stack registers are available
490
  /// and allocate \p count registers.
491
  /// \param count number of registers to allocate.
492
  /// \param initValue initialize the allocated registers with this value.
493
  /// \return \c true if allocation was successful.
494
  inline bool checkAndAllocStack(uint32_t count, HermesValue initValue);
495
496
  /// Pop the specified number of elements from the stack.
497
  inline void popStack(uint32_t count);
498
499
  /// \return the current frame pointer.
500
2.83k
  StackFramePtr getCurrentFrame() {
501
2.83k
    return currentFrame_;
502
2.83k
  }
503
504
  /// Set the current frame pointer to the current top of the stack and return
505
  /// it.
506
  /// \param topFrame a frame constructed at the top of stack. It must equal
507
  ///   stackPointer_, but it is more efficient to pass it in if it already
508
  ///   is in a register. It also provides some additional error checking in
509
  ///   debug builds, ensuring that the stack hasn't changed unexpectedly.
510
  inline void setCurrentFrameToTopOfStack(StackFramePtr topFrame);
511
512
  /// Set the current frame pointer to the current top of the stack and return
513
  /// it.
514
  /// \return the new value of the current frame pointer.
515
  inline StackFramePtr setCurrentFrameToTopOfStack();
516
517
  /// Restore the stack pointer to the base of the current frame and then
518
  /// set the frame pointer to the previous frame.
519
  /// \param currentFrame the currentFrame. It must match the value of
520
  ///   this->currentFrame_, but is more efficient to pass it in assuming it
521
  ///   already is in a register. It also provides some additional error
522
  ///   checking in debug builds, ensuring that the stack hasn't changed
523
  ///   unexpectedly.
524
  /// \return the updated value of the current frame pointer.
525
  inline StackFramePtr restoreStackAndPreviousFrame(StackFramePtr currentFrame);
526
527
  /// Restore the stack pointer to the base of the current frame and then
528
  /// set the frame pointer to the previous frame.
529
  /// \return the updated value of the current frame pointer.
530
  inline StackFramePtr restoreStackAndPreviousFrame();
531
532
  /// \return an iterator range that provides access to all stack frames
533
  /// starting from the top-most one.
534
  inline llvh::iterator_range<StackFrameIterator> getStackFrames();
535
536
  /// \return an iterator range that provides access to all stack frames
537
  /// starting from the top-most one.
538
  inline llvh::iterator_range<ConstStackFrameIterator> getStackFrames() const;
539
540
  /// Dump information about all stack frames to \p OS.
541
  void dumpCallFrames(llvh::raw_ostream &OS);
542
543
  /// Dump information about all stack frames to llvh::errs(). This is a
544
  /// helper method intended to be called from a debugger.
545
  void dumpCallFrames();
546
547
  /// \return `thrownValue`.
548
24
  HermesValue getThrownValue() const {
549
24
    return thrownValue_;
550
24
  }
551
552
  /// Set `thrownValue` to the specified value \p value, `returnValue` to
553
  /// empty and \return ExecutionResult::EXCEPTION.
554
  ExecutionStatus setThrownValue(HermesValue value);
555
556
  /// Set `thrownValue` to empty.
557
  void clearThrownValue();
558
559
  /// Return a hidden class corresponding to the specified prototype object
560
  /// and number of reserved slots. For now we only use the latter.
561
  inline Handle<HiddenClass> getHiddenClassForPrototype(
562
      JSObject *proto,
563
      unsigned reservedSlots);
564
565
  /// Return the global object.
566
  Handle<JSObject> getGlobal();
567
568
  /// Returns trailing data for all runtime modules.
569
  std::vector<llvh::ArrayRef<uint8_t>> getEpilogues();
570
571
  void printHeapStats(llvh::raw_ostream &os);
572
573
  /// Write IO tracking (aka HBC page access) info to the supplied
574
  /// stream as JSON. There will only be useful data for RuntimeModules
575
  /// backed by mmap'ed bytecode, and there will only be any data at all if
576
  /// RuntimeConfig::withTrackIO() has been set, and IO tracking is available on
577
  /// the current platform.
578
  void getIOTrackingInfoJSON(llvh::raw_ostream &os);
579
580
#ifndef NDEBUG
581
  /// Iterate over all arrays in the heap and print their sizes and capacities.
582
  void printArrayCensus(llvh::raw_ostream &os);
583
#endif
584
585
  /// Returns the common storage object.
586
0
  RuntimeCommonStorage *getCommonStorage() {
587
0
    return commonStorage_.get();
588
0
  }
589
590
0
  const GCExecTrace &getGCExecTrace() {
591
0
    return getHeap().getGCExecTrace();
592
0
  }
593
594
#if defined(HERMES_ENABLE_DEBUGGER)
595
  /// Request the interpreter loop to take an asynchronous break at a convenient
596
  /// point due to debugger UI request. This may be called from any thread, or a
597
  /// signal handler.
598
  void triggerDebuggerAsyncBreak(
599
0
      ::facebook::hermes::debugger::AsyncPauseKind kind) {
600
0
    triggerAsyncBreak(
601
0
        kind == ::facebook::hermes::debugger::AsyncPauseKind::Explicit
602
0
            ? AsyncBreakReasonBits::DebuggerExplicit
603
0
            : AsyncBreakReasonBits::DebuggerImplicit);
604
0
  }
605
#endif
606
607
  /// Request the interpreter loop to take an asynchronous break at a convenient
608
  /// point due to previous registered timeout. This may be called from any
609
  /// thread, or a signal handler.
610
0
  void triggerTimeoutAsyncBreak() {
611
0
    triggerAsyncBreak(AsyncBreakReasonBits::Timeout);
612
0
  }
613
614
#ifdef HERMES_ENABLE_DEBUGGER
615
  /// Encapsulates useful information about a stack frame, needed by the
616
  /// debugger. It requres extra context and cannot be extracted from a
617
  /// single frame pointer.
618
  struct StackFrameInfo {
619
    ConstStackFramePtr frame;
620
    bool isGlobal;
621
  };
622
623
  /// Extract \c StackFrameInfo of the specified stack frame.
624
  /// \param frameIdx a relative frame index where the top-most frame is 0.
625
  /// \return a populated StackFrameInfo, or llvh::None if the frame is invalid.
626
  llvh::Optional<StackFrameInfo> stackFrameInfoByIndex(uint32_t frameIdx) const;
627
628
  /// Calculate and \return the offset between the location of the specified
629
  /// frame and the start of the stack. This value increases with every nested
630
  /// call.
631
  uint32_t calcFrameOffset(ConstStackFrameIterator it) const;
632
633
  /// \return the offset between the location of the current frame and the
634
  ///   start of the stack. This value increases with every nested call.
635
  uint32_t getCurrentFrameOffset() const;
636
#endif
637
638
  /// Flag the interpreter that an error with the specified \p msg must be
639
  /// thrown when execution resumes.
640
  /// \return ExecutionResult::EXCEPTION
641
  LLVM_NODISCARD ExecutionStatus raiseError(const TwineChar16 &msg);
642
643
  /// Flag the interpreter that a type error with the specified message must be
644
  /// thrown when execution resumes.
645
  /// If the message is not a string, it is converted using toString().
646
  LLVM_NODISCARD ExecutionStatus raiseTypeError(Handle<> message);
647
648
  /// Flag the interpreter that a type error must be thrown when execution
649
  /// resumes.
650
  /// \return ExecutionResult::EXCEPTION
651
  LLVM_NODISCARD ExecutionStatus raiseTypeError(const TwineChar16 &msg);
652
653
  /// Flag the interpreter that a type error must be thrown when execution
654
  /// resumes. The string thrown concatenates a description of \p value
655
  /// with \p msg.
656
  /// \return ExecutionResult::EXCEPTION
657
  LLVM_NODISCARD ExecutionStatus
658
0
  raiseTypeErrorForValue(Handle<> value, llvh::StringRef msg) {
659
0
    return raiseTypeErrorForValue("", value, msg);
660
0
  }
661
662
  /// Flag the interpreter that a type error must be thrown when execution
663
  /// resumes. The string thrown concatenates \p msg1, a description of \p
664
  /// value, and \p msg2. \return ExecutionResult::EXCEPTION
665
  LLVM_NODISCARD ExecutionStatus raiseTypeErrorForValue(
666
      const TwineChar16 &msg1,
667
      Handle<> value,
668
      const TwineChar16 &msg2);
669
670
  /// Flag the interpreter that a type error must be thrown when execution
671
  /// resumes. The string thrown concatenates either the textified callable for
672
  /// \p callable (if it is available) with " is not a function"; or a
673
  /// description of \p callable with " is not a function". \return
674
  /// ExecutionResult::EXCEPTION
675
  LLVM_NODISCARD ExecutionStatus raiseTypeErrorForCallable(Handle<> callable);
676
677
  /// Flag the interpreter that a syntax error must be thrown.
678
  /// \return ExecutionStatus::EXCEPTION
679
  LLVM_NODISCARD ExecutionStatus raiseSyntaxError(const TwineChar16 &msg);
680
681
  /// Raise a special SyntaxError when attempting to eval when disallowed.
682
  LLVM_NODISCARD ExecutionStatus raiseEvalUnsupported(llvh::StringRef code);
683
684
  /// Raise a \c RangeError exception.
685
  /// \return ExecutionStatus::EXCEPTION
686
  LLVM_NODISCARD ExecutionStatus raiseRangeError(const TwineChar16 &msg);
687
688
  /// Raise a \c ReferenceError exception.
689
  /// \return ExecutionStatus::EXCEPTION
690
  LLVM_NODISCARD ExecutionStatus raiseReferenceError(const TwineChar16 &msg);
691
692
  /// Raise a \c URIError exception.
693
  /// \return ExecutionStatus::EXCEPTION
694
  LLVM_NODISCARD ExecutionStatus raiseURIError(const TwineChar16 &msg);
695
696
  enum class StackOverflowKind {
697
    // The JS register stack was exhausted.
698
    JSRegisterStack,
699
    // A limit on the number of native stack frames used in
700
    // evaluation, intended to conservatively prevent native stack
701
    // overflow, was exceeded.
702
    NativeStack,
703
    // RuntimeJSONParser has a maximum number of "nesting levels", and
704
    // calls raiseStackOverflow if that is exceeded.
705
    JSONParser,
706
    // JSONStringifyer has the same limit as JSONParser.
707
    JSONStringify,
708
  };
709
710
  /// Raise a stack overflow exception. This is special because constructing
711
  /// the object must not execute any custom or JavaScript code.  The
712
  /// argument influences the exception's message, to aid debugging.
713
  /// \return ExecutionStatus::EXCEPTION
714
  LLVM_NODISCARD ExecutionStatus raiseStackOverflow(StackOverflowKind kind);
715
716
  /// Raise an error for the quit function. This error is not catchable.
717
  LLVM_NODISCARD ExecutionStatus raiseQuitError();
718
719
  /// Raise an error for execution timeout. This error is not catchable.
720
  LLVM_NODISCARD ExecutionStatus raiseTimeoutError();
721
722
  /// Utility function to raise a catchable JS error with \p errMessage.
723
  LLVM_NODISCARD ExecutionStatus
724
  raiseUncatchableError(Handle<JSObject> prototype, llvh::StringRef errMessage);
725
726
  /// Interpret the current function until it returns or throws and return
727
  /// CallResult<HermesValue> or the thrown object in 'thrownObject'.
728
  CallResult<HermesValue> interpretFunction(CodeBlock *newCodeBlock);
729
730
#ifdef HERMES_ENABLE_DEBUGGER
731
  /// Single-step the provided function, update the interpreter state.
732
  ExecutionStatus stepFunction(InterpreterState &state);
733
#endif
734
735
  /// Inserts an object into the string cycle checking stack if it does not
736
  /// already exist.
737
  /// \return true if a cycle was found
738
  bool insertVisitedObject(JSObject *obj);
739
740
  /// Removes the last element (which must be obj) from the cycle check stack.
741
  /// \param obj the last element, which will be removed. Used for checking
742
  /// that invariants aren't violated in debug mode.
743
  void removeVisitedObject(JSObject *obj);
744
745
  /// Like calling JSObject::getNamed, but uses this runtime's property cache.
746
  CallResult<PseudoHandle<>> getNamed(Handle<JSObject> obj, PropCacheID id);
747
748
  /// Like calling JSObject::putNamed with the ThrowOnError flag, but uses this
749
  /// runtime's property cache.
750
  ExecutionStatus putNamedThrowOnError(
751
      Handle<JSObject> obj,
752
      PropCacheID id,
753
      SmallHermesValue hv);
754
755
  /// @}
756
757
#define RUNTIME_HV_FIELD(name) PinnedHermesValue name{};
758
#define RUNTIME_HV_FIELD_PROTOTYPE(name) RUNTIME_HV_FIELD(name)
759
#define RUNTIME_HV_FIELD_INSTANCE(name) RUNTIME_HV_FIELD(name)
760
#define RUNTIME_HV_FIELD_RUNTIMEMODULE(name) RUNTIME_HV_FIELD(name)
761
#include "hermes/VM/RuntimeHermesValueFields.def"
762
#undef RUNTIME_HV_FIELD
763
764
  /// Raw pointers to prototypes.
765
  JSObject *objectPrototypeRawPtr{};
766
767
  JSObject *functionPrototypeRawPtr{};
768
769
  RegExpMatch regExpLastMatch{};
770
771
  /// Whether to allow eval and Function ctor.
772
  const bool enableEval : 1;
773
  /// Whether to verify the IR being generated by eval and the Function ctor.
774
  const bool verifyEvalIR : 1;
775
  /// Whether to optimize the code in the string passed to eval and the Function
776
  /// ctor.
777
  const bool optimizedEval : 1;
778
  /// Whether to emit async break check instructions in eval().
779
  const bool asyncBreakCheckInEval : 1;
780
781
#ifdef HERMESVM_PROFILER_OPCODE
782
  /// Track the frequency of each opcode in the interpreter.
783
  uint32_t opcodeExecuteFrequency[256] = {0};
784
785
  /// Track time spent of each opcode in the interpreter, in CPU cycles.
786
  uint64_t timeSpent[256] = {0};
787
788
  /// Dump opcode stats to a stream.
789
  void dumpOpcodeStats(llvh::raw_ostream &os) const;
790
#endif
791
792
#if defined(HERMESVM_PROFILER_JSFUNCTION)
793
  static std::atomic<ProfilerID> nextProfilerId;
794
795
  std::vector<ProfilerFunctionInfo> functionInfo{};
796
797
  /// Get block's index in functionInfo (creating a new entry if needed).
798
  ProfilerID getProfilerID(CodeBlock *block);
799
800
  /// Get profiler info associated with given id or nullptr if the id
801
  /// is not associated with any function.
802
  const ProfilerFunctionInfo *getProfilerInfo(ProfilerID id);
803
804
  /// Track the maximum size of the stack.
805
  uint32_t maxStackLevel = 0;
806
#endif
807
808
#if defined(HERMESVM_PROFILER_JSFUNCTION)
809
  std::vector<ProfilerFunctionEvent> functionEvents{};
810
811
  /// Total number of opcodes executed by this runtime.
812
  uint64_t opcodeCount = 0;
813
814
  /// Dump function profiling stats to stdout.
815
  enum class ProfileType{TIME, OPCODES, ALL};
816
  void dumpJSFunctionStats(ProfileType type = ProfileType::ALL);
817
#endif
818
819
#ifdef HERMESVM_PROFILER_BB
820
  BasicBlockExecutionInfo &getBasicBlockExecutionInfo();
821
822
  /// Dump basic block profile trace to \p OS in json format.
823
  void dumpBasicBlockProfileTrace(llvh::raw_ostream &OS);
824
#endif
825
826
1.64k
  CodeCoverageProfiler &getCodeCoverageProfiler() {
827
1.64k
    return *codeCoverageProfiler_;
828
1.64k
  }
829
830
#if HERMESVM_SAMPLING_PROFILER_AVAILABLE
831
  /// Sampling profiler data for this runtime. The ctor/dtor of SamplingProfiler
832
  /// will automatically register/unregister this runtime from profiling.
833
  std::unique_ptr<SamplingProfiler> samplingProfiler;
834
#endif // HERMESVM_SAMPLING_PROFILER_AVAILABLE
835
836
  /// Time limit monitor data for this runtime.
837
  std::shared_ptr<TimeLimitMonitor> timeLimitMonitor;
838
839
#ifdef HERMESVM_PROFILER_NATIVECALL
840
  /// Dump statistics about native calls.
841
  void dumpNativeCallStats(llvh::raw_ostream &OS);
842
#endif
843
844
#ifdef HERMES_ENABLE_DEBUGGER
845
1.89k
  Debugger &getDebugger() {
846
1.89k
    return debugger_;
847
1.89k
  }
848
#endif
849
850
0
  RuntimeModuleList &getRuntimeModules() {
851
0
    return runtimeModuleList_;
852
0
  }
853
854
198
  bool hasES6Promise() const {
855
198
    return hasES6Promise_;
856
198
  }
857
858
198
  bool hasES6Proxy() const {
859
198
    return hasES6Proxy_;
860
198
  }
861
862
0
  bool hasIntl() const {
863
0
    return hasIntl_;
864
0
  }
865
866
99
  bool hasArrayBuffer() const {
867
99
    return hasArrayBuffer_;
868
99
  }
869
870
297
  bool hasMicrotaskQueue() const {
871
297
    return hasMicrotaskQueue_;
872
297
  }
873
874
0
  bool builtinsAreFrozen() const {
875
0
    return builtinsFrozen_;
876
0
  }
877
878
  bool shouldStabilizeInstructionCount();
879
880
1.22k
  experiments::VMExperimentFlags getVMExperimentFlags() const {
881
1.22k
    return vmExperimentFlags_;
882
1.22k
  }
883
884
  // Return a reference to the runtime's CrashManager.
885
  inline CrashManager &getCrashManager();
886
887
  /// Returns a string representation of the JS stack.  Does no operations
888
  /// that allocate on the JS heap, so safe to use for an out-of-memory
889
  /// exception.
890
  /// \p ip specifies the the IP of the leaf frame.
891
  std::string getCallStackNoAlloc(const Inst *ip);
892
893
  /// \return a string representation of the JS stack without knowing the leaf
894
  /// frame ip.  Does no operations that allocate on the JS heap, so safe to use
895
  /// for an out-of-memory exception.
896
0
  std::string getCallStackNoAlloc() override {
897
0
    return getCallStackNoAlloc(nullptr);
898
0
  }
899
900
  /// \return whether we are currently formatting a stack trace. Used to break
901
  /// recursion in Error.prepareStackTrace.
902
0
  bool formattingStackTrace() const {
903
0
    return formattingStackTrace_;
904
0
  }
905
906
  /// Mark whether we are currently formatting a stack trace. Used to break
907
  /// recursion in Error.prepareStackTrace.
908
0
  void setFormattingStackTrace(bool value) {
909
0
    assert(
910
0
        value != formattingStackTrace() &&
911
0
        "All calls to setFormattingStackTrace must actually change the current state");
912
0
    formattingStackTrace_ = value;
913
0
  }
914
915
  /// A stack overflow exception is thrown when \c nativeCallFrameDepth_ exceeds
916
  /// this threshold.
917
  static constexpr unsigned MAX_NATIVE_CALL_FRAME_DEPTH =
918
#ifdef HERMES_LIMIT_STACK_DEPTH
919
      // UBSAN builds will hit a native stack overflow much earlier, so make
920
      // this limit dramatically lower.
921
      30
922
#elif defined(_MSC_VER) && defined(__clang__) && defined(HERMES_SLOW_DEBUG)
923
      30
924
#elif defined(_MSC_VER) && defined(HERMES_SLOW_DEBUG)
925
      // On windows in dbg mode builds, stack frames are bigger, and a depth
926
      // limit of 384 results in a C++ stack overflow in testing.
927
      128
928
#elif defined(_MSC_VER) && !NDEBUG
929
      192
930
#else
931
      /// This depth limit was originally 256, and we
932
      /// increased when an app violated it.  The new depth is 128
933
      /// larger.  See T46966147 for measurements/calculations indicating
934
      /// that this limit should still insulate us from native stack overflow.)
935
      384
936
#endif
937
      ;
938
939
  /// Called when various GC events(e.g. collection start/end) happen.
940
  void onGCEvent(GCEventKind kind, const std::string &extraInfo) override;
941
942
#ifdef HERMESVM_PROFILER_BB
943
  using ClassId = InlineCacheProfiler::ClassId;
944
945
  /// Get filename, line number, and column number from
946
  /// code block and instruction pointer. It returns true if it succeeds.
947
  llvh::Optional<std::tuple<std::string, uint32_t, uint32_t>>
948
  getIPSourceLocation(const CodeBlock *codeBlock, const Inst *ip);
949
950
  /// Inserts the Hidden class as a root to prevent it from being garbage
951
  /// collected.
952
  void preventHCGC(HiddenClass *hc);
953
954
  /// Inserts Hidden Classes into InlineCacheProfiler
955
  void recordHiddenClass(
956
      CodeBlock *codeBlock,
957
      const Inst *cacheMissInst,
958
      SymbolID symbolID,
959
      HiddenClass *objectHiddenClass,
960
      HiddenClass *cachedHiddenClass);
961
962
  /// Resolve HiddenClass pointers from its hidden class Id.
963
  HiddenClass *resolveHiddenClassId(ClassId classId);
964
965
  /// Dumps inline cache profiler info.
966
  void getInlineCacheProfilerInfo(llvh::raw_ostream &ostream);
967
#endif
968
969
 private:
970
  /// Only called internally or by the wrappers used for profiling.
971
  CallResult<HermesValue> interpretFunctionImpl(CodeBlock *newCodeBlock);
972
973
 private:
974
  explicit Runtime(
975
      std::shared_ptr<StorageProvider> provider,
976
      const RuntimeConfig &runtimeConfig);
977
978
  /// Called by the GC at the beginning of a collection. This method informs the
979
  /// GC of all runtime roots.  The \p markLongLived argument
980
  /// indicates whether root data structures that contain only
981
  /// references to long-lived objects (allocated directly as long lived)
982
  /// are required to be scanned.
983
  void markRoots(RootAndSlotAcceptorWithNames &acceptor, bool markLongLived)
984
      override;
985
986
  /// Called by the GC during collections that may reset weak references. This
987
  /// method informs the GC of all runtime weak roots.
988
  void markWeakRoots(WeakRootAcceptor &weakAcceptor, bool markLongLived)
989
      override;
990
991
  /// See documentation on \c GCBase::GCCallbacks.
992
  void markRootsForCompleteMarking(
993
      RootAndSlotAcceptorWithNames &acceptor) override;
994
995
  /// Visits every entry in the identifier table and calls acceptor with
996
  /// the entry and its id as arguments. This is intended to be used only for
997
  /// snapshots, as it is slow. The function passed as acceptor shouldn't
998
  /// perform any heap operations.
999
  void visitIdentifiers(
1000
      const std::function<void(SymbolID, const StringPrimitive *)> &acceptor)
1001
      override;
1002
1003
#ifdef HERMESVM_PROFILER_BB
1004
 public:
1005
#endif
1006
  /// Convert the given symbol into its UTF-8 string representation.
1007
  std::string convertSymbolToUTF8(SymbolID id) override;
1008
1009
  /// Prints any statistics maintained in the Runtime about GC to \p
1010
  /// os.  At present, this means the breakdown of markRoots time by
1011
  /// "phase" within markRoots.
1012
  void printRuntimeGCStats(JSONEmitter &json) const override;
1013
1014
  /// \return one higher than the largest symbol in the identifier table. This
1015
  /// enables the GC to size its internal structures for symbol marking.
1016
  /// Optionally invoked at the beginning of a garbage collection.
1017
  virtual unsigned getSymbolsEnd() const override;
1018
1019
  /// If any symbols are marked by the IdentifierTable, clear that marking.
1020
  /// Optionally invoked at the beginning of some collections.
1021
  virtual void unmarkSymbols() override;
1022
1023
  /// Called by the GC at the end of a collection to free all symbols not set in
1024
  /// markedSymbols.
1025
  virtual void freeSymbols(const llvh::BitVector &markedSymbols) override;
1026
1027
#ifdef HERMES_SLOW_DEBUG
1028
  /// \return true if the given symbol is a live entry in the identifier
1029
  /// table.
1030
  virtual bool isSymbolLive(SymbolID id) override;
1031
1032
  /// \return An associated heap cell for the symbol if one exists, null
1033
  /// otherwise.
1034
  virtual const void *getStringForSymbol(SymbolID id) override;
1035
#endif
1036
1037
  /// See \c GCCallbacks for details.
1038
  size_t mallocSize() const override;
1039
1040
  /// Generate a bytecode buffer that contains a few special functions:
1041
  /// 0) an empty function that returns undefined.
1042
  /// 1) a function that returns the global object.
1043
  static std::unique_ptr<Buffer> generateSpecialRuntimeBytecode();
1044
1045
  /// Insert the predefined strings into the IdentifierTable.
1046
  /// NOTE: this function does not do any allocations in the GC heap, it is safe
1047
  /// to use at any time in initialization.
1048
  void initPredefinedStrings();
1049
1050
  /// Initialize the \c charStrings_ array with a StringPrimitive for each
1051
  /// character.
1052
  void initCharacterStrings();
1053
1054
  /// \param methodIndex is the index of the method in the table that lists
1055
  ///   all the builtin methods, which is what we are iterating over.
1056
  /// \param objectName is the id for the name of the object in the list of the
1057
  ///   predefined strings.
1058
  /// \param object is the object where the builtin method is defined as a
1059
  ///   property.
1060
  /// \param methodID is the SymbolID for the name of the method.
1061
  using ForEachPublicNativeBuiltinCallback = ExecutionStatus(
1062
      unsigned methodIndex,
1063
      Predefined::Str objectName,
1064
      Handle<JSObject> &object,
1065
      SymbolID methodID);
1066
1067
  /// Enumerate all public native builtin methods, and invoke the callback on
1068
  /// each method.
1069
  ExecutionStatus forEachPublicNativeBuiltin(
1070
      const std::function<ForEachPublicNativeBuiltinCallback> &callback);
1071
1072
  /// Populate native builtins into the builtins table.
1073
  /// Public native builtins are added by extracting the values from the global
1074
  /// object. Private native builtins are added by \c createHermesBuiltins().
1075
  void initNativeBuiltins();
1076
1077
  /// Populate JS builtins into the builtins table, after verifying they do
1078
  /// exist from the result of running internal bytecode.
1079
  void initJSBuiltins(
1080
      llvh::MutableArrayRef<Callable *> builtins,
1081
      Handle<JSObject> jsBuiltins);
1082
1083
  /// Walk all the builtin methods, assert that they are not overridden. If they
1084
  /// are, throw an exception. This will be called at most once, before freezing
1085
  /// the builtins.
1086
  ExecutionStatus assertBuiltinsUnmodified();
1087
1088
  /// Called after asserting all builtin methods are not overridden, to freeze
1089
  /// those builtins. This will be called at most once.
1090
  void freezeBuiltins();
1091
1092
  /// The slow path for \c getCharacterString(). This function allocates a new
1093
  /// string for the passed character \p ch.
1094
  Handle<StringPrimitive> allocateCharacterString(char16_t ch);
1095
1096
  /// Add a \c RuntimeModule \p rm to the runtime module list.
1097
928
  void addRuntimeModule(RuntimeModule *rm) {
1098
928
    runtimeModuleList_.push_back(*rm);
1099
928
  }
1100
1101
  /// Remove a \c RuntimeModule \p rm from the runtime module list.
1102
  void removeRuntimeModule(RuntimeModule *rm);
1103
1104
  /// Called by CrashManager on the event of a crash to produce a stream of data
1105
  /// to crash log. Output should be a JSON object. This is the central point
1106
  /// for adding calls to further functions which dump specific elements of
1107
  /// of crash dump data for a Hermes Runtime instance.
1108
  void crashCallback(int fd);
1109
1110
  /// Write a JS stack trace as part of a \c crashCallback() run.
1111
  void crashWriteCallStack(JSONEmitter &json);
1112
1113
 private:
1114
  GCStorage heapStorage_;
1115
1116
  std::vector<std::function<void(GC *, RootAcceptor &)>> customMarkRootFuncs_;
1117
  std::vector<std::function<void(GC *, WeakRootAcceptor &)>>
1118
      customMarkWeakRootFuncs_;
1119
  std::vector<std::function<void(HeapSnapshot &)>> customSnapshotNodeFuncs_;
1120
  std::vector<std::function<void(HeapSnapshot &)>> customSnapshotEdgeFuncs_;
1121
1122
  /// Set to true if we should enable ES6 Promise.
1123
  const bool hasES6Promise_;
1124
1125
  /// Set to true if we should enable ES6 Proxy.
1126
  const bool hasES6Proxy_;
1127
1128
  /// Set to true if we should enable ECMA-402 Intl APIs.
1129
  const bool hasIntl_;
1130
1131
  /// Set to true if we should enable ArrayBuffer, DataView and typed arrays.
1132
  const bool hasArrayBuffer_;
1133
1134
  /// Set to true if we are using microtasks.
1135
  const bool hasMicrotaskQueue_;
1136
1137
  /// Set to true if we should randomize stack placement etc.
1138
  const bool shouldRandomizeMemoryLayout_;
1139
1140
  // Percentage in [0,100] of bytecode we should eagerly read into page cache.
1141
  const uint8_t bytecodeWarmupPercent_;
1142
1143
  // Signal-based I/O tracking. Slows down execution.
1144
  const bool trackIO_;
1145
1146
  // Whether we are currently formatting a stack trace. Used to break recursion
1147
  // in Error.prepareStackTrace.
1148
  bool formattingStackTrace_{false};
1149
1150
  /// This value can be passed to the runtime as flags to test experimental
1151
  /// features. Each experimental feature decides how to interpret these
1152
  /// values. Generally each experiment is associated with one or more bits of
1153
  /// this value. Interpretation of these bits is up to each experiment.
1154
  /// To add an experiment, populate the VMExperimentFlags enum with additional
1155
  /// bit values, typically 1 as test and 0 as control.
1156
  experiments::VMExperimentFlags vmExperimentFlags_{experiments::Default};
1157
1158
  friend class GCScope;
1159
  friend class HandleBase;
1160
  friend class Interpreter;
1161
  friend class RuntimeModule;
1162
  friend class MarkRootsPhaseTimer;
1163
  friend struct RuntimeOffsets;
1164
  friend class ScopedNativeDepthReducer;
1165
  friend class ScopedNativeDepthTracker;
1166
  friend class ScopedNativeCallFrame;
1167
1168
  class StackRuntime;
1169
  class MarkRootsPhaseTimer;
1170
1171
  /// Whenever we pass through the first phase, we record the current time here,
1172
  /// so we can calculate the total time after we pass through the last phase.
1173
  std::chrono::time_point<std::chrono::steady_clock> startOfMarkRoots_;
1174
  /// The duration of each GC root marking phase is accumulated here.
1175
  double markRootsPhaseTimes_[static_cast<unsigned>(
1176
      RootAcceptor::Section::NumSections)] = {};
1177
  /// The duration of the all root makring is accumulated here.
1178
  double totalMarkRootsTime_ = 0.0;
1179
1180
  /// A global counter that increments and provide unique object IDs.
1181
  ObjectID nextObjectID_{0};
1182
1183
  /// The identifier table.
1184
  IdentifierTable identifierTable_{};
1185
1186
  /// The global symbol registry.
1187
  SymbolRegistry symbolRegistry_{};
1188
1189
  /// Shared location to place native objects required by JSLib
1190
  std::shared_ptr<RuntimeCommonStorage> commonStorage_;
1191
1192
  /// Empty code block that returns undefined.
1193
  /// Owned by specialCodeBlockRuntimeModule_.
1194
  CodeBlock *emptyCodeBlock_{};
1195
1196
  /// Code block that returns the global object.
1197
  /// Owned by specialCodeBlockRuntimeModule_.
1198
  CodeBlock *returnThisCodeBlock_{};
1199
1200
  /// The runtime module that owns emptyCodeBlock_ and returnThisCodeBlock_.
1201
  /// We use a raw pointer here because it will be added to runtimeModuleList_,
1202
  /// and will be freed when Runtime is freed.
1203
  RuntimeModule *specialCodeBlockRuntimeModule_{};
1204
1205
  /// A list of all active runtime modules. Each \c RuntimeModule adds itself
1206
  /// on construction and removes itself on destruction.
1207
  RuntimeModuleList runtimeModuleList_{};
1208
1209
  /// Optional record of the last few executed bytecodes in case of a crash.
1210
  CrashTrace crashTrace_{};
1211
1212
  /// @name Private VM State
1213
  /// @{
1214
1215
  /// If the register stack is allocated by the runtime, then this stores its
1216
  /// location and size.
1217
  llvh::MutableArrayRef<PinnedHermesValue> registerStackAllocation_;
1218
  PinnedHermesValue *registerStackStart_;
1219
  PinnedHermesValue *registerStackEnd_;
1220
  PinnedHermesValue *stackPointer_;
1221
  /// Manages data to be used in the case of a crash.
1222
  std::shared_ptr<CrashManager> crashMgr_;
1223
  /// Points to the last register in the callers frame. The current frame (the
1224
  /// callee frame) starts in the next register and continues up to and
1225
  /// including \c stackPointer_.
1226
  StackFramePtr currentFrame_{nullptr};
1227
1228
  /// Current depth of native call frames, including recursive interpreter
1229
  /// calls.
1230
  unsigned nativeCallFrameDepth_{0};
1231
1232
  /// rootClazzes_[i] is a PinnedHermesValue pointing to a hidden class with
1233
  /// its i first slots pre-reserved.
1234
  std::array<
1235
      PinnedHermesValue,
1236
      InternalProperty::NumAnonymousInternalProperties + 1>
1237
      rootClazzes_;
1238
1239
  /// Cache for property lookups in non-JS code.
1240
  PropertyCacheEntry fixedPropCache_[(size_t)PropCacheID::_COUNT];
1241
1242
  /// StringPrimitive representation of the first 256 characters.
1243
  /// These are allocated as "long-lived" objects, so they don't need
1244
  /// to be scanned as roots in young-gen collections.
1245
  std::vector<PinnedHermesValue> charStrings_{};
1246
1247
  /// Keeps track of objects that have already been visited in order to detect
1248
  /// cycles while doing string conversions.
1249
  std::vector<JSObject *> stringCycleCheckVisited_{};
1250
1251
  /// Pointers to callable implementations of builtins.
1252
  std::vector<Callable *> builtins_{};
1253
1254
  /// True if the builtins are all frozen (non-writable, non-configurable).
1255
  bool builtinsFrozen_{false};
1256
1257
  /// ES6-ES11 8.4 Jobs and Job Queues.
1258
  /// A queue of pointers to callables that represent Jobs.
1259
  ///
1260
  /// Job: Since the ScriptJob is removed from ES12, the only type of Job from
1261
  /// ECMA-262 are Promise Jobs (https://tc39.es/ecma262/#sec-promise-jobs).
1262
  /// But it is also possible to implement the HTML defined `queueMicrotask`,
1263
  /// which is polyfill-able via Promise, by directly enqueuing into this job.
1264
  ///
1265
  /// Job are represented as callables with no parameters and would be invoked
1266
  /// via \c executeCall0 in Hermes. It's safe to do so because:
1267
  /// - Promise Jobs enqueued from Promise internal bytecode are thunks (or, in
1268
  /// the ES12 wording, Promise Jobs are Abstract Closure with no parameters).
1269
  /// - `queueMicrotask` take a JSFunction but only invoke it with 0 arguments.
1270
  ///
1271
  /// Although ES12 (9.4 Jobs and Host Operations to Enqueue Jobs) changed the
1272
  /// meta-language to ask hosts to schedule Promise Job to integrate with the
1273
  /// HTML spec, Hermes chose to adapt the ES6-11 suggested internal queue
1274
  /// approach, similar to other engines, e.g. V8/JSC, which is more efficient
1275
  /// (being able to batch the job invocations) and sufficient to express the
1276
  /// HTML spec specified "perform a microtask checkpoint" algorithm.
1277
  std::deque<Callable *> jobQueue_{};
1278
1279
#ifdef HERMESVM_PROFILER_BB
1280
  BasicBlockExecutionInfo basicBlockExecInfo_;
1281
1282
  /// Store all inline caching miss information.
1283
  InlineCacheProfiler inlineCacheProfiler_;
1284
#endif
1285
1286
  /// ScriptIDs to use for new RuntimeModules coming in.
1287
  facebook::hermes::debugger::ScriptID nextScriptId_{1};
1288
1289
  /// Store a key for the function that is executed if a crash occurs.
1290
  /// This key will be unregistered in the destructor.
1291
  const CrashManager::CallbackKey crashCallbackKey_;
1292
1293
  /// Pointer to the code coverage profiler.
1294
  const std::unique_ptr<CodeCoverageProfiler> codeCoverageProfiler_;
1295
1296
  /// Bit flags for async break request reasons.
1297
  enum class AsyncBreakReasonBits : uint8_t {
1298
    DebuggerExplicit = 0x1,
1299
    DebuggerImplicit = 0x2,
1300
    Timeout = 0x4,
1301
  };
1302
1303
  /// An atomic flag set when an async pause is requested.
1304
  /// It is a bits flag with each bit reserved for different clients
1305
  /// defined by AsyncBreakReasonBits.
1306
  /// This may be manipulated from multiple threads.
1307
  std::atomic<uint8_t> asyncBreakRequestFlag_{0};
1308
1309
#if defined(HERMES_ENABLE_DEBUGGER)
1310
  /// \return zero if no debugger async pause was requested, the old nonzero
1311
  /// async flags if an async pause was requested. If nonzero is returned, the
1312
  /// flag is reset to 0.
1313
3.88k
  uint8_t testAndClearDebuggerAsyncBreakRequest() {
1314
3.88k
    return testAndClearAsyncBreakRequest(
1315
3.88k
        (uint8_t)AsyncBreakReasonBits::DebuggerExplicit |
1316
3.88k
        (uint8_t)AsyncBreakReasonBits::DebuggerImplicit);
1317
3.88k
  }
1318
1319
  Debugger debugger_{*this};
1320
#endif
1321
1322
  /// Holds references to persistent BC providers for the lifetime of the
1323
  /// Runtime. This is needed because the identifier table may contain pointers
1324
  /// into bytecode, and so memory backing these must be preserved.
1325
  std::vector<std::shared_ptr<hbc::BCProvider>> persistentBCProviders_;
1326
1327
  /// Config-provided callback for GC events.
1328
  std::function<void(GCEventKind, const char *)> gcEventCallback_;
1329
1330
  /// @}
1331
1332
  /// \return whether any async break is requested or not.
1333
33
  bool hasAsyncBreak() const {
1334
33
    return asyncBreakRequestFlag_.load(std::memory_order_relaxed) != 0;
1335
33
  }
1336
1337
  /// \return whether async break was requested or not for \p reasonBits. Clear
1338
  /// \p reasonBit request bit afterward.
1339
3.88k
  uint8_t testAndClearAsyncBreakRequest(uint8_t reasonBits) {
1340
    /// Note that while the triggerTimeoutAsyncBreak() function may be called
1341
    /// from any thread, this one may only be called from within the Interpreter
1342
    /// loop.
1343
3.88k
    uint8_t flag = asyncBreakRequestFlag_.load(std::memory_order_relaxed);
1344
3.88k
    if (LLVM_LIKELY((flag & (uint8_t)reasonBits) == 0)) {
1345
      // Fast path.
1346
3.88k
      return false;
1347
3.88k
    }
1348
    // Clear the flag using CAS.
1349
0
    uint8_t oldFlag = asyncBreakRequestFlag_.fetch_and(
1350
0
        ~(uint8_t)reasonBits, std::memory_order_relaxed);
1351
0
    assert(oldFlag != 0 && "Why is oldFlag zero?");
1352
0
    return oldFlag;
1353
3.88k
  }
1354
1355
  /// \return whether timeout async break was requested or not. Clear the
1356
  /// timeout request bit afterward.
1357
0
  bool testAndClearTimeoutAsyncBreakRequest() {
1358
0
    return testAndClearAsyncBreakRequest(
1359
0
        (uint8_t)AsyncBreakReasonBits::Timeout);
1360
0
  }
1361
1362
  /// Request the interpreter loop to take an asynchronous break
1363
  /// at a convenient point.
1364
0
  void triggerAsyncBreak(AsyncBreakReasonBits reason) {
1365
0
    asyncBreakRequestFlag_.fetch_or((uint8_t)reason, std::memory_order_relaxed);
1366
0
  }
1367
1368
  /// Notify runtime execution has timeout.
1369
  ExecutionStatus notifyTimeout();
1370
1371
 private:
1372
#ifdef NDEBUG
1373
  /// See \c ::setCurrentIP() and \c ::getCurrentIP() .
1374
  const inst::Inst *currentIP_{nullptr};
1375
#else
1376
  /// When assertions are enabled we track whether \c currentIP_ is "valid" by
1377
  /// making it optional. If this is accessed when the optional value is cleared
1378
  /// (the invalid state) we assert.
1379
  llvh::Optional<const inst::Inst *> currentIP_{(const inst::Inst *)nullptr};
1380
#endif
1381
1382
 public:
1383
  /// Set the value of the current Instruction Pointer (IP). Generally this is
1384
  /// called by the interpeter before it makes any major calls out of its main
1385
  /// loop. However, the interpeter also reads the value held here back after
1386
  /// major calls return so this can also be called by other code which wants to
1387
  /// return to the interpreter at a different IP. This allows things external
1388
  /// to the interpreter loop to affect the flow of bytecode execution.
1389
289k
  inline void setCurrentIP(const inst::Inst *ip) {
1390
289k
    currentIP_ = ip;
1391
289k
  }
1392
1393
  /// Get the current Instruction Pointer (IP). This can be used to find out
1394
  /// the last bytecode executed if we're currently in the interpeter loop. If
1395
  /// we are not in the interpeter loop (i.e. we've made it into the VM
1396
  /// internals via a native call), this this will return nullptr.
1397
5.28M
  inline const inst::Inst *getCurrentIP() const {
1398
#ifdef NDEBUG
1399
    return currentIP_;
1400
#else
1401
5.28M
    assert(
1402
5.28M
        currentIP_.hasValue() &&
1403
5.28M
        "Current IP unknown - this probably means a CAPTURE_IP_* is missing in the interpreter.");
1404
0
    return *currentIP_;
1405
5.28M
#endif
1406
5.28M
  }
1407
1408
  /// This is slow compared to \c getCurrentIP() as it's virtual.
1409
2.29M
  inline const inst::Inst *getCurrentIPSlow() const override {
1410
2.29M
    return getCurrentIP();
1411
2.29M
  }
1412
1413
#ifdef NDEBUG
1414
  void invalidateCurrentIP() {}
1415
#else
1416
289k
  void invalidateCurrentIP() {
1417
289k
    currentIP_.reset();
1418
289k
  }
1419
#endif
1420
1421
  /// Save the return address in the caller in the stack frame.
1422
  /// This needs to be called at the beginning of a function call, after the
1423
  /// stack frame is set up.
1424
409k
  void saveCallerIPInStackFrame() {
1425
409k
#ifndef NDEBUG
1426
409k
    assert(
1427
409k
        (!currentFrame_.getSavedIP() ||
1428
409k
         (currentIP_.hasValue() && currentFrame_.getSavedIP() == currentIP_)) &&
1429
409k
        "The ip should either be null or already have the expected value");
1430
0
#endif
1431
0
    currentFrame_.getSavedIPRef() =
1432
409k
        HermesValue::encodeNativePointer(getCurrentIP());
1433
409k
  }
1434
1435
 private:
1436
#ifdef HERMES_MEMORY_INSTRUMENTATION
1437
  /// Given the current last known IP used in the interpreter loop, returns the
1438
  /// last known CodeBlock and IP combination. IP must not be null as this
1439
  /// suggests we're not in the interpter loop, and there will be no CodeBlock
1440
  /// to find.
1441
  std::pair<const CodeBlock *, const inst::Inst *>
1442
  getCurrentInterpreterLocation(const inst::Inst *initialSearchIP);
1443
1444
 public:
1445
  /// Return a StackTraceTreeNode for the last known interpreter bytecode
1446
  /// location. Returns nullptr if we're not in the interpeter loop, or
1447
  /// allocation location tracking is not enabled. For this to function it
1448
  /// needs to be passed the current IP from getCurrentIP(). We do not call
1449
  /// this internally because it should always be called prior even if we
1450
  /// do not really want a stack-traces node. This means we can leverage our
1451
  /// library of tests to assert getCurrentIP() would return the right value
1452
  /// at this point without actually collecting stack-trace data.
1453
  StackTracesTreeNode *getCurrentStackTracesTreeNode(
1454
      const inst::Inst *ip) override;
1455
1456
  /// Return the current StackTracesTree or nullptr if it's not available.
1457
0
  StackTracesTree *getStackTracesTree() override {
1458
0
    return stackTracesTree_.get();
1459
0
  }
1460
1461
  /// To facilitate allocation location tracking this must be called by the
1462
  /// interpeter:
1463
  /// * Just before we enter a new CodeBlock
1464
  /// * At the entry point of a CodeBlock if this is the first entry into the
1465
  ///   interpter loop.
1466
1.64k
  inline void pushCallStack(const CodeBlock *codeBlock, const inst::Inst *ip) {
1467
1.64k
    if (stackTracesTree_) {
1468
0
      pushCallStackImpl(codeBlock, ip);
1469
0
    }
1470
1.64k
  }
1471
1472
  /// Must pair up with every call to \c pushCallStack .
1473
1.64k
  inline void popCallStack() {
1474
1.64k
    if (stackTracesTree_) {
1475
0
      popCallStackImpl();
1476
0
    }
1477
1.64k
  }
1478
1479
0
  void enableAllocationLocationTracker() {
1480
0
    enableAllocationLocationTracker(nullptr);
1481
0
  }
1482
  void enableAllocationLocationTracker(
1483
      std::function<void(
1484
          uint64_t,
1485
          std::chrono::microseconds,
1486
          std::vector<GCBase::AllocationLocationTracker::HeapStatsUpdate>)>
1487
          fragmentCallback);
1488
1489
  /// Disable allocation location tracking for new objects. Old objects tagged
1490
  /// with stack traces continue to be tracked until they are freed.
1491
  /// \param clearExistingTree is for use by tests and in general will break
1492
  /// because old objects would end up with dead pointers to stack-trace nodes.
1493
  void disableAllocationLocationTracker(bool clearExistingTree = false);
1494
1495
  /// Enable the heap sampling profiler. About every \p samplingInterval bytes
1496
  /// allocated, the stack will be sampled. This will attribute the highest
1497
  /// allocating functions.
1498
  /// \param samplingInterval A number of bytes that a sample should be taken,
1499
  ///   on average.
1500
  /// \param seed If non-negative, used as the seed for the random engine.
1501
  void enableSamplingHeapProfiler(size_t samplingInterval, int64_t seed = -1);
1502
1503
  /// Disable the heap sampling profiler and flush the results out to \p os.
1504
  void disableSamplingHeapProfiler(llvh::raw_ostream &os);
1505
1506
 private:
1507
  void popCallStackImpl();
1508
  void pushCallStackImpl(const CodeBlock *codeBlock, const inst::Inst *ip);
1509
  std::unique_ptr<StackTracesTree> stackTracesTree_;
1510
#endif
1511
};
1512
1513
/// An encrypted/obfuscated native pointer. The key is held by GCBase.
1514
template <typename T, XorPtrKeyID K>
1515
class XorPtr {
1516
  uintptr_t bits_;
1517
1518
 public:
1519
  XorPtr() = default;
1520
4.50k
  XorPtr(Runtime &runtime, T *ptr) {
1521
4.50k
    set(runtime, ptr);
1522
4.50k
  }
1523
4.50k
  void set(Runtime &runtime, T *ptr) {
1524
4.50k
    set(runtime.getHeap(), ptr);
1525
4.50k
  }
hermes::vm::XorPtr<hermes::vm::CodeBlock, (hermes::vm::XorPtrKeyID)1>::set(hermes::vm::Runtime&, hermes::vm::CodeBlock*)
Line
Count
Source
1523
4.50k
  void set(Runtime &runtime, T *ptr) {
1524
4.50k
    set(runtime.getHeap(), ptr);
1525
4.50k
  }
Unexecuted instantiation: hermes::vm::XorPtr<unsigned char, (hermes::vm::XorPtrKeyID)0>::set(hermes::vm::Runtime&, unsigned char*)
1526
4.50k
  void set(GC &gc, T *ptr) {
1527
4.50k
    bits_ = reinterpret_cast<uintptr_t>(ptr) ^ gc.pointerEncryptionKey_[K];
1528
4.50k
  }
hermes::vm::XorPtr<hermes::vm::CodeBlock, (hermes::vm::XorPtrKeyID)1>::set(hermes::vm::HadesGC&, hermes::vm::CodeBlock*)
Line
Count
Source
1526
4.50k
  void set(GC &gc, T *ptr) {
1527
4.50k
    bits_ = reinterpret_cast<uintptr_t>(ptr) ^ gc.pointerEncryptionKey_[K];
1528
4.50k
  }
Unexecuted instantiation: hermes::vm::XorPtr<unsigned char, (hermes::vm::XorPtrKeyID)0>::set(hermes::vm::HadesGC&, unsigned char*)
1529
1.73k
  T *get(Runtime &runtime) const {
1530
1.73k
    return get(runtime.getHeap());
1531
1.73k
  }
Unexecuted instantiation: hermes::vm::XorPtr<unsigned char, (hermes::vm::XorPtrKeyID)0>::get(hermes::vm::Runtime&) const
hermes::vm::XorPtr<hermes::vm::CodeBlock, (hermes::vm::XorPtrKeyID)1>::get(hermes::vm::Runtime&) const
Line
Count
Source
1529
1.73k
  T *get(Runtime &runtime) const {
1530
1.73k
    return get(runtime.getHeap());
1531
1.73k
  }
1532
1.73k
  T *get(GC &gc) const {
1533
1.73k
    return reinterpret_cast<T *>(bits_ ^ gc.pointerEncryptionKey_[K]);
1534
1.73k
  }
Unexecuted instantiation: hermes::vm::XorPtr<unsigned char, (hermes::vm::XorPtrKeyID)0>::get(hermes::vm::HadesGC&) const
hermes::vm::XorPtr<hermes::vm::CodeBlock, (hermes::vm::XorPtrKeyID)1>::get(hermes::vm::HadesGC&) const
Line
Count
Source
1532
1.73k
  T *get(GC &gc) const {
1533
1.73k
    return reinterpret_cast<T *>(bits_ ^ gc.pointerEncryptionKey_[K]);
1534
1.73k
  }
1535
};
1536
1537
static_assert(
1538
    std::is_trivial<XorPtr<void, XorPtrKeyID::_NumKeys>>::value,
1539
    "XorPtr must be trivial");
1540
1541
/// An RAII class for automatically tracking the native call frame depth.
1542
class ScopedNativeDepthTracker {
1543
  Runtime &runtime_;
1544
1545
 public:
1546
408k
  explicit ScopedNativeDepthTracker(Runtime &runtime) : runtime_(runtime) {
1547
408k
    ++runtime.nativeCallFrameDepth_;
1548
408k
  }
1549
408k
  ~ScopedNativeDepthTracker() {
1550
408k
    --runtime_.nativeCallFrameDepth_;
1551
408k
  }
1552
1553
  /// \return whether we overflowed the native call frame depth.
1554
408k
  bool overflowed() const {
1555
408k
    return runtime_.nativeCallFrameDepth_ >
1556
408k
        Runtime::MAX_NATIVE_CALL_FRAME_DEPTH;
1557
408k
  }
1558
};
1559
1560
/// An RAII class which creates a little headroom in the native depth
1561
/// tracking.  This is used when calling into JSError to extract the
1562
/// stack, as the error may represent an overflow.  Without this, a
1563
/// cascade of exceptions could occur, overflowing the C++ stack.
1564
class ScopedNativeDepthReducer {
1565
  Runtime &runtime_;
1566
  bool undo = false;
1567
  // This is empirically good enough.
1568
  static constexpr int kDepthAdjustment = 3;
1569
1570
 public:
1571
24
  explicit ScopedNativeDepthReducer(Runtime &runtime) : runtime_(runtime) {
1572
24
    if (runtime.nativeCallFrameDepth_ >= kDepthAdjustment) {
1573
24
      runtime.nativeCallFrameDepth_ -= kDepthAdjustment;
1574
24
      undo = true;
1575
24
    }
1576
24
  }
1577
24
  ~ScopedNativeDepthReducer() {
1578
24
    if (undo) {
1579
24
      runtime_.nativeCallFrameDepth_ += kDepthAdjustment;
1580
24
    }
1581
24
  }
1582
};
1583
1584
/// A ScopedNativeCallFrame is an RAII class that manipulates the Runtime
1585
/// stack and depth counter, and holds a stack frame. The stack frame contents
1586
/// may be accessed (as StackFramePtr) via ->. Note that constructing this may
1587
/// fail due to stack overflow, either via the register stack or the depth
1588
/// counter. It is necessary to check the overflowed() flag before access the
1589
/// stack frame contents.
1590
/// Note that the arguments to the call frame are left uninitialized. The caller
1591
/// must clear these before triggering a GC. The fillArgs() function may be used
1592
/// for this purpose.
1593
class ScopedNativeCallFrame {
1594
  /// The runtime for this call frame.
1595
  Runtime &runtime_;
1596
1597
  /// The stack pointer that will be restored in the destructor.
1598
  PinnedHermesValue *const savedSP_;
1599
1600
  /// The contents of the new frame.
1601
  StackFramePtr frame_;
1602
1603
  /// Whether this call frame overflowed.
1604
  bool overflowed_;
1605
1606
#ifndef NDEBUG
1607
  /// Whether the user has called overflowed() with a false result.
1608
  mutable bool overflowHasBeenChecked_{false};
1609
#endif
1610
1611
  /// \return whether the runtime can allocate a new frame with the given number
1612
  /// of registers. This may fail if we've overflowed our register stack, or
1613
  /// exceeded the native call frame depth.
1614
  static bool runtimeCanAllocateFrame(
1615
      Runtime &runtime,
1616
407k
      uint32_t registersNeeded) {
1617
407k
    return runtime.checkAvailableStack(registersNeeded) &&
1618
407k
        runtime.nativeCallFrameDepth_ <= Runtime::MAX_NATIVE_CALL_FRAME_DEPTH;
1619
407k
  }
1620
1621
 public:
1622
  /// Construct a native call frame for the given \p runtime in preparation of
1623
  /// calling \p callee with \p argCount arguments and the given \p thisArg.
1624
  /// \p callee is either a native pointer to CodeBlock, or an object pointer to
1625
  /// a Callable (the two cases are distinguished by the type tag).
1626
  /// \p newTarget is either \c undefined or the callable of the constructor
1627
  /// currently being invoked by new.
1628
  /// On overflow, the overflowed() flag is set, in which case the stack frame
1629
  /// must not be used.
1630
  /// The arguments are initially uninitialized. The caller should initialize
1631
  /// them by storing into them, or via fillArguments().
1632
  ScopedNativeCallFrame(
1633
      Runtime &runtime,
1634
      uint32_t argCount,
1635
      HermesValue callee,
1636
      HermesValue newTarget,
1637
      HermesValue thisArg)
1638
407k
      : runtime_(runtime), savedSP_(runtime.getStackPointer()) {
1639
407k
    runtime.nativeCallFrameDepth_++;
1640
407k
    uint32_t registersNeeded =
1641
407k
        StackFrameLayout::callerOutgoingRegisters(argCount);
1642
407k
    overflowed_ = !runtimeCanAllocateFrame(runtime, registersNeeded);
1643
407k
    if (LLVM_UNLIKELY(overflowed_)) {
1644
0
      return;
1645
0
    }
1646
1647
    // We have enough space. Increment the call frame depth and construct the
1648
    // frame. The ScopedNativeCallFrame will restore both.
1649
407k
    auto *stack = runtime.allocUninitializedStack(registersNeeded);
1650
407k
    frame_ = StackFramePtr::initFrame(
1651
407k
        stack,
1652
407k
        runtime.currentFrame_,
1653
407k
        nullptr,
1654
407k
        nullptr,
1655
407k
        argCount,
1656
407k
        callee,
1657
407k
        newTarget);
1658
407k
    frame_.getThisArgRef() = thisArg;
1659
407k
#if HERMES_SLOW_DEBUG
1660
    // Poison the initial arguments to ensure the caller sets all of them before
1661
    // a GC.
1662
407k
    assert(!overflowed_ && "Overflow should return early");
1663
0
    overflowHasBeenChecked_ = true;
1664
407k
    fillArguments(argCount, HermesValue::encodeInvalidValue());
1665
    // We still want the user to check for overflow.
1666
407k
    overflowHasBeenChecked_ = false;
1667
407k
#endif
1668
407k
  }
1669
1670
  /// Construct a native call frame for the given \p runtime in preparation of
1671
  /// calling \p callee with \p argCount arguments and the given \p thisArg. On
1672
  /// overflow, the overflowed() flag is set, in which case the stack frame must
1673
  /// not be used.
1674
  /// The arguments are initially uninitialized. The caller should initialize
1675
  /// them by storing into them, or via fillArguments().
1676
  ScopedNativeCallFrame(
1677
      Runtime &runtime,
1678
      uint32_t argCount,
1679
      Callable *callee,
1680
      bool construct,
1681
      HermesValue thisArg)
1682
      : ScopedNativeCallFrame(
1683
            runtime,
1684
            argCount,
1685
            HermesValue::encodeObjectValue(callee),
1686
            construct ? HermesValue::encodeObjectValue(callee)
1687
                      : HermesValue::encodeUndefinedValue(),
1688
0
            thisArg) {}
1689
1690
407k
  ~ScopedNativeCallFrame() {
1691
    // Note that we unconditionally increment the native call frame depth and
1692
    // save the SP to avoid branching in the dtor.
1693
407k
    runtime_.nativeCallFrameDepth_--;
1694
407k
    runtime_.popToSavedStackPointer(savedSP_);
1695
407k
#ifndef NDEBUG
1696
    // Clear the frame to detect use-after-free.
1697
407k
    frame_ = StackFramePtr{};
1698
407k
#endif
1699
407k
  }
1700
1701
  /// Fill \p argCount arguments with the given value \p fillValue.
1702
407k
  void fillArguments(uint32_t argCount, HermesValue fillValue) {
1703
407k
    assert(overflowHasBeenChecked_ && "ScopedNativeCallFrame could overflow");
1704
0
    assert(argCount == frame_.getArgCount() && "Arg count mismatch.");
1705
0
    std::uninitialized_fill_n(frame_.argsBegin(), argCount, fillValue);
1706
407k
  }
1707
1708
  /// \return whether the stack frame overflowed.
1709
407k
  bool overflowed() const {
1710
407k
#ifndef NDEBUG
1711
407k
    overflowHasBeenChecked_ = !overflowed_;
1712
407k
#endif
1713
407k
    return overflowed_;
1714
407k
  }
1715
1716
  /// Access the stack frame contents via ->.
1717
404k
  StackFramePtr operator->() {
1718
404k
    assert(overflowHasBeenChecked_ && "ScopedNativeCallFrame could overflow");
1719
0
    return frame_;
1720
404k
  }
1721
};
1722
1723
#ifdef NDEBUG
1724
1725
/// NoAllocScope and NoHandleScope have no impact in release mode (except that
1726
/// if they are embedded into another struct/class, they will still use space!)
1727
class NoAllocScope {
1728
 public:
1729
  explicit NoAllocScope(Runtime &runtime) {}
1730
  explicit NoAllocScope(GC &gc) {}
1731
  NoAllocScope(const NoAllocScope &) = default;
1732
  NoAllocScope(NoAllocScope &&) = default;
1733
  NoAllocScope &operator=(const NoAllocScope &) = default;
1734
  NoAllocScope &operator=(NoAllocScope &&rhs) = default;
1735
  void release() {}
1736
1737
 private:
1738
  NoAllocScope() = delete;
1739
};
1740
using NoHandleScope = NoAllocScope;
1741
1742
#else
1743
1744
/// RAII class to temporarily disallow allocation of something.
1745
class BaseNoScope {
1746
 public:
1747
4.45M
  explicit BaseNoScope(uint32_t *level) : level_(level) {
1748
4.45M
    assert(level_ && "constructing BaseNoScope with moved/release object");
1749
0
    ++*level_;
1750
4.45M
  }
1751
1752
0
  BaseNoScope(const BaseNoScope &other) : BaseNoScope(other.level_) {}
1753
0
  BaseNoScope(BaseNoScope &&other) : level_(other.level_) {
1754
0
    // not a release operation as this inherits the counter from other.
1755
0
    other.level_ = nullptr;
1756
0
  }
1757
1758
4.45M
  ~BaseNoScope() {
1759
4.45M
    if (level_)
1760
4.45M
      release();
1761
4.45M
  }
1762
1763
0
  BaseNoScope &operator=(BaseNoScope &&rhs) {
1764
0
    if (level_) {
1765
0
      release();
1766
0
    }
1767
0
1768
0
    // N.B.: to account for cases when this == &rhs, first copy rhs.level_
1769
0
    // to a temporary, then null it out.
1770
0
    auto ptr = rhs.level_;
1771
0
    rhs.level_ = nullptr;
1772
0
    level_ = ptr;
1773
0
    return *this;
1774
0
  }
1775
1776
0
  BaseNoScope &operator=(const BaseNoScope &other) {
1777
0
    return *this = BaseNoScope(other.level_);
1778
0
  }
1779
1780
  /// End this scope early. May only be called once.
1781
4.45M
  void release() {
1782
4.45M
    assert(level_ && "already released");
1783
0
    assert(*level_ > 0 && "unbalanced no alloc");
1784
0
    --*level_;
1785
4.45M
    level_ = nullptr;
1786
4.45M
  }
1787
1788
 protected:
1789
  uint32_t *level_;
1790
1791
 private:
1792
  BaseNoScope() = delete;
1793
};
1794
1795
/// RAII class to temporarily disallow handle creation.
1796
class NoHandleScope : public BaseNoScope {
1797
 public:
1798
  explicit NoHandleScope(Runtime &runtime)
1799
0
      : BaseNoScope(&runtime.noHandleLevel_) {}
1800
  using BaseNoScope::BaseNoScope;
1801
  using BaseNoScope::operator=;
1802
};
1803
1804
/// RAII class to temporarily disallow allocating cells in the JS heap.
1805
class NoAllocScope : public BaseNoScope {
1806
 public:
1807
4.45M
  explicit NoAllocScope(Runtime &runtime) : NoAllocScope(runtime.getHeap()) {}
1808
4.45M
  explicit NoAllocScope(GC &gc) : BaseNoScope(&gc.noAllocLevel_) {}
1809
  using BaseNoScope::BaseNoScope;
1810
  using BaseNoScope::operator=;
1811
};
1812
#endif
1813
1814
//===----------------------------------------------------------------------===//
1815
// Runtime inline methods.
1816
1817
inline void Runtime::addCustomRootsFunction(
1818
99
    std::function<void(GC *, RootAcceptor &)> markRootsFn) {
1819
99
  customMarkRootFuncs_.emplace_back(std::move(markRootsFn));
1820
99
}
1821
1822
inline void Runtime::addCustomWeakRootsFunction(
1823
99
    std::function<void(GC *, WeakRootAcceptor &)> markRootsFn) {
1824
99
  customMarkWeakRootFuncs_.emplace_back(std::move(markRootsFn));
1825
99
}
1826
1827
inline void Runtime::addCustomSnapshotFunction(
1828
    std::function<void(HeapSnapshot &)> nodes,
1829
99
    std::function<void(HeapSnapshot &)> edges) {
1830
99
  customSnapshotNodeFuncs_.emplace_back(std::move(nodes));
1831
99
  customSnapshotEdgeFuncs_.emplace_back(std::move(edges));
1832
99
}
1833
1834
template <
1835
    typename T,
1836
    HasFinalizer hasFinalizer,
1837
    LongLived longLived,
1838
    class... Args>
1839
555k
T *Runtime::makeAFixed(Args &&...args) {
1840
555k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
555k
  (void)getCurrentIP();
1846
555k
#endif
1847
555k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
555k
      std::forward<Args>(args)...);
1849
555k
}
hermes::vm::BoxedDouble* hermes::vm::Runtime::makeAFixed<hermes::vm::BoxedDouble, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, double&>(double&)
Line
Count
Source
1839
1.79k
T *Runtime::makeAFixed(Args &&...args) {
1840
1.79k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
1.79k
  (void)getCurrentIP();
1846
1.79k
#endif
1847
1.79k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
1.79k
      std::forward<Args>(args)...);
1849
1.79k
}
hermes::vm::NativeConstructor* hermes::vm::Runtime::makeAFixed<hermes::vm::NativeConstructor, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> (*&)(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*), hermes::vm::CellKind&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> (*&)(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*), hermes::vm::CellKind&)
Line
Count
Source
1839
4.05k
T *Runtime::makeAFixed(Args &&...args) {
1840
4.05k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
4.05k
  (void)getCurrentIP();
1846
4.05k
#endif
1847
4.05k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
4.05k
      std::forward<Args>(args)...);
1849
4.05k
}
Unexecuted instantiation: hermes::vm::NativeConstructor* hermes::vm::Runtime::makeAFixed<hermes::vm::NativeConstructor, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> (*&)(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*), hermes::vm::CellKind&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> (*&)(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*), hermes::vm::CellKind&)
hermes::vm::BoundFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::BoundFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Callable>&, hermes::vm::MutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue> >&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Callable>&, hermes::vm::MutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue> >&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
hermes::vm::NativeFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::NativeFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs)>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs))
Line
Count
Source
1839
42.4k
T *Runtime::makeAFixed(Args &&...args) {
1840
42.4k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
42.4k
  (void)getCurrentIP();
1846
42.4k
#endif
1847
42.4k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
42.4k
      std::forward<Args>(args)...);
1849
42.4k
}
Unexecuted instantiation: hermes::vm::NativeFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::NativeFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs)>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs))
hermes::vm::JSFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::JSFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&)
Line
Count
Source
1839
4.50k
T *Runtime::makeAFixed(Args &&...args) {
1840
4.50k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
4.50k
  (void)getCurrentIP();
1846
4.50k
#endif
1847
4.50k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
4.50k
      std::forward<Args>(args)...);
1849
4.50k
}
Unexecuted instantiation: hermes::vm::JSAsyncFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::JSAsyncFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&)
Unexecuted instantiation: hermes::vm::JSGeneratorFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::JSGeneratorFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&)
Unexecuted instantiation: hermes::vm::GeneratorInnerFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::GeneratorInnerFunction, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&, unsigned int>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Domain>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::Environment>&, hermes::vm::CodeBlock*&, unsigned int&&)
hermes::vm::Domain* hermes::vm::Runtime::makeAFixed<hermes::vm::Domain, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0>()
Line
Count
Source
1839
254
T *Runtime::makeAFixed(Args &&...args) {
1840
254
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
254
  (void)getCurrentIP();
1846
254
#endif
1847
254
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
254
      std::forward<Args>(args)...);
1849
254
}
Unexecuted instantiation: hermes::vm::RequireContext* hermes::vm::Runtime::makeAFixed<hermes::vm::RequireContext, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
hermes::vm::HiddenClass* hermes::vm::Runtime::makeAFixed<hermes::vm::HiddenClass, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)1, hermes::vm::Runtime&, hermes::vm::ClassFlags&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::SymbolID&, hermes::vm::PropertyFlags&, unsigned int&>(hermes::vm::Runtime&, hermes::vm::ClassFlags&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::SymbolID&, hermes::vm::PropertyFlags&, unsigned int&)
Line
Count
Source
1839
56.9k
T *Runtime::makeAFixed(Args &&...args) {
1840
56.9k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
56.9k
  (void)getCurrentIP();
1846
56.9k
#endif
1847
56.9k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
56.9k
      std::forward<Args>(args)...);
1849
56.9k
}
Unexecuted instantiation: hermes::vm::Arguments* hermes::vm::Runtime::makeAFixed<hermes::vm::Arguments, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
hermes::vm::JSArray* hermes::vm::Runtime::makeAFixed<hermes::vm::JSArray, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::GCPointerBase::NoBarriers>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::GCPointerBase::NoBarriers&&)
Line
Count
Source
1839
428k
T *Runtime::makeAFixed(Args &&...args) {
1840
428k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
428k
  (void)getCurrentIP();
1846
428k
#endif
1847
428k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
428k
      std::forward<Args>(args)...);
1849
428k
}
Unexecuted instantiation: hermes::vm::JSArrayIterator* hermes::vm::Runtime::makeAFixed<hermes::vm::JSArrayIterator, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::IterationKind&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::IterationKind&)
Unexecuted instantiation: hermes::vm::JSArrayBuffer* hermes::vm::Runtime::makeAFixed<hermes::vm::JSArrayBuffer, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSDataView* hermes::vm::Runtime::makeAFixed<hermes::vm::JSDataView, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSDate* hermes::vm::Runtime::makeAFixed<hermes::vm::JSDate, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, double&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, double&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
hermes::vm::JSError* hermes::vm::Runtime::makeAFixed<hermes::vm::JSError, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, bool&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, bool&)
Line
Count
Source
1839
24
T *Runtime::makeAFixed(Args &&...args) {
1840
24
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
24
  (void)getCurrentIP();
1846
24
#endif
1847
24
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
24
      std::forward<Args>(args)...);
1849
24
}
Unexecuted instantiation: hermes::vm::JSGenerator* hermes::vm::Runtime::makeAFixed<hermes::vm::JSGenerator, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
hermes::vm::JSObject* hermes::vm::Runtime::makeAFixed<hermes::vm::JSObject, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::GCPointerBase::NoBarriers>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::GCPointerBase::NoBarriers&&)
Line
Count
Source
1839
10.9k
T *Runtime::makeAFixed(Args &&...args) {
1840
10.9k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
10.9k
  (void)getCurrentIP();
1846
10.9k
#endif
1847
10.9k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
10.9k
      std::forward<Args>(args)...);
1849
10.9k
}
Unexecuted instantiation: hermes::vm::JSProxy* hermes::vm::Runtime::makeAFixed<hermes::vm::JSProxy, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
hermes::vm::JSRegExp* hermes::vm::Runtime::makeAFixed<hermes::vm::JSRegExp, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Line
Count
Source
1839
242
T *Runtime::makeAFixed(Args &&...args) {
1840
242
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
242
  (void)getCurrentIP();
1846
242
#endif
1847
242
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
242
      std::forward<Args>(args)...);
1849
242
}
Unexecuted instantiation: hermes::vm::JSMapImpl<(hermes::vm::CellKind)47>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSMapImpl<(hermes::vm::CellKind)47>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSMapImpl<(hermes::vm::CellKind)48>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSMapImpl<(hermes::vm::CellKind)48>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSMapIteratorImpl<(hermes::vm::CellKind)50>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSMapIteratorImpl<(hermes::vm::CellKind)50>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSMapIteratorImpl<(hermes::vm::CellKind)49>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSMapIteratorImpl<(hermes::vm::CellKind)49>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<signed char, (hermes::vm::CellKind)35>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<signed char, (hermes::vm::CellKind)35>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<short, (hermes::vm::CellKind)36>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<short, (hermes::vm::CellKind)36>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<int, (hermes::vm::CellKind)37>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<int, (hermes::vm::CellKind)37>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)38>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)38>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)39>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)39>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<unsigned short, (hermes::vm::CellKind)40>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<unsigned short, (hermes::vm::CellKind)40>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<unsigned int, (hermes::vm::CellKind)41>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<unsigned int, (hermes::vm::CellKind)41>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<float, (hermes::vm::CellKind)42>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<float, (hermes::vm::CellKind)42>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<double, (hermes::vm::CellKind)43>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<double, (hermes::vm::CellKind)43>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<long, (hermes::vm::CellKind)44>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<long, (hermes::vm::CellKind)44>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSTypedArray<unsigned long, (hermes::vm::CellKind)45>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSTypedArray<unsigned long, (hermes::vm::CellKind)45>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)51>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)51>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> >&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> >&)
Unexecuted instantiation: hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)52>* hermes::vm::Runtime::makeAFixed<hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)52>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> >&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> >&)
Unexecuted instantiation: hermes::vm::JSWeakRef* hermes::vm::Runtime::makeAFixed<hermes::vm::JSWeakRef, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::DecoratedObject* hermes::vm::Runtime::makeAFixed<hermes::vm::DecoratedObject, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, std::__1::unique_ptr<hermes::vm::DecoratedObject::Decoration, std::__1::default_delete<hermes::vm::DecoratedObject::Decoration> > >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, std::__1::unique_ptr<hermes::vm::DecoratedObject::Decoration, std::__1::default_delete<hermes::vm::DecoratedObject::Decoration> >&&)
Unexecuted instantiation: hermes::vm::FinalizableNativeFunction* hermes::vm::Runtime::makeAFixed<hermes::vm::FinalizableNativeFunction, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), void (*&)(void*)>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, void*&, hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> (*&)(void*, hermes::vm::Runtime&, hermes::vm::NativeArgs), void (*&)(void*))
hermes::vm::HostObject* hermes::vm::Runtime::makeAFixed<hermes::vm::HostObject, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, std::__1::unique_ptr<hermes::vm::HostObjectProxy, std::__1::default_delete<hermes::vm::HostObjectProxy> > >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, std::__1::unique_ptr<hermes::vm::HostObjectProxy, std::__1::default_delete<hermes::vm::HostObjectProxy> >&&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
Unexecuted instantiation: hermes::vm::NativeState* hermes::vm::Runtime::makeAFixed<hermes::vm::NativeState, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, void*&, void (*&)(void*)>(void*&, void (*&)(void*))
hermes::vm::JSString* hermes::vm::Runtime::makeAFixed<hermes::vm::JSString, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::StringPrimitive>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::StringPrimitive>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
Unexecuted instantiation: hermes::vm::JSStringIterator* hermes::vm::Runtime::makeAFixed<hermes::vm::JSStringIterator, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::Handle<hermes::vm::StringPrimitive>&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&, hermes::vm::Handle<hermes::vm::StringPrimitive>&)
Unexecuted instantiation: hermes::vm::JSBigInt* hermes::vm::Runtime::makeAFixed<hermes::vm::JSBigInt, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::BigIntPrimitive>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::BigIntPrimitive>&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
hermes::vm::JSNumber* hermes::vm::Runtime::makeAFixed<hermes::vm::JSNumber, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, double&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, double&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
hermes::vm::JSBoolean* hermes::vm::Runtime::makeAFixed<hermes::vm::JSBoolean, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, bool&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, bool&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
Unexecuted instantiation: hermes::vm::JSSymbol* hermes::vm::Runtime::makeAFixed<hermes::vm::JSSymbol, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::SymbolID&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&>(hermes::vm::Runtime&, hermes::vm::SymbolID&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&)
hermes::vm::PropertyAccessor* hermes::vm::Runtime::makeAFixed<hermes::vm::PropertyAccessor, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Callable>&, hermes::vm::Handle<hermes::vm::Callable>&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Callable>&, hermes::vm::Handle<hermes::vm::Callable>&)
Line
Count
Source
1839
4.28k
T *Runtime::makeAFixed(Args &&...args) {
1840
4.28k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
4.28k
  (void)getCurrentIP();
1846
4.28k
#endif
1847
4.28k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
4.28k
      std::forward<Args>(args)...);
1849
4.28k
}
Unexecuted instantiation: hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>::Segment* hermes::vm::Runtime::makeAFixed<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>::Segment, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>()
hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>::Segment* hermes::vm::Runtime::makeAFixed<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>::Segment, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>()
Line
Count
Source
1839
1.09k
T *Runtime::makeAFixed(Args &&...args) {
1840
1.09k
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
1.09k
  (void)getCurrentIP();
1846
1.09k
#endif
1847
1.09k
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
1.09k
      std::forward<Args>(args)...);
1849
1.09k
}
hermes::vm::SingleObject<(hermes::vm::CellKind)60>* hermes::vm::Runtime::makeAFixed<hermes::vm::SingleObject<(hermes::vm::CellKind)60>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
hermes::vm::SingleObject<(hermes::vm::CellKind)59>* hermes::vm::Runtime::makeAFixed<hermes::vm::SingleObject<(hermes::vm::CellKind)59>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
Unexecuted instantiation: hermes::vm::HashMapEntry* hermes::vm::Runtime::makeAFixed<hermes::vm::HashMapEntry, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>()
hermes::vm::OrderedHashMap* hermes::vm::Runtime::makeAFixed<hermes::vm::OrderedHashMap, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32> >&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32> >&)
Line
Count
Source
1839
99
T *Runtime::makeAFixed(Args &&...args) {
1840
99
#ifndef NDEBUG
1841
  // We always call getCurrentIP() in a debug build as this has the effect of
1842
  // asserting the IP is correctly set (not invalidated) at this point. This
1843
  // allows us to leverage our whole test-suite to find missing cases of
1844
  // CAPTURE_IP* macros in the interpreter loop.
1845
99
  (void)getCurrentIP();
1846
99
#endif
1847
99
  return getHeap().makeAFixed<T, hasFinalizer, longLived>(
1848
99
      std::forward<Args>(args)...);
1849
99
}
Unexecuted instantiation: hermes::vm::JSCallSite* hermes::vm::Runtime::makeAFixed<hermes::vm::JSCallSite, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::JSError>&, unsigned int&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::JSError>&, unsigned int&)
Unexecuted instantiation: hermes::vm::JSCallableProxy* hermes::vm::Runtime::makeAFixed<hermes::vm::JSCallableProxy, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, hermes::vm::Handle<hermes::vm::HiddenClass> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&&, hermes::vm::Handle<hermes::vm::HiddenClass>&&)
Unexecuted instantiation: hermes::vm::JSRegExpStringIterator* hermes::vm::Runtime::makeAFixed<hermes::vm::JSRegExpStringIterator, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::StringPrimitive>&, bool&, bool&>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::HiddenClass>&&, hermes::vm::Handle<hermes::vm::JSObject>&, hermes::vm::Handle<hermes::vm::StringPrimitive>&, bool&, bool&)
1850
1851
template <
1852
    typename T,
1853
    HasFinalizer hasFinalizer,
1854
    LongLived longLived,
1855
    class... Args>
1856
1.73M
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
1.73M
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
1.73M
  (void)getCurrentIP();
1863
1.73M
#endif
1864
1.73M
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
1.73M
      size, std::forward<Args>(args)...);
1866
1.73M
}
Unexecuted instantiation: hermes::vm::BigIntPrimitive* hermes::vm::Runtime::makeAVariable<hermes::vm::BigIntPrimitive, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&>(unsigned int, unsigned int&)
hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32>* hermes::vm::Runtime::makeAVariable<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>(unsigned int)
Line
Count
Source
1856
459k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
459k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
459k
  (void)getCurrentIP();
1863
459k
#endif
1864
459k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
459k
      size, std::forward<Args>(args)...);
1866
459k
}
hermes::vm::Environment* hermes::vm::Runtime::makeAVariable<hermes::vm::Environment, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Environment>&, unsigned int&>(unsigned int, hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::Environment>&, unsigned int&)
Line
Count
Source
1856
452
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
452
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
452
  (void)getCurrentIP();
1863
452
#endif
1864
452
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
452
      size, std::forward<Args>(args)...);
1866
452
}
hermes::vm::ArrayStorageBase<hermes::vm::HermesValue>* hermes::vm::Runtime::makeAVariable<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>(unsigned int)
Line
Count
Source
1856
99
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
99
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
99
  (void)getCurrentIP();
1863
99
#endif
1864
99
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
99
      size, std::forward<Args>(args)...);
1866
99
}
hermes::vm::DynamicStringPrimitive<char, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, unsigned long&>(unsigned int, unsigned long&)
Line
Count
Source
1856
105k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
105k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
105k
  (void)getCurrentIP();
1863
105k
#endif
1864
105k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
105k
      size, std::forward<Args>(args)...);
1866
105k
}
hermes::vm::DynamicStringPrimitive<char16_t, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, unsigned long&>(unsigned int, unsigned long&)
Line
Count
Source
1856
132
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
132
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
132
  (void)getCurrentIP();
1863
132
#endif
1864
132
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
132
      size, std::forward<Args>(args)...);
1866
132
}
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, unsigned long&>(unsigned int, unsigned long&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char16_t, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, unsigned long&>(unsigned int, unsigned long&)
Unexecuted instantiation: hermes::vm::FillerCell* hermes::vm::Runtime::makeAVariable<hermes::vm::FillerCell, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>(unsigned int)
Unexecuted instantiation: hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>* hermes::vm::Runtime::makeAVariable<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>(unsigned int)
Unexecuted instantiation: hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>* hermes::vm::Runtime::makeAVariable<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1>(unsigned int)
hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>* hermes::vm::Runtime::makeAVariable<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0>(unsigned int)
Line
Count
Source
1856
415k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
415k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
415k
  (void)getCurrentIP();
1863
415k
#endif
1864
415k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
415k
      size, std::forward<Args>(args)...);
1866
415k
}
Unexecuted instantiation: hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>* hermes::vm::Runtime::makeAVariable<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue32>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1>(unsigned int)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char16_t, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, llvh::ArrayRef<char16_t>&>(unsigned int, llvh::ArrayRef<char16_t>&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char16_t, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, llvh::ArrayRef<char16_t>&>(unsigned int, llvh::ArrayRef<char16_t>&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char16_t, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&>(unsigned int, unsigned int&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, llvh::ArrayRef<char>&>(unsigned int, llvh::ArrayRef<char>&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, llvh::ArrayRef<char>&>(unsigned int, llvh::ArrayRef<char>&)
Unexecuted instantiation: hermes::vm::DynamicStringPrimitive<char, true>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, true>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&>(unsigned int, unsigned int&)
hermes::vm::DynamicStringPrimitive<char16_t, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, llvh::ArrayRef<char16_t>&>(unsigned int, llvh::ArrayRef<char16_t>&)
Line
Count
Source
1856
8
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
8
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
8
  (void)getCurrentIP();
1863
8
#endif
1864
8
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
8
      size, std::forward<Args>(args)...);
1866
8
}
hermes::vm::DynamicStringPrimitive<char16_t, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, llvh::ArrayRef<char16_t>&>(unsigned int, llvh::ArrayRef<char16_t>&)
Line
Count
Source
1856
12.6k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
12.6k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
12.6k
  (void)getCurrentIP();
1863
12.6k
#endif
1864
12.6k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
12.6k
      size, std::forward<Args>(args)...);
1866
12.6k
}
hermes::vm::DynamicStringPrimitive<char16_t, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char16_t, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&>(unsigned int, unsigned int&)
Line
Count
Source
1856
410k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
410k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
410k
  (void)getCurrentIP();
1863
410k
#endif
1864
410k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
410k
      size, std::forward<Args>(args)...);
1866
410k
}
hermes::vm::DynamicStringPrimitive<char, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, llvh::ArrayRef<char>&>(unsigned int, llvh::ArrayRef<char>&)
Line
Count
Source
1856
249k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
249k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
249k
  (void)getCurrentIP();
1863
249k
#endif
1864
249k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
249k
      size, std::forward<Args>(args)...);
1866
249k
}
hermes::vm::DynamicStringPrimitive<char, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1, llvh::ArrayRef<char>&>(unsigned int, llvh::ArrayRef<char>&)
Line
Count
Source
1856
12.6k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
12.6k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
12.6k
  (void)getCurrentIP();
1863
12.6k
#endif
1864
12.6k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
12.6k
      size, std::forward<Args>(args)...);
1866
12.6k
}
hermes::vm::DynamicStringPrimitive<char, false>* hermes::vm::Runtime::makeAVariable<hermes::vm::DynamicStringPrimitive<char, false>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&>(unsigned int, unsigned int&)
Line
Count
Source
1856
49.4k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
49.4k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
49.4k
  (void)getCurrentIP();
1863
49.4k
#endif
1864
49.4k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
49.4k
      size, std::forward<Args>(args)...);
1866
49.4k
}
hermes::vm::ExternalStringPrimitive<char16_t>* hermes::vm::Runtime::makeAVariable<hermes::vm::ExternalStringPrimitive<char16_t>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)1, std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> > >(unsigned int, std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> >&&)
Line
Count
Source
1856
13
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
13
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
13
  (void)getCurrentIP();
1863
13
#endif
1864
13
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
13
      size, std::forward<Args>(args)...);
1866
13
}
hermes::vm::ExternalStringPrimitive<char>* hermes::vm::Runtime::makeAVariable<hermes::vm::ExternalStringPrimitive<char>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)1, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
1856
5
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
5
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
5
  (void)getCurrentIP();
1863
5
#endif
1864
5
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
5
      size, std::forward<Args>(args)...);
1866
5
}
hermes::vm::ExternalStringPrimitive<char>* hermes::vm::Runtime::makeAVariable<hermes::vm::ExternalStringPrimitive<char>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
1856
60
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
60
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
60
  (void)getCurrentIP();
1863
60
#endif
1864
60
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
60
      size, std::forward<Args>(args)...);
1866
60
}
hermes::vm::ExternalStringPrimitive<char16_t>* hermes::vm::Runtime::makeAVariable<hermes::vm::ExternalStringPrimitive<char16_t>, (hermes::vm::HasFinalizer)1, (hermes::vm::LongLived)0, std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> > >(unsigned int, std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> >&&)
Line
Count
Source
1856
48
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
48
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
48
  (void)getCurrentIP();
1863
48
#endif
1864
48
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
48
      size, std::forward<Args>(args)...);
1866
48
}
hermes::vm::BufferedStringPrimitive<char16_t>* hermes::vm::Runtime::makeAVariable<hermes::vm::BufferedStringPrimitive<char16_t>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, unsigned int&, hermes::vm::Handle<hermes::vm::ExternalStringPrimitive<char16_t> >&>(unsigned int, hermes::vm::Runtime&, unsigned int&, hermes::vm::Handle<hermes::vm::ExternalStringPrimitive<char16_t> >&)
Line
Count
Source
1856
162
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
162
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
162
  (void)getCurrentIP();
1863
162
#endif
1864
162
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
162
      size, std::forward<Args>(args)...);
1866
162
}
hermes::vm::BufferedStringPrimitive<char>* hermes::vm::Runtime::makeAVariable<hermes::vm::BufferedStringPrimitive<char>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, hermes::vm::Runtime&, unsigned int&, hermes::vm::Handle<hermes::vm::ExternalStringPrimitive<char> >&>(unsigned int, hermes::vm::Runtime&, unsigned int&, hermes::vm::Handle<hermes::vm::ExternalStringPrimitive<char> >&)
Line
Count
Source
1856
711
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
711
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
711
  (void)getCurrentIP();
1863
711
#endif
1864
711
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
711
      size, std::forward<Args>(args)...);
1866
711
}
Unexecuted instantiation: hermes::vm::ArrayStorageBase<hermes::vm::HermesValue>* hermes::vm::Runtime::makeAVariable<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1>(unsigned int)
Unexecuted instantiation: hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32>* hermes::vm::Runtime::makeAVariable<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32>, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)1>(unsigned int)
hermes::vm::DictPropertyMap* hermes::vm::Runtime::makeAVariable<hermes::vm::DictPropertyMap, (hermes::vm::HasFinalizer)0, (hermes::vm::LongLived)0, unsigned int&, unsigned int&>(unsigned int, unsigned int&, unsigned int&)
Line
Count
Source
1856
19.2k
T *Runtime::makeAVariable(uint32_t size, Args &&...args) {
1857
19.2k
#ifndef NDEBUG
1858
  // We always call getCurrentIP() in a debug build as this has the effect of
1859
  // asserting the IP is correctly set (not invalidated) at this point. This
1860
  // allows us to leverage our whole test-suite to find missing cases of
1861
  // CAPTURE_IP* macros in the interpreter loop.
1862
19.2k
  (void)getCurrentIP();
1863
19.2k
#endif
1864
19.2k
  return getHeap().makeAVariable<T, hasFinalizer, longLived>(
1865
19.2k
      size, std::forward<Args>(args)...);
1866
19.2k
}
1867
1868
template <typename T>
1869
178k
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
178k
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
178k
  return std::move(res.getValue());
1876
178k
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_11HermesValueEEET_NS0_10CallResultIS4_Xsr6detail23GetCallResultSpecializeIS4_EE5valueEEE
Line
Count
Source
1869
135k
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
135k
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
135k
  return std::move(res.getValue());
1876
135k
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_12PseudoHandleINS0_15StringPrimitiveEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
34.1k
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
34.1k
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
34.1k
  return std::move(res.getValue());
1876
34.1k
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_12PseudoHandleINS0_8JSObjectEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
877
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
877
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
877
  return std::move(res.getValue());
1876
877
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureIbEET_NS0_10CallResultIS3_Xsr6detail23GetCallResultSpecializeIS3_EE5valueEEE
Line
Count
Source
1869
3.06k
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
3.06k
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
3.06k
  return std::move(res.getValue());
1876
3.06k
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_6HandleINS0_8SymbolIDEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
4.35k
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
4.35k
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
4.35k
  return std::move(res.getValue());
1876
4.35k
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_12PseudoHandleINS0_11HermesValueEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
495
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
495
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
495
  return std::move(res.getValue());
1876
495
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_6HandleINS0_8JSStringEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
99
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
99
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
99
  return std::move(res.getValue());
1876
99
}
_ZN6hermes2vm7Runtime23ignoreAllocationFailureINS0_6HandleINS0_7JSArrayEEEEET_NS0_10CallResultIS6_Xsr6detail23GetCallResultSpecializeIS6_EE5valueEEE
Line
Count
Source
1869
99
inline T Runtime::ignoreAllocationFailure(CallResult<T> res) {
1870
99
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION))
1871
0
    hermes_fatal("Unhandled out of memory exception");
1872
  // Use std::move here to account for specializations of CallResult,
1873
  // (in particular, CallResult<PseudoHandle<U>>)
1874
  // which wrap a class with a deleted copy constructor.
1875
99
  return std::move(res.getValue());
1876
99
}
1877
1878
446k
inline void Runtime::ignoreAllocationFailure(ExecutionStatus status) {
1879
446k
  if (LLVM_UNLIKELY(status == ExecutionStatus::EXCEPTION))
1880
0
    hermes_fatal("Unhandled out of memory exception");
1881
446k
}
1882
1883
0
inline void Runtime::ttiReached() {
1884
  // Currently, only the heap_ behavior can change at TTI.
1885
0
  getHeap().ttiReached();
1886
0
}
1887
1888
template <class T>
1889
303k
inline Handle<T> Runtime::makeHandle(const GCPointer<T> &p) {
1890
303k
  return Handle<T>(*this, p.get(*this));
1891
303k
}
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::JSArrayBuffer> hermes::vm::Runtime::makeHandle<hermes::vm::JSArrayBuffer>(hermes::vm::GCPointer<hermes::vm::JSArrayBuffer> const&)
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::DictPropertyMap> hermes::vm::Runtime::makeHandle<hermes::vm::DictPropertyMap>(hermes::vm::GCPointer<hermes::vm::DictPropertyMap> const&)
hermes::vm::Handle<hermes::vm::Callable> hermes::vm::Runtime::makeHandle<hermes::vm::Callable>(hermes::vm::GCPointer<hermes::vm::Callable> const&)
Line
Count
Source
1889
1.90k
inline Handle<T> Runtime::makeHandle(const GCPointer<T> &p) {
1890
1.90k
  return Handle<T>(*this, p.get(*this));
1891
1.90k
}
hermes::vm::Handle<hermes::vm::HiddenClass> hermes::vm::Runtime::makeHandle<hermes::vm::HiddenClass>(hermes::vm::GCPointer<hermes::vm::HiddenClass> const&)
Line
Count
Source
1889
301k
inline Handle<T> Runtime::makeHandle(const GCPointer<T> &p) {
1890
301k
  return Handle<T>(*this, p.get(*this));
1891
301k
}
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::JSObject> hermes::vm::Runtime::makeHandle<hermes::vm::JSObject>(hermes::vm::GCPointer<hermes::vm::JSObject> const&)
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::OrderedHashMap> hermes::vm::Runtime::makeHandle<hermes::vm::OrderedHashMap>(hermes::vm::GCPointer<hermes::vm::OrderedHashMap> const&)
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::StringPrimitive> hermes::vm::Runtime::makeHandle<hermes::vm::StringPrimitive>(hermes::vm::GCPointer<hermes::vm::StringPrimitive> const&)
Unexecuted instantiation: hermes::vm::Handle<hermes::vm::JSError> hermes::vm::Runtime::makeHandle<hermes::vm::JSError>(hermes::vm::GCPointer<hermes::vm::JSError> const&)
1892
1893
template <class T>
1894
5.76k
inline MutableHandle<T> Runtime::makeMutableHandle(const GCPointer<T> &p) {
1895
5.76k
  return MutableHandle<T>(*this, p.get(*this));
1896
5.76k
}
Unexecuted instantiation: hermes::vm::MutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue> > hermes::vm::Runtime::makeMutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue> >(hermes::vm::GCPointer<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue> > const&)
hermes::vm::MutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32> > hermes::vm::Runtime::makeMutableHandle<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32> >(hermes::vm::GCPointer<hermes::vm::ArrayStorageBase<hermes::vm::HermesValue32> > const&)
Line
Count
Source
1894
5.76k
inline MutableHandle<T> Runtime::makeMutableHandle(const GCPointer<T> &p) {
1895
5.76k
  return MutableHandle<T>(*this, p.get(*this));
1896
5.76k
}
Unexecuted instantiation: hermes::vm::MutableHandle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> > hermes::vm::Runtime::makeMutableHandle<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> >(hermes::vm::GCPointer<hermes::vm::SegmentedArrayBase<hermes::vm::HermesValue> > const&)
1897
1898
inline StringPrimitive *Runtime::getPredefinedString(
1899
29.9k
    Predefined::Str predefined) {
1900
29.9k
  return getStringPrimFromSymbolID(Predefined::getSymbolID(predefined));
1901
29.9k
}
1902
1903
inline StringPrimitive *Runtime::getPredefinedString(
1904
0
    Predefined::Sym predefined) {
1905
0
  return getStringPrimFromSymbolID(Predefined::getSymbolID(predefined));
1906
0
}
1907
1908
inline Handle<StringPrimitive> Runtime::getPredefinedStringHandle(
1909
3.12k
    Predefined::Str predefined) {
1910
3.12k
  return makeHandle(getPredefinedString(predefined));
1911
3.12k
}
1912
1913
inline Handle<StringPrimitive> Runtime::getPredefinedStringHandle(
1914
0
    Predefined::Sym predefined) {
1915
0
  return makeHandle(getPredefinedString(predefined));
1916
0
}
1917
1918
78.5k
inline StringPrimitive *Runtime::getStringPrimFromSymbolID(SymbolID id) {
1919
78.5k
  return identifierTable_.getStringPrim(*this, id);
1920
78.5k
}
1921
1922
#ifdef HERMESVM_PROFILER_BB
1923
inline BasicBlockExecutionInfo &Runtime::getBasicBlockExecutionInfo() {
1924
  return basicBlockExecInfo_;
1925
}
1926
1927
inline void Runtime::dumpBasicBlockProfileTrace(llvh::raw_ostream &OS) {
1928
  basicBlockExecInfo_.dump(OS);
1929
}
1930
#endif
1931
1932
0
inline Runtime::FormatSymbolID Runtime::formatSymbolID(SymbolID id) {
1933
0
  return FormatSymbolID(*this, id);
1934
0
}
1935
1936
407k
inline void Runtime::popToSavedStackPointer(PinnedHermesValue *stackPointer) {
1937
407k
  assert(
1938
407k
      stackPointer <= stackPointer_ &&
1939
407k
      "attempting to pop the stack to a higher level");
1940
0
  stackPointer_ = stackPointer;
1941
407k
}
1942
1943
0
inline uint32_t Runtime::getStackLevel() const {
1944
0
  return (uint32_t)(stackPointer_ - registerStackStart_);
1945
0
}
1946
1947
1.63M
inline uint32_t Runtime::availableStackSize() const {
1948
1.63M
  return (uint32_t)(registerStackEnd_ - stackPointer_);
1949
1.63M
}
1950
1951
817k
inline bool Runtime::checkAvailableStack(uint32_t count) {
1952
  // Note: use 64-bit arithmetic to avoid overflow. We could also do it with
1953
  // a couple of comparisons, but that is likely to be slower.
1954
817k
  return availableStackSize() >= (uint64_t)count + STACK_RESERVE;
1955
817k
}
1956
1957
817k
inline PinnedHermesValue *Runtime::allocUninitializedStack(uint32_t count) {
1958
817k
  assert(availableStackSize() >= count && "register stack overflow");
1959
0
  return stackPointer_ += count;
1960
817k
}
1961
1962
409k
inline bool Runtime::checkAndAllocStack(uint32_t count, HermesValue initValue) {
1963
409k
  if (!checkAvailableStack(count))
1964
0
    return false;
1965
409k
  allocStack(count, initValue);
1966
409k
  return true;
1967
409k
}
1968
1969
0
inline void Runtime::popStack(uint32_t count) {
1970
0
  assert(getStackLevel() >= count && "register stack underflow");
1971
0
  stackPointer_ += count;
1972
0
}
1973
1974
0
inline void Runtime::setCurrentFrameToTopOfStack(StackFramePtr topFrame) {
1975
0
  assert(
1976
0
      topFrame.ptr() == stackPointer_ &&
1977
0
      "topFrame must equal the top of stack");
1978
0
  currentFrame_ = topFrame;
1979
0
}
1980
1981
/// Set the current frame pointer to the current top of the stack and return
1982
/// it.
1983
/// \return the new value of the current frame pointer.
1984
409k
inline StackFramePtr Runtime::setCurrentFrameToTopOfStack() {
1985
409k
  return currentFrame_ = StackFramePtr(stackPointer_);
1986
409k
}
1987
1988
inline StackFramePtr Runtime::restoreStackAndPreviousFrame(
1989
409k
    StackFramePtr currentFrame) {
1990
409k
  assert(
1991
409k
      currentFrame_ == currentFrame &&
1992
409k
      "currentFrame parameter must match currentFrame_");
1993
0
  stackPointer_ = currentFrame.ptr();
1994
409k
  return currentFrame_ = currentFrame.getPreviousFrame();
1995
409k
}
1996
1997
0
inline StackFramePtr Runtime::restoreStackAndPreviousFrame() {
1998
0
  return restoreStackAndPreviousFrame(currentFrame_);
1999
0
}
2000
2001
403
inline llvh::iterator_range<StackFrameIterator> Runtime::getStackFrames() {
2002
403
  return {
2003
403
      StackFrameIterator{currentFrame_},
2004
403
      StackFrameIterator{registerStackStart_}};
2005
403
};
2006
2007
inline llvh::iterator_range<ConstStackFrameIterator> Runtime::getStackFrames()
2008
0
    const {
2009
0
  return {
2010
0
      ConstStackFrameIterator{currentFrame_},
2011
0
      ConstStackFrameIterator{registerStackStart_}};
2012
0
};
2013
2014
48
inline ExecutionStatus Runtime::setThrownValue(HermesValue value) {
2015
48
  thrownValue_ = value;
2016
48
  return ExecutionStatus::EXCEPTION;
2017
48
}
2018
2019
203
inline void Runtime::clearThrownValue() {
2020
203
  thrownValue_ = HermesValue::encodeEmptyValue();
2021
203
}
2022
2023
1.38k
inline CrashManager &Runtime::getCrashManager() {
2024
1.38k
  return *crashMgr_;
2025
1.38k
}
2026
2027
#ifndef HERMESVM_SANITIZE_HANDLES
2028
1.19M
inline void Runtime::potentiallyMoveHeap() {}
2029
#endif
2030
2031
//===----------------------------------------------------------------------===//
2032
2033
/// Invoke the T constructor with the given args to construct the
2034
/// object in the given memory mem.
2035
template <typename T, typename... CtorArgs>
2036
inline void constructInHeapObj(void *mem, CtorArgs... args) {
2037
  new (mem) T(args...);
2038
}
2039
2040
/// Serialize a SymbolID.
2041
llvh::raw_ostream &operator<<(
2042
    llvh::raw_ostream &OS,
2043
    Runtime::FormatSymbolID format);
2044
2045
} // namespace vm
2046
} // namespace hermes
2047
2048
#endif // HERMES_VM_RUNTIME_H