Aaron Leventhal wrote:
Why do our interfaces allow for multiple presshells?

I think dbaron handled this already.

Also, correct me if I'm wrong, but we basically have a 1 to 1 relationship between these objects: docshell, presshell, prescontext, document, domwindow, widget, docshell and contentviewer

You're wrong.  :)

There's a 1-1 relationship between docshell and docshell, sure. There is a 1-1 relationship between docshell and outer domwindow. There is a 1-1 relationship between presshell and prescontext, except during setup and teardown.

There is a 1-1 relationship between inner domwindow and document, except that some documents don't have inner domwindows (though we might change that) and that some inner domwindows might no longer have documents even though they are still alive.

There is a 1-many relationship between outer domwindows and inner domwindows, in general, though one can only get at the "current" inner domwindow from the outer domwindow.

There is a 1-1 relationship between content viewer and presshell, except a document viewer may not have a presshell, and which exact presshell it has can change at any time.

There is a 1-1 relationship between document and content viewer, except some documents may not have content viewers.

There is a 1-many relationship between docshell and content viewer in general. The only time many > 1 is during paint suppression.

I don't know how widgets got in here. We have all sorts of widgets not related to any of this stuff. As far as docshells go, each docshell has a widget inside it and many docshells have a widget immediately outside them. This state of affairs is not expected to persist into Gecko 1.9 -- by that point there will hopefully be a single widget for the root docshell in the docshell hierarchy and that's it.

These are created for elements such as:
<browser>, <iframe>, <frame>, <editor>, etc.

And <object>, yeah.

Correct or no? Do we have docs on how this works including the ownership model? What changes are planned for the future?

We do not have good docs, no. At some point I tried setting up an ownership model map of "document and window level objects" while trying to review bfcache. I'll paste it in at the end of the mail. It's probably pretty out of date, being about 16 months old, especially with splitwindow happening in between. And I don't think I ever completed it... For example, the nsDocumentViewer [art is empty. But I actually think it was out of date within a month or two of me creating it... which is the usual problem with trying to document this stuff. :( That said, if someone wants to document this, it's a start.

As for changes, I think I mentioned a few above. I also still think we should merge presshell and prescontext into a single class. I believe roc wants to eliminate view manager altogether. Past that, I think we should think about how we can simplify this mess.

-Boris

---------------------------------------------------------------------------------
Ownership model (out of date):

Key:
+: strong ref
-: weak ref raw ptr
=: nsWeakPtr ref
*: owner (new/delete)
#: non-pointer member

Refcounted objects have a '|' before the object name in the list.  In general,
any weak ref held by a refcounted object that is not explicitly cleared is a
crash waiting to happen.

Note that this list does not include parent/child pointers amongst documents,
docshells, viewmanagers, etc.

I've left out a lot of things that are in a 1-1 relationship with just the
document (and which correctly drop weak refs when it goes away) for clarity.

------------------------------------------------------------
Long-lived objects (across document loads):
------------------------------------------------------------

|nsWebShell:
  +nsLoadGroup -- mLoadGroup (set in nsDocLoader::Init, never cleared)
+DocumentViewerImpl -- mContentViewer (set in nsDocShell::SetupNewViewer [via Embed],
     released in nsDocShell::Destroy)
  +nsDeviceContext -- mDeviceContext (set in nsDocShellEnsureDeviceContext,
     cleared in SetParentWidget [called via nsIBaseWindow setup stuff])
     XXX this should clear any time mParentWidget changes!  But device contexts
     are refcounted, so we still have problems.  Basically, the device context
     needs to hold a strong ref to the widget it's created for or something
     like that.  Changes to the parent widget here should wipe all
     presentations, I guess....
  +nsGlobalWindow -- mScriptGlobal (set in nsDocShell::EnsureScriptEnvironment,
     released in nsDocShell::Destroy).  XXX fix ordering dependency with
     SetChromeEventHandler here, somehow!
  +nsGlobalWindow -- via mSecurityUI (set and cleared via scriptable interface)
  +nsCommandManager -- mCommandManager (not the same one as in nsHTMLDocument,
     set in EnsureCommandManager, released in ~nsWebShell)

|nsGlobalWindow:
  +nsDocument -- mDocument (set in SetNewDocument, released in SetNewDocument
     and ~nsGlobalWindow)
  +nsGlobalWindow -- strong ref to self via mScriptContext.  (Set when the
     script context is created, cleared in SetDocShell, ReallyCloseWindow.)
  -nsWebShell -- mGlobalObjectOwner (set and cleared in SetGlobalObjectOwner
     [via nsDocShell::EnsureScriptEnvironment and
          nsDocShell::Destroy respectively])
  -nsWebShell -- mDocShell (set and cleared in SetDocShell
     [via nsDocShell::EnsureScriptEnvironment and
          nsDocShell::Destroy respectively])
     XXXbz why not just QI this off mGlobalObjectOwner?

|nsCommandManager:
  -nsGlobalWindow -- mWindow (set in Init, never cleared; XXX this is buggy)

|nsLoadGroup:
  =nsWebShell (in our case) -- mCallbacks (set in SetNotificationCallbacks)
  =nsWebShell/nsDocLoader -- mObserver (set in SetGroupObserver)

------------------------------------------------------------
Per-document objects:
------------------------------------------------------------
|nsDocument:
  =nsLoadGroup -- mDocumentLoadGroup (set in ResetToURI, never cleared)
  =nsWebShell -- mDocumentContainer (set in SetContainer
     [via nsDocShell::CreateAboutBlankContentViewer or
          DocumentViewerImpl::SetDOMDocument],
     never cleared)
  -PresShell -- mPresShells (set in nsDocument::doCreateShell,
     cleared in DeleteShell [via PresShell::Destroy]
  +nsGlobalWindow -- mScriptGlobalObject (set and released in
     SetScriptGlobalObject)
  -PresShell -- mObservers (cleared via PresShell::EndObservingDocument,
     mostly called from content viewer code, right before calling
     PresShell::Destroy; XXX maybe just call it from PresShell::Destroy?)

|nsHTMLDocument (additional to nsDocument):
  +nsParser -- mParser (set in StartDocumentLoad, released in EndLoad)
  +nsCommandManager -- mMidasCommandManager (set in GetMidasCommandManager,
      released in ~nsHTMLDocument)

|nsXMLDocument (additional to nsDocument):
  +nsGlobalWindow -- via mScriptContext (set in Load, never released, 
effectively)

|nsContentSink:
  +nsDocument -- mDocument (set in Init, released in ~nsContentSink)
  +nsParser -- mParser (set in SetParser [via nsParser::SetContentSink],
     released in DidBuildModel
  +nsWebShell -- mDocShell (set in Init, released in ~nsContentSink)


|nsXULContentSink:
  =nsDocument -- mDocument (set in Init, cleared in DidBuildModel)
  +nsParser -- mParser (set in SetParser [via nsParser::SetContentSink],
     released in DidBuildModel)

|nsParser:
  +nsContentSink/nsXULContentSink -- mSink (set in SetContentSink,
     released in ~nsParser)

------------------------------------------------------------
Mutant not really per-presentation, but sorta objects:
------------------------------------------------------------

|nsDocumentViewer:

|nsDocViewerSelectionListener:
  -DocumentViewerImpl -- mDocViewer (set in Init, never cleared XXX this can
       lead to crashes)

------------------------------------------------------------
Per-presentation objects:
------------------------------------------------------------

|PresShell:
  +nsDocument -- mDocument (set in Init, released ~PresShell)
  +nsPresContext -- mPresContext (set in Init, released ~PresShell)
  *nsStyleSet -- mStyleSet (set in Init, deleted in ~PresShell)
*nsCSSFrameConstructor -- mFrameConstructor (created in Init, deleted in ~PresShell)
  -nsViewManager -- mViewManager (set in Init, cleared in Destroy)
  +nsSelection -- mSelection set in Init, released ~PresShell)
  #nsFrameManager -- mFrameManager
  // XXXbz there are some weird comments at the top of nsIPresShell about
  ownership; sort them out.
  // XXXnote: let jwatt know how this pans out

|nsSelection:
  -PresShell -- mShell (set in Init, never cleared XXX this is buggy)

|nsPresContext:
  // XXXbz this isn't done yet
  -PresShell -- mPresShell (set in , cleared in )
  +nsDeviceContext -- mDeviceContext (set in , cleared in )
  -nsWebShell -- mLinkHandler (set in SetLinkHandler by document viewer,
                               cleared in same)  XXXbz finish this
  =nsWebShell -- mContainer (set in SetContainer by document viewer) XXXbz 
finish

|nsEventStateManager:
  -nsPresContext -- mPresContext (set and cleared in SetPresContext
     [via nsPresContext::Init and ~nsPresContext respectively]
     XXX this is refcounted, so can outlive the prescontext, but doesn't seem
     to deal so well (never null-checks it, e.g.)
  +nsDocument -- mDocument (set in EnsureDocument, sorta ad-hoc,
     released in ~nsEventStateManager).
     XXX it's not clear to me why we have a member here...  And
     EnsureDocument() doesn't ensure anything if the prescontext is null.  Fix
     things here.

nsStyleSet:
  -nsPresContext -- mRoot->mPresContext (set in Init, cleared in Shutdown)

nsCSSFrameConstructor:
  -nsDocument -- mDocument (set in constructor, never cleared)
  -PresShell -- mPresShell (set in constructor, never cleared)

|nsViewManager:
  -PresShell -- mViewObserver (set in SetViewObserver [via PresShell::Init],
                               cleared in ~nsViewManager and in
                                          SetViewObserver [via 
PresShell::Destroy])
  -nsDeviceContext -- mContext (set in Init, cleared in ~nsViewManager)
    // XXXbz the comments here seem wrong.  The device context doesn't hold a
    // ref to us.  Perhaps this should be a strong ref?

nsFrameManager:
  -PresShell -- mPresShell (set in Init, cleared in Destroy)
  -nsStyleSet -- mStyleSet (set in Init, never cleared XXX this is wrong)
  XXX do we even need an mStyleSet?  Why not use mPresShell->StyleSet() ?
  -nsPresContext -- via mRootFrame (set in SetRootFrame, cleared in Destroy)
  -nsPresContext -- via mUndisplayedMap (cleared in Destroy)

------------------------------------------------------------
Unknown lifetime:
------------------------------------------------------------

|nsDeviceContext:
   Seems to have no members we care about here
_______________________________________________
dev-tech-layout mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-layout

Reply via email to