Bug 708805 - Add write barrier to JSFunction::env (r=bhackett)
authorBill McCloskey <wmccloskey@mozilla.com>
Thu, 15 Dec 2011 09:41:04 -0800
changeset 84315 3a190f6b9ee3b93e42f2bbbed0385d3e72295b73
parent 84314 1deb23332fb5b82db1c17d8c55f3466a7a5edc05
child 84316 fdc3f397377a565c03bc31b89011655828014cb3
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs708805
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 708805 - Add write barrier to JSFunction::env (r=bhackett)
js/src/jit-test/tests/basic/bug708805.js
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsfuninlines.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug708805.js
@@ -0,0 +1,4 @@
+gczeal(4);
+test();
+function test()
+eval("with({}) let(x=[])(function(){#2=x})()");
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2158,17 +2158,17 @@ js_NewFunction(JSContext *cx, JSObject *
     fun = static_cast<JSFunction *>(funobj);
 
     /* Initialize all function members. */
     fun->nargs = uint16(nargs);
     fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK);
     if ((flags & JSFUN_KINDMASK) >= JSFUN_INTERPRETED) {
         JS_ASSERT(!native);
         fun->script().init(NULL);
-        fun->setEnvironment(parent);
+        fun->initEnvironment(parent);
     } else {
         fun->u.n.clasp = NULL;
         fun->u.n.native = native;
         JS_ASSERT(fun->u.n.native);
     }
     if (kind == JSFunction::ExtendedFinalizeKind) {
         fun->flags |= JSFUN_EXTENDED;
         fun->initializeExtended();
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -111,18 +111,19 @@ struct JSFunction : public JSObject
     union U {
         struct Native {
             js::Native  native;   /* native method pointer or null */
             js::Class   *clasp;   /* class of objects constructed
                                      by this function */
         } n;
         struct Scripted {
             JSScript    *script_; /* interpreted bytecode descriptor or null;
-                                     use the setter! */
-            JSObject    *env;     /* environment for new activations */
+                                     use the accessor! */
+            JSObject    *env_;    /* environment for new activations;
+                                     use the accessor! */
         } i;
         void            *nativeOrScript;
     } u;
     JSAtom          *atom;        /* name for diagnostics and decompiling */
 
     bool optimizedClosure()  const { return kind() > JSFUN_INTERPRETED; }
     bool isInterpreted()     const { return kind() >= JSFUN_INTERPRETED; }
     bool isNative()          const { return !isInterpreted(); }
@@ -162,18 +163,19 @@ struct JSFunction : public JSObject
     }
 
     /*
      * For an interpreted function, accessors for the initial scope object of
      * activations (stack frames) of the function.
      */
     inline JSObject *environment() const;
     inline void setEnvironment(JSObject *obj);
+    inline void initEnvironment(JSObject *obj);
 
-    static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env); }
+    static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
 
     inline void setJoinable();
 
     js::HeapPtrScript &script() const {
         JS_ASSERT(isInterpreted());
         return *(js::HeapPtrScript *)&u.i.script_;
     }
 
--- a/js/src/jsfuninlines.h
+++ b/js/src/jsfuninlines.h
@@ -50,24 +50,31 @@ JSFunction::inStrictMode() const
 {
     return script()->strictModeCode;
 }
 
 inline JSObject *
 JSFunction::environment() const
 {
     JS_ASSERT(isInterpreted());
-    return u.i.env;
+    return u.i.env_;
 }
 
 inline void
 JSFunction::setEnvironment(JSObject *obj)
 {
     JS_ASSERT(isInterpreted());
-    u.i.env = obj;
+    *(js::HeapPtrObject *)&u.i.env_ = obj;
+}
+
+inline void
+JSFunction::initEnvironment(JSObject *obj)
+{
+    JS_ASSERT(isInterpreted());
+    ((js::HeapPtrObject *)&u.i.env_)->init(obj);
 }
 
 inline void
 JSFunction::initializeExtended()
 {
     JS_ASSERT(isExtended());
 
     JS_ASSERT(js::ArrayLength(toExtended()->extendedSlots) == 2);