Closed Bug 455853 Opened 16 years ago Closed 16 years ago

Javascript: User defined properties disappear after 3 to 10 seconds from nodes that are added to a DOM document that is created using document.implementation.createDocument()

Categories

(Core :: DOM: Core & HTML, defect, P1)

x86
Windows Vista
defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: lukevanin, Assigned: smaug)

References

()

Details

(Keywords: regression)

Attachments

(3 files, 1 obsolete file)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 This is an error with the DOM in JavaScript - possibly due to the garbage collector collecting variables that are still in scope. When using a user-defined property on a node that belongs to a DOM document, the user-defined property becomes undefined without reason or explanation. The error seems to be time-related because the property which is defined for a few seconds later becomes undefined. In my tests the property becomes undefined typically after 3 to 10 seconds, although it may take longer. The DOM document mentioned here is one created using document.implementation.createDocument( "", "", null ); Please see the "Steps to Reproduce", "Additional Information", and "URL" for example scripts to re-create the error. Reproducible: Always Steps to Reproduce: 1. A DOM document is created using document.implementation.createDocument( "", "", null) (call this MyDom) 2. A node is created (call this MyDocument), and added to the DOM document with MyDom.appendChild( MyDocument) 3. A node is created using document.createElement( "B" ) or MyDoc.createElement( "B" ) (call this MyNode) 4. A user defined property is added to the node from step 3 (MyNode) 5. The node from step 3 (MyNode) is added to the node from step 2 (MyDocument) 6. After an arbitrary time interval (3 to 10 seconds on my browser) the user defined property becomes undefined Actual Results: For the first few seconds of the script's lifetime the user-defined property exists (that is, it is defined). After 3 to 10 seconds the property becomes undefined. Expected Results: The property should stay defined as long as there is a variable that holds a reference to it (in this case, the containing node). I have created a sample script (written in JavaScript) to reproduce the error. Copy and paste the code below into an HTML file. Click the "test" button when the page has loaded. Clicking the button will run code which will check if a specific user-defined property exists on a node created using the above-mentioned techniques. For the first few seconds clicking the button yields the result "property exists: true", indicating that the user-defined property does exist. After 3 to 10 seconds, clicking the button yields the result "property exists: false" indicating that the user-defined property no longer exists. [-----SNIP-----] <script language="javascript"> // var doc = document.implementation.createDocument( "", "", null ); var lib = doc.createElement( 'nodes' ); doc.appendChild( lib ); function MakeNode() { var node = document.createElement( 'b' ); node.extendedElement = true; doc.importNode( node, true ); lib.appendChild( node ); } MakeNode(); // function TestCode() { // var n = lib.firstChild; alert( 'property exists: ' + ( n.extendedElement != undefined ) ); } </script> <input type="button" onClick="TestCode();" value="test" /> [-----SNIP-----]
Did a few attempts to find a regression range but the script failed in older builds with an error.
Assignee: nobody → general
Component: General → JavaScript Engine
Product: Firefox → Core
QA Contact: general → general
Version: unspecified → Trunk
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: blocking1.9.1?
most bugs seem to come from vista related programs.
Assignee: general → nobody
Component: JavaScript Engine → DOM: Core & HTML
QA Contact: general → general
Probably related to the importNode call.
Wow I didn't expect such a quick response. This is awesome! Peter: I don't think it is the importNode() call. Although importNode() would remove the user-defined properties I only included it here for 'correctness'. The script still seems to execute without the call, although the bug still appears. I have uploaded another test script (sans the importNode() call) to http://www.aliotech.com/lab/javascript/v0.09/test-gc-3.html
(In reply to comment #1) > Did a few attempts to find a regression range but the script failed in older > builds with an error. What I meant to say is that this bug is a regression but that the date is unclear because of that wrong document error being thrown.
Keywords: regression
Need real regression range, assuming this is a regression. I would suspect this never worked, since there is no script global object on the document, but it might be a cycle collection regression.
Keywords: qawanted
Slightly smaller test case: <script language="javascript"> var doc = document.implementation.createDocument("", "", null); var root = doc.createElement('nodes'); doc.appendChild(root); root.expando = "ok"; root = null; </script> <input type=button onclick="alert(doc.documentElement.expando || 'gone')" value="test">
Assignee: nobody → Olli.Pettay
Attached patch possible fix (obsolete) — Splinter Review
Check the existence of script object.
Attachment #339607 - Flags: superreview?(peterv)
Attachment #339607 - Flags: review?(peterv)
Attachment #339607 - Flags: superreview?(peterv)
Attachment #339607 - Flags: superreview+
Attachment #339607 - Flags: review?(peterv)
Attachment #339607 - Flags: review+
This seemed to cause leaks on some (but not all) tboxes. I think the problem might be that document doesn't traverse references. Trying to write a reliable testcase for that.
Or perhaps the reason is that globalobject can't access the wrappers created for data documents. ...still trying to find what is causing the leaks and ensuring that backing out the patch did actually fix the problem.
Attached patch proposed patchSplinter Review
This way I don't get any document/element/attr leaks when running mochitest.
Attachment #339607 - Attachment is obsolete: true
Attachment #340163 - Flags: superreview?(peterv)
Attachment #340163 - Flags: review?(peterv)
Attached patch or this oneSplinter Review
This might be better still. Document doesn't own the keys of mContentWrapperHash (== content nodes), only the wrappers, so I think there might be cases when the cycle doesn't contain document. If content node can inform about the wrapper, and even unlink it, the cycle can be broken down before unlinking/destroying the document.
Attachment #340170 - Flags: superreview?(peterv)
Attachment #340170 - Flags: review?(peterv)
Not blocking on this, but it'd be awesome to get one of the patches here reviewed and checked in!
Flags: wanted1.9.1+
Flags: blocking1.9.1?
Flags: blocking1.9.1-
Priority: -- → P1
Comment on attachment 340170 [details] [diff] [review] or this one >@@ -1287,16 +1299,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( > tmp->mRadioGroups.Enumerate(RadioGroupsTraverser, &cb); > > // The boxobject for an element will only exist as long as it's in the > // document, so we'll traverse the table here instead of from the element. > if (tmp->mBoxObjectTable) { > tmp->mBoxObjectTable->EnumerateRead(BoxObjectTraverser, &cb); > } > >+ if (tmp->mContentWrapperHash) { >+ tmp->mContentWrapperHash->EnumerateRead(ContentWrapperTraverser, &cb); >+ } These references are already traversed from nodes, so I think this would result in them being traversed twice. The advantage of traversing from the node is that if there is nothing referencing the node or the wrapper it can get cycle collected before the document is. > nsDocument::AddReference(void *aKey, nsISupports *aReference) > { >- if (mScriptGlobalObject) { >+ PRBool dummy; >+ nsIScriptGlobalObject* scriptObject = GetScriptHandlingObject(dummy); >+ if (scriptObject) { Not sure why there is a scriptObject check needed at all? If it was just to prevent leaks the cycle collector should take care of that now.
(In reply to comment #16) > These references are already traversed from nodes, so I think this would result > in them being traversed twice. Yes, that is a small problem. Could be fixed so that traverse from nodes only when not bound to document. > The advantage of traversing from the node is > that if there is nothing referencing the node or the wrapper it can get cycle > collected before the document is. That is the change which fixes the leak I saw when checked in the original patch. Document owns all the references, but it can't traverse all them via childNodes, because there can be disconnected subtrees. > Not sure why there is a scriptObject check needed at all? If it was just to > prevent leaks the cycle collector should take care of that now. Well, possibly not needed. It was added when CC landed.
Attachment #340163 - Flags: superreview?(peterv)
Attachment #340163 - Flags: review?(peterv)
(In reply to comment #17) > Yes, that is a small problem. Could be fixed so that traverse from > nodes only when not bound to document. Bah, doesn't quite work. Way too late here.
Attachment #340170 - Flags: superreview?(peterv)
Attachment #340170 - Flags: review?(peterv)
This should be fixed now by some peterv's patch, IIRC.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → WORKSFORME
Issue is Resolved - removing QA-Wanted Keywords - QA-Wanted query clean-up task
Keywords: qawanted
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: