On 2/13/13 10:06 PM, Boris Zbarsky wrote:
That sounds like it should be fast enough, yes. We should verify that
it actually is in practice. Which to me suggests that the scheduler
rewrite is a higher priority than, say, floats. At least if they're
both gated on brson. ;) Do we have any ETA on the scheduler rewrite?
Currently, floats aren't really on our priority list; we want them to be
done, but other things are higher priority. For example, the scheduler
rewrite. :)
The current status of the rewrite is that the scheduler thread (which is
the I/O thread in the new design) is starting up tasks, but
communication and I/O does not work. I/O is important to get right,
since a major impetus for the creation of the new scheduler is to avoid
having separate event loops for I/O and scheduling. The two event loops
proved to be a big performance problem for I/O (see the threads on
rust-dev if you're curious).
I plan to write up my thoughts more on the wiki tomorrow, but I am
currently leaning toward not using copy-on-write and instead just having
the DOM objects' contents be immutable while layout is running.
Hmm. This loses us a lot of the "quickly return to the event loop and
page script" benefit we're ideally aiming for, I think. It also makes
doing any sort of speculative layout much more problematic, right?
>
Why the change of heart here? Or should I just wait for your writeup on
the wiki which will cover that?
So as I write this I realize there is a hybrid solution (#3 below) that
we could possibly employ.
The current/old COW scheme uses "handles". In this scheme, if script
modifies a DOM object while layout is running, the memory looks like this:
[ JSObject ] -> [ Handle ]
/ \
[ Script Object ] [ Layout Object ]
This has the problem that there are two allocations (one for the handle)
and two levels of indirection for each property access. Moreover, these
costs are paid even in the sequential case, when layout is not running:
[ JSObject ] -> [ Handle ]
\ /
[ DOM Object ]
Compare this to Gecko/WebKit, where the memory simply looks like this:
[ JSObject ] -> [ DOM Object ]
In Gecko/WebKit we have just one allocation and one level of
indirection. So ideally we would like Servo to have this property as
well. The obvious problem is what to do when script modifies the DOM
while layout is running. There are a number of strategies we can choose:
(1) Have script block on layout whenever it tries to modify the DOM
while layout is running. While it's blocking try to do *something*
useful like GC. This can cause jank, however.
(2) Have script append its modification to a journal if layout is
running. (If layout is not running, the change is committed directly.)
Script then checks the log when doing a get if layout is running. When
layout completes, commit all the actions in the journal to the DOM. The
advantage to this is that sets while layout is running are very fast
(just add to a buffer). The disadvantage is that gets are slow, unless
we do something really fancy. (There is an interesting analogy to log
structured filesystems and databases here.)
(3) Have script copy the DOM node and store a pointer to the new node in
the header of the DOM object.
Layout Object Script Object
+-------------------+ +-----------+
[ JSObject ] -> | Script Object Ptr | -> | fields... |
+-------------------+ \/\/\/\/\/\/\
| fields... |
\/\/\/\/\/\/\/\/\/\/\
Whenever script does a get, if layout is running, it follows the script
object pointer to find the object it should be looking at. When script
does a set, it copies the DOM node, sets the script object pointer, and
then modifies the copy. Layout never looks at the script object pointer.
When layout completes, the layout objects are discarded and the script
objects become the new layout objects. This has the advantage that gets
are fast; the only overhead is one extra load (to follow the script
object pointer). The disadvantage is that sets are slow, because they
involve copying the DOM node and allocation.
I am leaning toward (3) now.
I think we should just ignore the fact that Rust cannot currently
inherit traits from structs for now
OK. How temporary is "for now"?
Niko and I have a proposal and we can bring it up at the next Rust
meeting on Tuesday.
and implement the DOM object methods
that have to be virtual using unsafe Rust code.
You mean non-virtual, right?
I mean virtual. Right now virtual in Rust is all-or-nothing; all your
methods are virtual or none are. As I understand things, however, the
DOM needs a finer-grained approach, in which some methods are virtual,
some methods are nonvirtual, and some fields can be accessed at known
offsets. So for now we can use structs that Rust already provides, which
provide both nonvirtual methods and fields at known offsets out of the
box, and then craft vtables out of unsafe code for the DOM methods that
absolutely have to be virtual. (Which may be no methods at all, at least
for this initial work. You can always simulate simple stuff like tagName
with a switch over instanceof self.)
How is this not virtual dispatch? I feel like I'm missing something,
but I can't tell whether it's my lack of Rust knowledge or something else.
It is virtual dispatch, but it'd be only for the methods that *need* to
be virtual. Fields like "firstChild", as well as methods like
appendChild(), would be nonvirtual under this scheme.
The endgame I would like to see for our DOM representation is that the
DOM impl can write some sort of (presumably very simple) firstChild
getter in safe Rust code and the binding can be generated in such a way
that the compiler will inline the getter into the binding when all is
said and done.
I see no obstacles to doing this.
That seems ok for basic performance sanity testing, sure. Not so great
for actual implementation.
Right.
Do we have any ETA on inheritance of traits from structs? This also
seems like a higher priority than floats.
I don't have one at the moment, but I'll bring it up at the meeting, as
I mentioned. I don't *think* it will be hard to implement at least the
parts we'll need in Rust, but the trait code is some of the hairiest
parts of the compiler, so there might be something unforeseen that would
come up. Might be doable in a day or two though. We'll see.
This, too seems like a higher priority than floats. ;)
We're treating it as such.
Patrick
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo