Ejemplo n.º 1
0
void EventHook::onFunctionSuspendE(ActRec* suspending,
                                   const ActRec* resumableAR) {
  // When we're suspending an eagerly executing resumable, we've already
  // teleported the ActRec from suspending over to resumableAR, so we need to
  // make sure the unwinder knows not to touch the locals, $this, or
  // VarEnv/ExtraArgs.
  suspending->setThisOrClassAllowNull(nullptr);
  suspending->setLocalsDecRefd();
  suspending->setVarEnv(nullptr);

  try {
    ssize_t flags = CheckSurprise();
    onFunctionExit(resumableAR, nullptr, nullptr, flags);

    if ((flags & RequestInjectionData::AsyncEventHookFlag) &&
        resumableAR->func()->isAsyncFunction()) {
      assert(resumableAR->resumed());
      auto const afwh = frame_afwh(resumableAR);
      auto const session = AsioSession::Get();
      if (session->hasOnResumableCreateCallback()) {
        session->onResumableCreate(afwh, afwh->getChild());
      }
    }
  } catch (...) {
    auto const resumableObj = [&]() -> ObjectData* {
      if (resumableAR->func()->isAsyncFunction()) {
        return frame_afwh(resumableAR);
      }
      assert(resumableAR->func()->isGenerator());
      return frame_base_generator(resumableAR);
    }();
    decRefObj(resumableObj);
    throw;
  }
}
Ejemplo n.º 2
0
void EventHook::onFunctionSuspend(const ActRec* ar, bool suspendingResumed) {
  // TODO(#2329497) can't CheckSurprise() yet, unwinder frees suspended locals
  ssize_t flags = GetConditionFlags();
  onFunctionExit(ar, nullptr, nullptr, flags);

  // Async profiler
  if ((flags & RequestInjectionData::AsyncEventHookFlag) &&
      ar->func()->isAsyncFunction()) {
    assert(ar->resumed());
    auto afwh = frame_afwh(ar);
    auto session = AsioSession::Get();
    // Blocking await @ eager execution => AsyncFunctionWaitHandle created.
    if (!suspendingResumed && session->hasOnResumableCreateCallback()) {
      session->onResumableCreate(afwh, afwh->getChild());
    }
    // Blocking await @ resumed execution => AsyncFunctionWaitHandle awaiting.
    if (suspendingResumed && session->hasOnResumableAwaitCallback()) {
      session->onResumableAwait(afwh, afwh->getChild());
    }
  }
}