v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
builtins-microtask-queue-gen.cc
Go to the documentation of this file.
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/api/api.h"
11#include "src/objects/promise.h"
12#include "src/objects/smi-inl.h"
13
14namespace v8 {
15namespace internal {
16
18
19using compiler::ScopedExceptionHandler;
20
22 public:
25
31 TNode<IntPtrT> new_size);
34 TNode<IntPtrT> new_start);
37 TNode<IntPtrT> index);
38
39 void PrepareForContext(TNode<Context> microtask_context, Label* bailout);
40 void RunSingleMicrotask(TNode<Context> current_context,
41 TNode<Microtask> microtask);
43
46
49 void RewindEnteredContext(TNode<IntPtrT> saved_entered_context_count);
50
52 TNode<HeapObject> promise_or_capability);
54 TNode<HeapObject> promise_or_capability,
55 TNode<Uint32T> promiseHookFlags);
56#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
57 void SetupContinuationPreservedEmbedderData(TNode<Microtask> microtask);
58 void ClearContinuationPreservedEmbedderData();
59#endif
60};
61
69
75
81
87
93
99
105
111
114 CSA_DCHECK(this, IsNativeContext(native_context));
115
116 // Skip the microtask execution if the associated context is shutdown.
118 bailout);
119
122}
123
124#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
125void MicrotaskQueueBuiltinsAssembler::SetupContinuationPreservedEmbedderData(
126 TNode<Microtask> microtask) {
127 TNode<Object> continuation_preserved_embedder_data = LoadObjectField(
128 microtask, Microtask::kContinuationPreservedEmbedderDataOffset);
129 Label continuation_preserved_data_done(this);
130 // The isolate's continuation preserved embedder data is cleared at the start
131 // of RunMicrotasks and after each microtask, so it only needs to be set if
132 // it's not undefined.
133 GotoIf(IsUndefined(continuation_preserved_embedder_data),
134 &continuation_preserved_data_done);
135 SetContinuationPreservedEmbedderData(continuation_preserved_embedder_data);
136 Goto(&continuation_preserved_data_done);
137 BIND(&continuation_preserved_data_done);
138}
139
140void MicrotaskQueueBuiltinsAssembler::ClearContinuationPreservedEmbedderData() {
141 SetContinuationPreservedEmbedderData(UndefinedConstant());
142}
143#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
144
146 TNode<Context> current_context, TNode<Microtask> microtask) {
147 CSA_DCHECK(this, TaggedIsNotSmi(microtask));
148 CSA_DCHECK(this, Word32BinaryNot(IsExecutionTerminating()));
149
150 StoreRoot(RootIndex::kCurrentMicrotask, microtask);
151 TNode<IntPtrT> saved_entered_context_count = GetEnteredContextCount();
152 TNode<Map> microtask_map = LoadMap(microtask);
153 TNode<Uint16T> microtask_type = LoadMapInstanceType(microtask_map);
154
155 TVARIABLE(Object, var_exception);
156 Label if_exception(this, Label::kDeferred);
157 Label is_callable(this), is_callback(this),
158 is_promise_fulfill_reaction_job(this),
159 is_promise_reject_reaction_job(this),
160 is_promise_resolve_thenable_job(this),
161 is_unreachable(this, Label::kDeferred), done(this);
162
163 int32_t case_values[] = {CALLABLE_TASK_TYPE, CALLBACK_TASK_TYPE,
164 PROMISE_FULFILL_REACTION_JOB_TASK_TYPE,
165 PROMISE_REJECT_REACTION_JOB_TASK_TYPE,
166 PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE};
167 Label* case_labels[] = {
168 &is_callable, &is_callback, &is_promise_fulfill_reaction_job,
169 &is_promise_reject_reaction_job, &is_promise_resolve_thenable_job};
170 static_assert(arraysize(case_values) == arraysize(case_labels), "");
171 Switch(microtask_type, &is_unreachable, case_values, case_labels,
172 arraysize(case_labels));
173
174 BIND(&is_callable);
175 {
176 // Enter the context of the {microtask}.
177 TNode<Context> microtask_context =
178 LoadObjectField<Context>(microtask, CallableTask::kContextOffset);
181
182#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
183 SetupContinuationPreservedEmbedderData(microtask);
184#endif
185 TNode<JSReceiver> callable =
186 LoadObjectField<JSReceiver>(microtask, CallableTask::kCallableOffset);
187 {
188 ScopedExceptionHandler handler(this, &if_exception, &var_exception);
189 Call(microtask_context, callable, UndefinedConstant());
190 }
191 RewindEnteredContext(saved_entered_context_count);
192 SetCurrentContext(current_context);
193#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
194 ClearContinuationPreservedEmbedderData();
195#endif
196 Goto(&done);
197 }
198
199 BIND(&is_callback);
200 {
201 const TNode<Object> microtask_callback =
202 LoadObjectField(microtask, CallbackTask::kCallbackOffset);
203 const TNode<Object> microtask_data =
204 LoadObjectField(microtask, CallbackTask::kDataOffset);
205#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
206 SetupContinuationPreservedEmbedderData(microtask);
207#endif
208
209 // If this turns out to become a bottleneck because of the calls
210 // to C++ via CEntry, we can choose to speed them up using a
211 // similar mechanism that we use for the CallApiFunction stub,
212 // except that calling the MicrotaskCallback is even easier, since
213 // it doesn't accept any tagged parameters, doesn't return a value
214 // and ignores exceptions.
215 //
216 // But from our current measurements it doesn't seem to be a
217 // serious performance problem, even if the microtask is full
218 // of CallHandlerTasks (which is not a realistic use case anyways).
219 {
220 ScopedExceptionHandler handler(this, &if_exception, &var_exception);
221 CallRuntime(Runtime::kRunMicrotaskCallback, current_context,
222 microtask_callback, microtask_data);
223 }
224#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
225 ClearContinuationPreservedEmbedderData();
226#endif
227 Goto(&done);
228 }
229
230 BIND(&is_promise_resolve_thenable_job);
231 {
232 // Enter the context of the {microtask}.
233 TNode<Context> microtask_context = LoadObjectField<Context>(
234 microtask, PromiseResolveThenableJobTask::kContextOffset);
237
238 const TNode<Object> promise_to_resolve = LoadObjectField(
239 microtask, PromiseResolveThenableJobTask::kPromiseToResolveOffset);
240 const TNode<Object> then =
241 LoadObjectField(microtask, PromiseResolveThenableJobTask::kThenOffset);
242 const TNode<Object> thenable = LoadObjectField(
243 microtask, PromiseResolveThenableJobTask::kThenableOffset);
244#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
245 SetupContinuationPreservedEmbedderData(microtask);
246#endif
248 CAST(promise_to_resolve));
249
250 {
251 ScopedExceptionHandler handler(this, &if_exception, &var_exception);
252 CallBuiltin(Builtin::kPromiseResolveThenableJob, native_context,
253 promise_to_resolve, thenable, then);
254 }
255
257 CAST(promise_to_resolve));
258
259 RewindEnteredContext(saved_entered_context_count);
260 SetCurrentContext(current_context);
261#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
262 ClearContinuationPreservedEmbedderData();
263#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
264 Goto(&done);
265 }
266
267 BIND(&is_promise_fulfill_reaction_job);
268 {
269 // Enter the context of the {microtask}.
270 TNode<Context> microtask_context = LoadObjectField<Context>(
271 microtask, PromiseReactionJobTask::kContextOffset);
274
275 const TNode<Object> argument =
276 LoadObjectField(microtask, PromiseReactionJobTask::kArgumentOffset);
277 const TNode<Object> job_handler =
278 LoadObjectField(microtask, PromiseReactionJobTask::kHandlerOffset);
279 const TNode<HeapObject> promise_or_capability = CAST(LoadObjectField(
280 microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset));
281
282#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
283 SetupContinuationPreservedEmbedderData(microtask);
284#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
285
286 // Run the promise before/debug hook if enabled.
288 promise_or_capability);
289
290 {
291 ScopedExceptionHandler handler(this, &if_exception, &var_exception);
292 CallBuiltin(Builtin::kPromiseFulfillReactionJob, microtask_context,
293 argument, job_handler, promise_or_capability);
294 }
295
296 // Run the promise after/debug hook if enabled.
298 promise_or_capability);
299
300#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
301 ClearContinuationPreservedEmbedderData();
302#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
303
304 RewindEnteredContext(saved_entered_context_count);
305 SetCurrentContext(current_context);
306 Goto(&done);
307 }
308
309 BIND(&is_promise_reject_reaction_job);
310 {
311 // Enter the context of the {microtask}.
312 TNode<Context> microtask_context = LoadObjectField<Context>(
313 microtask, PromiseReactionJobTask::kContextOffset);
316
317 const TNode<Object> argument =
318 LoadObjectField(microtask, PromiseReactionJobTask::kArgumentOffset);
319 const TNode<Object> job_handler =
320 LoadObjectField(microtask, PromiseReactionJobTask::kHandlerOffset);
321 const TNode<HeapObject> promise_or_capability = CAST(LoadObjectField(
322 microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset));
323
324#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
325 SetupContinuationPreservedEmbedderData(microtask);
326#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
327
328 // Run the promise before/debug hook if enabled.
330 promise_or_capability);
331
332 {
333 ScopedExceptionHandler handler(this, &if_exception, &var_exception);
334 CallBuiltin(Builtin::kPromiseRejectReactionJob, microtask_context,
335 argument, job_handler, promise_or_capability);
336 }
337
338 // Run the promise after/debug hook if enabled.
340 promise_or_capability);
341
342#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
343 ClearContinuationPreservedEmbedderData();
344#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
345
346 RewindEnteredContext(saved_entered_context_count);
347 SetCurrentContext(current_context);
348 Goto(&done);
349 }
350
351 BIND(&is_unreachable);
352 Unreachable();
353
354 BIND(&if_exception);
355 {
356 // Report unhandled exceptions from microtasks.
357 CallRuntime(Runtime::kReportMessageFromMicrotask, GetCurrentContext(),
358 var_exception.value());
359 RewindEnteredContext(saved_entered_context_count);
360 SetCurrentContext(current_context);
361 Goto(&done);
362 }
363
364 BIND(&done);
365}
366
377
379 auto ref = ExternalReference::Create(kContextAddress, isolate());
380 // TODO(delphick): Add a checked cast. For now this is not possible as context
381 // can actually be Tagged<Smi>(0).
383}
384
390
392 auto ref = ExternalReference::handle_scope_implementer_address(isolate());
394
395 using ContextStack = DetachableVector<Context>;
396 TNode<IntPtrT> size_offset =
398 ContextStack::kSizeOffset);
399 return Load<IntPtrT>(hsi, size_offset);
400}
401
404 CSA_DCHECK(this, IsNativeContext(native_context));
405
406 auto ref = ExternalReference::handle_scope_implementer_address(isolate());
408
409 using ContextStack = DetachableVector<Context>;
410 TNode<IntPtrT> capacity_offset =
412 ContextStack::kCapacityOffset);
413 TNode<IntPtrT> size_offset =
415 ContextStack::kSizeOffset);
416
417 TNode<IntPtrT> capacity = Load<IntPtrT>(hsi, capacity_offset);
418 TNode<IntPtrT> size = Load<IntPtrT>(hsi, size_offset);
419
420 Label if_append(this), if_grow(this, Label::kDeferred), done(this);
421 Branch(WordEqual(size, capacity), &if_grow, &if_append);
422 BIND(&if_append);
423 {
424 TNode<IntPtrT> data_offset =
426 ContextStack::kDataOffset);
427 TNode<RawPtrT> data = Load<RawPtrT>(hsi, data_offset);
430
431 TNode<IntPtrT> new_size = IntPtrAdd(size, IntPtrConstant(1));
433 new_size);
434 Goto(&done);
435 }
436
437 BIND(&if_grow);
438 {
439 TNode<ExternalReference> function =
440 ExternalConstant(ExternalReference::call_enter_context_function());
442 std::make_pair(MachineType::Pointer(), hsi),
443 std::make_pair(MachineType::Pointer(),
445 Goto(&done);
446 }
447
448 BIND(&done);
449}
450
452 TNode<IntPtrT> saved_entered_context_count) {
453 auto ref = ExternalReference::handle_scope_implementer_address(isolate());
455
456 using ContextStack = DetachableVector<Context>;
457 TNode<IntPtrT> size_offset =
459 ContextStack::kSizeOffset);
460
461 if (DEBUG_BOOL) {
462 TNode<IntPtrT> size = Load<IntPtrT>(hsi, size_offset);
463 CSA_CHECK(this, IntPtrLessThan(IntPtrConstant(0), size));
464 CSA_CHECK(this, IntPtrLessThanOrEqual(saved_entered_context_count, size));
465 }
466
468 saved_entered_context_count);
469}
470
472 PromiseHookType type, TNode<Context> context,
473 TNode<HeapObject> promise_or_capability) {
474 TNode<Uint32T> promiseHookFlags = PromiseHookFlags();
475#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
476 Label hook(this, Label::kDeferred), done_hook(this);
477 Branch(NeedsAnyPromiseHooks(promiseHookFlags), &hook, &done_hook);
478 BIND(&hook);
479 {
480#endif
481 switch (type) {
483#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
484 RunContextPromiseHookBefore(context, CAST(promise_or_capability),
485 promiseHookFlags);
486#endif
487 RunPromiseHook(Runtime::kPromiseHookBefore, context,
488 promise_or_capability, promiseHookFlags);
489 break;
491#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
492 RunContextPromiseHookAfter(context, CAST(promise_or_capability),
493 promiseHookFlags);
494#endif
495 RunPromiseHook(Runtime::kPromiseHookAfter, context,
496 promise_or_capability, promiseHookFlags);
497 break;
498 default:
499 UNREACHABLE();
500 }
501#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
502 Goto(&done_hook);
503 }
504 BIND(&done_hook);
505#endif
506}
507
510 TNode<HeapObject> promise_or_capability,
511 TNode<Uint32T> promiseHookFlags) {
512 Label hook(this, Label::kDeferred), done_hook(this);
514 promiseHookFlags), &hook, &done_hook);
515 BIND(&hook);
516 {
517 // Get to the underlying JSPromise instance.
519 IsPromiseCapability(promise_or_capability),
520 [=, this] {
521 return CAST(LoadObjectField(promise_or_capability,
522 PromiseCapability::kPromiseOffset));
523 },
524
525 [=] { return promise_or_capability; });
526 GotoIf(IsUndefined(promise), &done_hook);
527 CallRuntime(id, context, promise);
528 Goto(&done_hook);
529 }
530 BIND(&done_hook);
531}
532
534 auto microtask = Parameter<Microtask>(Descriptor::kMicrotask);
535 auto context = Parameter<Context>(Descriptor::kContext);
536 TNode<NativeContext> native_context = LoadNativeContext(context);
537 TNode<RawPtrT> microtask_queue = GetMicrotaskQueue(native_context);
538
539 // Do not store the microtask if MicrotaskQueue is not available, that may
540 // happen when the context shutdown.
541 Label if_shutdown(this, Label::kDeferred);
542 GotoIf(WordEqual(microtask_queue, IntPtrConstant(0)), &if_shutdown);
543
544 TNode<RawPtrT> ring_buffer = GetMicrotaskRingBuffer(microtask_queue);
545 TNode<IntPtrT> capacity = GetMicrotaskQueueCapacity(microtask_queue);
546 TNode<IntPtrT> size = GetMicrotaskQueueSize(microtask_queue);
547 TNode<IntPtrT> start = GetMicrotaskQueueStart(microtask_queue);
548
549 Label if_grow(this, Label::kDeferred);
550 GotoIf(IntPtrEqual(size, capacity), &if_grow);
551
552 // |microtask_queue| has an unused slot to store |microtask|.
553 {
554 StoreNoWriteBarrier(MachineType::PointerRepresentation(), ring_buffer,
555 CalculateRingBufferOffset(capacity, start, size),
556 BitcastTaggedToWord(microtask));
558 IntPtrConstant(MicrotaskQueue::kSizeOffset),
559 IntPtrAdd(size, IntPtrConstant(1)));
560 Return(UndefinedConstant());
561 }
562
563 // |microtask_queue| has no space to store |microtask|. Fall back to C++
564 // implementation to grow the buffer.
565 BIND(&if_grow);
566 {
567 TNode<ExternalReference> isolate_constant =
568 ExternalConstant(ExternalReference::isolate_address());
569 TNode<ExternalReference> function =
570 ExternalConstant(ExternalReference::call_enqueue_microtask_function());
571 CallCFunction(function, MachineType::AnyTagged(),
572 std::make_pair(MachineType::Pointer(), isolate_constant),
573 std::make_pair(MachineType::IntPtr(), microtask_queue),
574 std::make_pair(MachineType::AnyTagged(), microtask));
575 Return(UndefinedConstant());
576 }
577
578 Bind(&if_shutdown);
579 Return(UndefinedConstant());
580}
581
583 // Load the current context from the isolate.
584 TNode<Context> current_context = GetCurrentContext();
585
586 auto microtask_queue =
587 UncheckedParameter<RawPtrT>(Descriptor::kMicrotaskQueue);
588
589 Label loop(this), done(this);
590 Goto(&loop);
591 BIND(&loop);
592
593 TNode<IntPtrT> size = GetMicrotaskQueueSize(microtask_queue);
594
595 // Exit if the queue is empty.
596 GotoIf(WordEqual(size, IntPtrConstant(0)), &done);
597
598 TNode<RawPtrT> ring_buffer = GetMicrotaskRingBuffer(microtask_queue);
599 TNode<IntPtrT> capacity = GetMicrotaskQueueCapacity(microtask_queue);
600 TNode<IntPtrT> start = GetMicrotaskQueueStart(microtask_queue);
601
603 CalculateRingBufferOffset(capacity, start, IntPtrConstant(0));
604 TNode<RawPtrT> microtask_pointer = Load<RawPtrT>(ring_buffer, offset);
605 TNode<Microtask> microtask = CAST(BitcastWordToTagged(microtask_pointer));
606
607 TNode<IntPtrT> new_size = IntPtrSub(size, IntPtrConstant(1));
608 TNode<IntPtrT> new_start = WordAnd(IntPtrAdd(start, IntPtrConstant(1)),
609 IntPtrSub(capacity, IntPtrConstant(1)));
610
611 // Remove |microtask| from |ring_buffer| before running it, since its
612 // invocation may add another microtask into |ring_buffer|.
613 SetMicrotaskQueueSize(microtask_queue, new_size);
614 SetMicrotaskQueueStart(microtask_queue, new_start);
615
616 RunSingleMicrotask(current_context, microtask);
617 IncrementFinishedMicrotaskCount(microtask_queue);
618 Goto(&loop);
619
620 BIND(&done);
621 {
622 // Reset the "current microtask" on the isolate.
623 StoreRoot(RootIndex::kCurrentMicrotask, UndefinedConstant());
624 Return(UndefinedConstant());
625 }
626}
627
629
630} // namespace internal
631} // namespace v8
#define BIND(label)
#define TVARIABLE(...)
#define CSA_DCHECK(csa,...)
#define CSA_CHECK(csa, x)
#define TF_BUILTIN(Name, AssemblerBase)
TNode< T > LoadObjectField(TNode< HeapObject > object, int offset)
TNode< BoolT > TaggedIsNotSmi(TNode< MaybeObject > a)
TNode< RawPtrT > LoadExternalPointerFromObject(TNode< HeapObject > object, int offset, ExternalPointerTagRange tag_range)
TNode< BoolT > IsIsolatePromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate()
TNode< JSAny > Call(TNode< Context > context, TNode< TCallable > callable, ConvertReceiverMode mode, TNode< JSAny > receiver, TArgs... args)
void SetContinuationPreservedEmbedderData(TNode< Object > value)
TNode< Uint16T > LoadMapInstanceType(TNode< Map > map)
TNode< NativeContext > LoadNativeContext(TNode< Context > context)
TNode< T > Select(TNode< BoolT > condition, const NodeGenerator< T > &true_body, const NodeGenerator< T > &false_body, BranchHint branch_hint=BranchHint::kNone)
TNode< Map > LoadMap(TNode< HeapObject > object)
TNode< WordT > TimesSystemPointerSize(TNode< WordT > value)
static V8_EXPORT_PRIVATE ExternalReference isolate_address()
static ExternalReference Create(const SCTableReference &table_ref)
static const size_t kEnteredContextsOffset
Definition api.h:388
static constexpr MachineType Pointer()
static constexpr MachineType Int32()
static constexpr MachineType AnyTagged()
static constexpr MachineRepresentation PointerRepresentation()
static constexpr MachineType IntPtr()
void RunPromiseHook(Runtime::FunctionId id, TNode< Context > context, TNode< HeapObject > promise_or_capability, TNode< Uint32T > promiseHookFlags)
TNode< RawPtrT > GetMicrotaskQueue(TNode< Context > context)
void PrepareForContext(TNode< Context > microtask_context, Label *bailout)
TNode< RawPtrT > GetMicrotaskRingBuffer(TNode< RawPtrT > microtask_queue)
void RewindEnteredContext(TNode< IntPtrT > saved_entered_context_count)
MicrotaskQueueBuiltinsAssembler(compiler::CodeAssemblerState *state)
void RunSingleMicrotask(TNode< Context > current_context, TNode< Microtask > microtask)
TNode< IntPtrT > GetMicrotaskQueueCapacity(TNode< RawPtrT > microtask_queue)
void IncrementFinishedMicrotaskCount(TNode< RawPtrT > microtask_queue)
TNode< IntPtrT > CalculateRingBufferOffset(TNode< IntPtrT > capacity, TNode< IntPtrT > start, TNode< IntPtrT > index)
void SetMicrotaskQueueSize(TNode< RawPtrT > microtask_queue, TNode< IntPtrT > new_size)
TNode< IntPtrT > GetMicrotaskQueueSize(TNode< RawPtrT > microtask_queue)
TNode< IntPtrT > GetMicrotaskQueueStart(TNode< RawPtrT > microtask_queue)
void SetMicrotaskQueueStart(TNode< RawPtrT > microtask_queue, TNode< IntPtrT > new_start)
void RunAllPromiseHooks(PromiseHookType type, TNode< Context > context, TNode< HeapObject > promise_or_capability)
static const size_t kRingBufferOffset
static const size_t kSizeOffset
static const size_t kCapacityOffset
static const size_t kFinishedMicrotaskCountOffset
static const size_t kStartOffset
static TNode UncheckedCast(compiler::Node *node)
Definition tnode.h:413
TNode< IntPtrT > IntPtrAdd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< IntPtrT > IntPtrConstant(intptr_t value)
TNode< BoolT > WordEqual(TNode< WordT > left, TNode< WordT > right)
TNode< Object > LoadFullTagged(Node *base)
TNode< IntPtrT > BitcastTaggedToWord(TNode< Smi > node)
void StoreFullTaggedNoWriteBarrier(TNode< RawPtrT > base, TNode< Object > tagged_value)
void GotoIf(TNode< IntegralT > condition, Label *true_label, GotoHint goto_hint=GotoHint::kNone)
Node * Load(MachineType type, Node *base)
TNode< IntPtrT > WordAnd(TNode< IntPtrT > left, TNode< IntPtrT > right)
void Switch(Node *index, Label *default_label, const int32_t *case_values, Label **case_labels, size_t case_count)
TNode< IntPtrT > IntPtrSub(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< ExternalReference > ExternalConstant(ExternalReference address)
void StoreRoot(RootIndex root_index, TNode< Object > value)
Node * CallCFunction(Node *function, std::optional< MachineType > return_type, CArgs... cargs)
TNode< T > CallRuntime(Runtime::FunctionId function, TNode< Object > context, TArgs... args)
TNode< T > CallBuiltin(Builtin id, TNode< Object > context, TArgs... args)
void Branch(TNode< IntegralT > condition, Label *true_label, Label *false_label, BranchHint branch_hint=BranchHint::kNone)
void StoreNoWriteBarrier(MachineRepresentation rep, Node *base, Node *value)
#define CAST(x)
#define DEBUG_BOOL
Definition globals.h:87
int start
MicrotaskQueue * microtask_queue
Definition execution.cc:77
int32_t offset
MovableLabel handler
@ kNativeContextMicrotaskQueueTag
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
i::Address Load(i::Address address)
Definition unwinder.cc:19
PromiseHookType
Definition v8-promise.h:141
#define arraysize(array)
Definition macros.h:67