Closed Bug 1008339 Opened 10 years ago Closed 10 years ago

prototype-based inheritance : calling derived method in constructor erases properties

Categories

(Core :: JavaScript Engine, defect)

29 Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla32

People

(Reporter: gruikmusic, Assigned: bhackett1024)

References

Details

(Keywords: regression, testcase)

Attachments

(2 files)

Attached file ff29-bug-demo.html
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36

Steps to reproduce:

Hi,

This weird bug appeared just when FF29 came out ; I first submitted the problem to prototype.js ( https://github.com/sstephenson/prototype/issues/195 ) because this happened by using prototype.js object API, but someone there gave me a code showing it happens without using prototype.js.

The conditions to trigger the bug are very particular : we need a derived method called in the parent constructor that adds properties, that method in the parent class needs to add properties too (even if the parent method is not called), and we need to instantiate another subclass of the parent class before the one showing the case.

In the demo I log stuff in a textarea because with the demo i made using prototype.js, the bug didn't occur if firebug or developer console was opened.

The way to implement inheritance is the old way (like here http://phrogz.net/JS/classes/OOPinJS2.html ) : setting "prototype" property of child constructors to a new instance of the parent class (except we use an intermediate "empty" constructor to avoid executing the parent constructor code on instantiating children prototype ; but the bug happens too if we instantiate Parent directly).
If we use Object.create(), it works fine.




Actual results:

log :


ChildB ctor
Parent ctor
Parent.meth1()
data3 before : undefined
Parent.meth2()
data3 after : undefined

ChildA ctor
Parent ctor
ChildA.meth1()
data3 before : z
ChildA.meth2()
data3 after : undefined



Expected results:

log :


ChildB ctor
Parent ctor
Parent.meth1()
data3 before : undefined
Parent.meth2()
data3 after : undefined

ChildA ctor
Parent ctor
ChildA.meth1()
data3 before : z
ChildA.meth2()
data3 after : z
I messed up in explaining the requirement to fulfill, well read the code to see all the requirements
This reproduces on 32 on OS X as well, and seems to work in V8. Over to the JS engine...
Status: UNCONFIRMED → NEW
Component: Untriaged → JavaScript Engine
Ever confirmed: true
OS: Windows 7 → All
Product: Firefox → Core
Hardware: x86_64 → All
Attached patch patchSplinter Review
Thanks for the great test case!  This predates bug 936156, actually.  The problem is that we thought that data4 was a property that ChildA objects definitely have and added it at the object's creation point, but when ChildA.meth1 was called first we didn't properly invalidate that information and ended up inadvertently erasing the data3 property when the definite property information was invalidated at the call to ChildA.meth2.
Assignee: nobody → bhackett1024
Attachment #8420591 - Flags: review?(jdemooij)
Comment on attachment 8420591 [details] [diff] [review]
patch

Review of attachment 8420591 [details] [diff] [review]:
-----------------------------------------------------------------

r=me with comments below addressed.

::: js/src/jit-test/tests/basic/bug1008339.js
@@ +1,2 @@
> +
> +function Parent() {

Shouldn't the test have some assertEq's in them? Please make sure it fails without the patch.

::: js/src/jit/IonBuilder.cpp
@@ +4194,5 @@
>          return false;
>  
> +    // Don't inline polymorphic sites during the definite properties analysis.
> +    // AddClearDefiniteFunctionUsesInScript depends on this for correctness.
> +    if (info().executionMode() == DefinitePropertiesAnalysis && targets.length() > 0)

targets.length() > 1
Attachment #8420591 - Flags: review?(jdemooij) → review+
(In reply to Jan de Mooij [:jandem] from comment #5)
> ::: js/src/jit-test/tests/basic/bug1008339.js
> @@ +1,2 @@
> > +
> > +function Parent() {
> 
> Shouldn't the test have some assertEq's in them? Please make sure it fails
> without the patch.

We actually busted on this test with an assert in debug builds, when we noticed we were erasing a property that didn't have an undefined value.
this appears to have caused a 9.7% regression (32034->28933)  on Octane-DeltaBlue on machine 11 on AWFY.

Regression range from AEFY : http://hg.mozilla.org/integration/mozilla-inbound/pushloghtml?fromchange=4e1e052624c2&tochange=14450e205899
https://hg.mozilla.org/mozilla-central/rev/582e943a30a5
Status: NEW → RESOLVED
Closed: 10 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla32
Depends on: 1009899
(In reply to mayankleoboy1 from comment #8)
> this appears to have caused a 9.7% regression (32034->28933)  on
> Octane-DeltaBlue on machine 11 on AWFY.
> 
> Regression range from AEFY :
> http://hg.mozilla.org/integration/mozilla-inbound/
> pushloghtml?fromchange=4e1e052624c2&tochange=14450e205899

Thanks!  I filed bug 1009899 for the regression.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: