Currently bidi-state is updated when textfragment uses PRUnichars and its data is modified. That shows up in some profiles, and if we start to share string data with JS, we would be storing PRUnichars a lot more often. So, would be better to calculate bidi-state lazily.
Couldn't nsTextFragment::SetTo/Apend/CopyTo set the bidi flag by checking characters as we copy them to the buffer? That would avoid the extra pass over the data in SetBidiFlag, which should make the performance much better. By "share string data with JS", do you mean that all JS strings would be nsTextFragments? Or something else? Obviously we need to avoid having JS string operations twiddle bidi flags.
Right now we set the bidiflag only if we need to detect that we need to store string data as PRUnichar. So in common cases we don't set it. But sure, it might be faster to set it when copying the data in PRUnichar case. And no, I don't mean all JSStrings would be textfragments, but I mean the case when someone for example creates a textnode (createTextNode(str)). I'd like us to be able to share the str data with DOM. (I don't know yet at all how to do that.)
I think when you pass an AString from C++ to JS, we usually manage to share the characters. You can read about this in XPCStringConvert::ReadableToJSVal, in js/src/xpconnect/src/xpcstring.cpp. When passing a JS string to C++, say for a DOMString, ISTM we should be able to share that too, but according to the miles of code under "case nsXPTType::T_DOMSTRING:" in XPCConvert::JSData2Native(), in js/src/xpconnect/src/xpcstring.cpp, there are lots of cases and different XPCOM string types we might use. There's a whole extra implementation of this in xpcquickstubs.h/cpp, where it looks like for xpc_qsDOMStrings we create an nsDependentString (which sounds like it might always share). Now. What happens if we then do weird stuff to XPCOM strings on the C++ side? In what situations do we incur copies? I have no idea.
> When passing a JS string to C++ That's the situation for createTextNode. > we should be able to share that too Not in this case, because the textnode needs to be able to reference the text even after the call unwinds. Which means that as things stand it needs to copy it, since there are no guarantees of the buffer surviving unwind+gc.