jdm mentioned that he's working on DOM bindings again, so I wanted to write down the things that we've run into as performance or usability gotchas in Gecko bindings so far.

Performance:

1) For interface types, one needs a very fast way to unwrap them to some sort of object you can call methods on. In Gecko this is done by ensuring that all the classes representing DOM prototypes for a particular object have the same pointer so you can reinterpret_cast between them (for example, the EventTarget*, Node*, Element*, HTMLElement*, and HTMLDivElement* for an HTML <div> all have the same value). Then that one pointer can be stored in the JS object, and all you have to check at runtime is that the the cast is safe.

What do we plan to do for the memory layout of DOM objects, and how do we plan to make it work with binding code?

2) For sequence in params for WebGL, you really want to stack-allocate the array for short arrays. Passing very short sequences for uniform*fv is common, and heap-allocation is expensive.

3) Strings are a major pain point. You want to be able to share strings between SpiderMonkey and your DOM stuff for return values. You also want some sort of JSString* cache, though this is not fundamental to the design and can be tacked on easily, I think. I know we have plans to sorta using JSString* internally kinda; the might be nice.

4) It helps a huge amount to be able to inline the implementation into the binding or at least make it a non-virtual function call. Virtual function calls are terrible not just because of the indirection but also because of fairly common cache misses on the vtable lookup.

Usability:

1) Ownership model (though at this point CC is getting more usable). In Gecko this is exacerbated by there being different models on main thread and in workers; let's please avoid that.

2) You want the same representation for arguments of both callback interfaces and natively implemented interfaces. Otherwise you get annoying impedance mismatches. We're working around those in Gecko with evil conversion operators, since you can do that in C++, but it's slightly suboptimal. The fact that we don't have to worry about ref vs pointer vs NonNull<T> in Rust will help here. But that doesn't necessarily help with the fallible/infallible array mess.

3) The combination of the two, where you can't necessarily use the same type for Node in both Node and sequence<Node> arguments because for the former you want to be fast while for the latter you have to keep the Nodes in the sequence alive.

4) Dictionary return arguments are a bit of a pain point. See https://bugzilla.mozilla.org/show_bug.cgi?id=817194

-Boris
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to