TryCatch implementation details as it relates to coroutines

37 views
Skip to first unread message

Michael Carter

unread,
Sep 12, 2010, 12:29:38 AM9/12/10
to v8-users
Hello,

I have been trying to implement coroutines in v8 based on Gary Hai's
work, js-coroutine ( http://code.google.com/p/js-coroutine/ ) which
uses libpcl to provide the coroutine support. This method seems to
work very well but for exceptions which cause segfaults.

I took a look at how exception handling is implemented in v8, and as
far as I can tell there is basically a stack of TryCatch objects
attached to a per-thread singleton. I believe this causes a problem
when more than one coroutine yields/enters a try/catch block within
the same thread.

For instance, consider coro1 which enters a try/catch block, then
yields to coro2 which subsequently enters a try/catch block and yields
back to coro1. Now, when an error is thrown in coro1, I believe that
it's the coro2 try/catch that actually is used to handle the error.

Incidentally, the Error constructor also seems to cause a segfault in
this instance. Perhaps it is related, but I haven't really
investigated that.

I am not particularly familiar with the v8 code base, but I want to
learn enough to solve this problem. I am incredibly excited about the
prospect of true coroutines in the JavaScript, and I feel like it's
really close. Any pointers or advice would be very helpful.

Thanks!

Michael Carter

malcolm handley

unread,
Sep 12, 2010, 1:21:28 AM9/12/10
to v8-u...@googlegroups.com
Are you determined to do this with a single thread? I had good results implementing a fiber API in with v8 where I used a separate pthread for each fiber. I assume that you could support continuations that way too.


Michael Carter

unread,
Sep 12, 2010, 2:02:26 AM9/12/10
to v8-u...@googlegroups.com
On Sat, Sep 11, 2010 at 10:21 PM, malcolm handley <malcolm...@gmail.com> wrote:
Are you determined to do this with a single thread? I had good results implementing a fiber API in with v8 where I used a separate pthread for each fiber. I assume that you could support continuations that way too.


Yes, I am determined to do this with a single thread; in fact, the main purpose of this exercise is to avoid the overhead of threads. Regardless, I appreciate the response.

Thanks,

Michael Carter
 

Peter Griess

unread,
Sep 13, 2010, 10:38:36 AM9/13/10
to v8-u...@googlegroups.com
Hey Michael,

I'm also interested in co-routines for V8 and was running into a very similar problem this weekend. I think the problem is that setjmp(2)/longjmp(2) does not properly integrate with V8's notion of what threads are. In fact, I've produced a small-ish test-case for this behavior http://gist.github.com/577360.

Running this results in the following output

starting v8 in callback ...
foo!


#
# Fatal error in src/api.h, line 384
# CHECK(blocks_.length() == 0) failed
#

Abort trap

From what I can tell, the problem is that the V8 runtime needs to be able to rely on implementations of v8::internal::Thread and v8::internal::ThreadHandle to provide correct thread local storage semantics. The test case that I posted above runs into assertion failures because the V8 execution on the alternate stack is still referencing the thread-local state from the first stack.

Can someone from the V8 team weigh in on this?

If one wishes to use setjmp(2) (and friends) or setcontext(2) (and friends), what needs to be done to coerce V8 into playing nicely with these foreign control flow semantics? It seems that alternate implementations of some combination of Thread and ThreadHandle (and others?) are needed.

Thanks,
Peter

--
Reply all
Reply to author
Forward
0 new messages