TerminateExecution does not work unless there is a js stackframe.

21 views
Skip to first unread message

jmr

unread,
Jul 29, 2025, 3:42:04 AMJul 29
to v8-users
Hi,

I've got code as follows in js:

while (true) { native_sleep(1000); }

Effectively js keeps leaving and re-entering native code repeatedly without affecting it's own stack. I noticed that in a situation like this TerminateExecution simply does not work.

If I change my code to:

func js_sleep(arg) { native_sleep(arg); }
while (true) { js_sleep(1000); }

Then it works, but this adds an unnecessary js stackframe, which for a tight rendering loop might not be great.

Is there a way to propagate termination without an extra js frame somehow?
I.e., could the termination checks be done when entering/leaving native calls?
Can I somehow force the propagation to kick in once I'm leaving my native call?

Thanks.

Jakob Kummerow

unread,
Jul 29, 2025, 8:22:39 AMJul 29
to v8-u...@googlegroups.com
This an optimization: if a loop contains a call, it doesn't need to emit its own stack checks in order to support interrupt requests, because the callee will contain a stack check.
So you can add an interrupt check to your native code that you're calling.
It might be feasible to fix this on the V8 side by checking if the call's target is known to be a non-JS function... not sure.

(FWIW, the specific given example is a bit unconvincing: a "tight rendering loop" that "native_sleep(1000)"s all the time can certainly take the minuscule overhead of a function call.)


--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/v8-users/2c2b769d-d599-4493-a459-2f05da527cadn%40googlegroups.com.
Message has been deleted

jmr

unread,
Jul 30, 2025, 4:27:10 AMJul 30
to v8-users
How do I check in my own native code if termination is happening, and how do I throw the uncatchable error?
IsTerminating seems to return false on the exit of my native call, and yes, I can throw an error, but not one that cannot be caught 

Jakob Kummerow

unread,
Jul 30, 2025, 5:10:51 AMJul 30
to v8-u...@googlegroups.com
Looks like the API doesn't currently expose that functionality, you'd have to add it. Something like (untested):

// Returns true if a pending termination request was found and handled.
bool v8::Isolate::HandleTerminationRequests() {
  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
  StackLimitCheck check(i_isolate);
  if (check.InterruptRequested() &&
      i_isolate->stack_guard()->HasTerminationRequest()) {
    i_isolate->TerminateExecution();
    return true;
  }
  return false;
}

The return value is useful if your code is currently in the middle of an expensive operation (such as a loop) from which it can return early.

Or you can just use the extra function call on the JS side, that's certainly easier and probably fast enough (even for a tight rendering loop).


Reply all
Reply to author
Forward
0 new messages