Merge m-c to b-i
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 04 Jan 2015 15:20:43 -0800
changeset 247805 eece95bdb7d1e53c93c7c7be016fd977f3b216ba
parent 247804 da38656aa089ca21db0acfbea59b44a8585426a0 (current diff)
parent 247788 636498d041b548b37c8b30b27d702852fb0064de (diff)
child 247806 bed9ea907821c7553764dd7e3869a7469d49a5eb
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone37.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
Merge m-c to b-i
--- a/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json
+++ b/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json
@@ -1,4 +1,8 @@
 {
+  "WeakMap.prototype.clear.length": true,
+  "WeakMap.prototype.delete.length": true,
   "WeakMap.prototype.get.length": true,
-  "WeakMap.prototype.get: return undefined": true
+  "WeakMap.prototype.get: return undefined": true,
+  "WeakMap.prototype.has.length": true,
+  "WeakMap.prototype.set.length": true
 }
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -926,17 +926,17 @@ imgRequest::OnDataAvailable(nsIRequest *
       // Notify listeners that we have an image.
       nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
       progressTracker->OnImageAvailable();
 
       if (mImage->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
         // We allow multipart images to fail to initialize without cancelling the
         // load because subsequent images might be fine; thus only single part
         // images end up here.
-        this->Cancel(NS_ERROR_FAILURE);
+        this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
         return NS_BINDING_ABORTED;
       }
 
       NS_ABORT_IF_FALSE(progressTracker->HasImage(), "Status tracker should have an image!");
       NS_ABORT_IF_FALSE(mImage, "imgRequest should have an image!");
 
       if (mDecodeRequested)
         mImage->StartDecoding();
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -347,16 +347,17 @@ class GCRuntime
 
     void notifyDidPaint();
     void shrinkBuffers();
     void onOutOfMallocMemory();
     void onOutOfMallocMemory(const AutoLockGC &lock);
 
 #ifdef JS_GC_ZEAL
     const void *addressOfZealMode() { return &zealMode; }
+    void getZeal(uint8_t *zeal, uint32_t *frequency);
     void setZeal(uint8_t zeal, uint32_t frequency);
     bool parseAndSetZeal(const char *str);
     void setNextScheduled(uint32_t count);
     void verifyPreBarriers();
     void verifyPostBarriers();
     void maybeVerifyPreBarriers(bool always);
     void maybeVerifyPostBarriers(bool always);
     bool selectForMarking(JSObject *object);
--- a/js/src/jit-test/tests/for-of/string-iterator-surfaces.js
+++ b/js/src/jit-test/tests/for-of/string-iterator-surfaces.js
@@ -36,17 +36,17 @@ function assertBuiltinFunction(o, name, 
 
     arraysEqual(Object.getOwnPropertyNames(fn).sort(), ["length", "name", "arguments", "caller"].sort());
 
     // Also test "name", "arguments" and "caller" in addition to "length"?
     assertDataDescriptor(Object.getOwnPropertyDescriptor(fn, "length"), {
         value: arity,
         writable: false,
         enumerable: false,
-        configurable: false,
+        configurable: true
     });
 }
 
 
 // String.prototype[@@iterator] is a built-in function
 assertBuiltinFunction(String.prototype, std_iterator, 0);
 
 // Test StringIterator.prototype surface
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -9327,31 +9327,47 @@ CodeGenerator::visitGetDOMProperty(LGetD
     masm.adjustStack(IonDOMExitFrameLayout::Size());
 
     masm.bind(&haveValue);
 
     MOZ_ASSERT(masm.framePushed() == initialStack);
 }
 
 void
-CodeGenerator::visitGetDOMMember(LGetDOMMember *ins)
-{
-    // It's simple to duplicate visitLoadFixedSlotV here than it is to try to
+CodeGenerator::visitGetDOMMemberV(LGetDOMMemberV *ins)
+{
+    // It's simpler to duplicate visitLoadFixedSlotV here than it is to try to
     // use an LLoadFixedSlotV or some subclass of it for this case: that would
     // require us to have MGetDOMMember inherit from MLoadFixedSlot, and then
     // we'd have to duplicate a bunch of stuff we now get for free from
     // MGetDOMProperty.
     Register object = ToRegister(ins->object());
     size_t slot = ins->mir()->domMemberSlotIndex();
     ValueOperand result = GetValueOutput(ins);
 
     masm.loadValue(Address(object, NativeObject::getFixedSlotOffset(slot)), result);
 }
 
 void
+CodeGenerator::visitGetDOMMemberT(LGetDOMMemberT *ins)
+{
+    // It's simpler to duplicate visitLoadFixedSlotT here than it is to try to
+    // use an LLoadFixedSlotT or some subclass of it for this case: that would
+    // require us to have MGetDOMMember inherit from MLoadFixedSlot, and then
+    // we'd have to duplicate a bunch of stuff we now get for free from
+    // MGetDOMProperty.
+    Register object = ToRegister(ins->object());
+    size_t slot = ins->mir()->domMemberSlotIndex();
+    AnyRegister result = ToAnyRegister(ins->getDef(0));
+    MIRType type = ins->mir()->type();
+
+    masm.loadUnboxedValue(Address(object, NativeObject::getFixedSlotOffset(slot)), type, result);
+}
+
+void
 CodeGenerator::visitSetDOMProperty(LSetDOMProperty *ins)
 {
     const Register JSContextReg = ToRegister(ins->getJSContextReg());
     const Register ObjectReg = ToRegister(ins->getObjectReg());
     const Register PrivateReg = ToRegister(ins->getPrivReg());
     const Register ValueReg = ToRegister(ins->getValueReg());
 
     DebugOnly<uint32_t> initialStack = masm.framePushed();
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -300,17 +300,18 @@ class CodeGenerator : public CodeGenerat
     void emitInstanceOf(LInstruction *ins, JSObject *prototypeObject);
     void visitIn(LIn *ins);
     void visitInArray(LInArray *ins);
     void visitInstanceOfO(LInstanceOfO *ins);
     void visitInstanceOfV(LInstanceOfV *ins);
     void visitCallInstanceOf(LCallInstanceOf *ins);
     void visitProfilerStackOp(LProfilerStackOp *lir);
     void visitGetDOMProperty(LGetDOMProperty *lir);
-    void visitGetDOMMember(LGetDOMMember *lir);
+    void visitGetDOMMemberV(LGetDOMMemberV *lir);
+    void visitGetDOMMemberT(LGetDOMMemberT *lir);
     void visitSetDOMProperty(LSetDOMProperty *lir);
     void visitCallDOMNative(LCallDOMNative *lir);
     void visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir);
     void visitIsCallable(LIsCallable *lir);
     void visitOutOfLineIsCallable(OutOfLineIsCallable *ool);
     void visitIsObject(LIsObject *lir);
     void visitIsObjectAndBranch(LIsObjectAndBranch *lir);
     void visitHasClass(LHasClass *lir);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -1745,21 +1745,38 @@ class LGetDOMProperty : public LDOMPrope
                                                      PrivReg, ValueReg)
     { }
 
     MGetDOMProperty *mir() const {
         return mir_->toGetDOMProperty();
     }
 };
 
-class LGetDOMMember : public LInstructionHelper<BOX_PIECES, 1, 0>
-{
-  public:
-    LIR_HEADER(GetDOMMember);
-    explicit LGetDOMMember(const LAllocation &object) {
+class LGetDOMMemberV : public LInstructionHelper<BOX_PIECES, 1, 0>
+{
+  public:
+    LIR_HEADER(GetDOMMemberV);
+    explicit LGetDOMMemberV(const LAllocation &object) {
+        setOperand(0, object);
+    }
+
+    const LAllocation *object() {
+        return getOperand(0);
+    }
+
+    MGetDOMMember *mir() const {
+        return mir_->toGetDOMMember();
+    }
+};
+
+class LGetDOMMemberT : public LInstructionHelper<1, 1, 0>
+{
+  public:
+    LIR_HEADER(GetDOMMemberT);
+    explicit LGetDOMMemberT(const LAllocation &object) {
         setOperand(0, object);
     }
 
     const LAllocation *object() {
         return getOperand(0);
     }
 
     MGetDOMMember *mir() const {
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -311,17 +311,18 @@
     _(InstanceOfO)                  \
     _(InstanceOfV)                  \
     _(CallInstanceOf)               \
     _(InterruptCheck)               \
     _(AsmJSInterruptCheck)          \
     _(InterruptCheckImplicit)       \
     _(ProfilerStackOp)              \
     _(GetDOMProperty)               \
-    _(GetDOMMember)                 \
+    _(GetDOMMemberV)                \
+    _(GetDOMMemberT)                \
     _(SetDOMProperty)               \
     _(CallDOMNative)                \
     _(IsCallable)                   \
     _(IsObject)                     \
     _(IsObjectAndBranch)            \
     _(HasClass)                     \
     _(AsmJSLoadHeap)                \
     _(AsmJSStoreHeap)               \
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3819,19 +3819,29 @@ void
 LIRGenerator::visitGetDOMMember(MGetDOMMember *ins)
 {
     MOZ_ASSERT(ins->isDomMovable(), "Members had better be movable");
     // We wish we could assert that ins->domAliasSet() == JSJitInfo::AliasNone,
     // but some MGetDOMMembers are for [Pure], not [Constant] properties, whose
     // value can in fact change as a result of DOM setters and method calls.
     MOZ_ASSERT(ins->domAliasSet() != JSJitInfo::AliasEverything,
                "Member gets had better not alias the world");
-    LGetDOMMember *lir =
-        new(alloc()) LGetDOMMember(useRegisterAtStart(ins->object()));
-    defineBox(lir, ins);
+
+    MDefinition *obj = ins->object();
+    MOZ_ASSERT(obj->type() == MIRType_Object);
+
+    MIRType type = ins->type();
+
+    if (type == MIRType_Value) {
+        LGetDOMMemberV *lir = new(alloc()) LGetDOMMemberV(useRegisterAtStart(obj));
+        defineBox(lir, ins);
+    } else {
+        LGetDOMMemberT *lir = new(alloc()) LGetDOMMemberT(useRegisterForTypedLoad(obj, type));
+        define(lir, ins);
+    }
 }
 
 void
 LIRGenerator::visitRecompileCheck(MRecompileCheck *ins)
 {
     LRecompileCheck *lir = new(alloc()) LRecompileCheck(temp());
     add(lir, ins);
     assignSafepoint(lir, ins);
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -1008,21 +1008,20 @@ MCall::New(TempAllocator &alloc, JSFunct
     return ins;
 }
 
 AliasSet
 MCallDOMNative::getAliasSet() const
 {
     const JSJitInfo *jitInfo = getJitInfo();
 
-    MOZ_ASSERT(jitInfo->aliasSet() != JSJitInfo::AliasNone);
     // If we don't know anything about the types of our arguments, we have to
     // assume that type-coercions can have side-effects, so we need to alias
     // everything.
-    if (jitInfo->aliasSet() != JSJitInfo::AliasDOMSets || !jitInfo->isTypedMethodJitInfo())
+    if (jitInfo->aliasSet() == JSJitInfo::AliasEverything || !jitInfo->isTypedMethodJitInfo())
         return AliasSet::Store(AliasSet::Any);
 
     uint32_t argIndex = 0;
     const JSTypedMethodJitInfo *methodInfo =
         reinterpret_cast<const JSTypedMethodJitInfo*>(jitInfo);
     for (const JSJitInfo::ArgType *argType = methodInfo->argTypes;
          *argType != JSJitInfo::ArgTypeListEnd;
          ++argType, ++argIndex)
@@ -1043,18 +1042,22 @@ MCallDOMNative::getAliasSet() const
         // JSJitInfo::Object.
         if ((actualType == MIRType_Value || actualType == MIRType_Object) ||
             (*argType & JSJitInfo::Object))
          {
              return AliasSet::Store(AliasSet::Any);
          }
     }
 
-    // We checked all the args, and they check out.  So we only
-    // alias DOM mutations.
+    // We checked all the args, and they check out.  So we only alias DOM
+    // mutations or alias nothing, depending on the alias set in the jitinfo.
+    if (jitInfo->aliasSet() == JSJitInfo::AliasNone)
+        return AliasSet::None();
+
+    MOZ_ASSERT(jitInfo->aliasSet() == JSJitInfo::AliasDOMSets);
     return AliasSet::Load(AliasSet::DOMProperty);
 }
 
 void
 MCallDOMNative::computeMovable()
 {
     // We are movable if the jitinfo says we can be and if we're also not
     // effectful.  The jitinfo can't check for the latter, since it depends on
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3361,21 +3361,21 @@ class MCallDOMNative : public MCall
     // actually a separate MIR op from MCall, because all sorts of places use
     // isCall() to check for calls and all we really want is to overload a few
     // virtual things from MCall.
   protected:
     MCallDOMNative(JSFunction *target, uint32_t numActualArgs)
         : MCall(target, numActualArgs, false)
     {
         // If our jitinfo is not marked movable, that means that our C++
-        // implementation is fallible or that we have no hope of ever doing the
-        // sort of argument analysis that would allow us to detemine that we're
-        // side-effect-free.  In the latter case we wouldn't get DCEd no matter
-        // what, but for the former case we have to explicitly say that we can't
-        // be DCEd.
+        // implementation is fallible or that it never wants to be eliminated or
+        // coalesced or that we have no hope of ever doing the sort of argument
+        // analysis that would allow us to detemine that we're side-effect-free.
+        // In the latter case we wouldn't get DCEd no matter what, but for the
+        // former two cases we have to explicitly say that we can't be DCEd.
         if (!getJitInfo()->isMovable)
             setGuard();
     }
 
     friend MCall *MCall::New(TempAllocator &alloc, JSFunction *target, size_t maxArgc,
                              size_t numActualArgs, bool construct, bool isDOMCall);
 
     const JSJitInfo *getJitInfo() const;
@@ -10639,16 +10639,17 @@ class MGetDOMProperty
 
 class MGetDOMMember : public MGetDOMProperty
 {
     // We inherit everything from MGetDOMProperty except our
     // possiblyCalls value and the congruentTo behavior.
     explicit MGetDOMMember(const JSJitInfo *jitinfo)
         : MGetDOMProperty(jitinfo)
     {
+        setResultType(MIRTypeFromValueType(jitinfo->returnType()));
     }
 
   public:
     INSTRUCTION_HEADER(GetDOMMember)
 
     static MGetDOMMember *New(TempAllocator &alloc, const JSJitInfo *info, MDefinition *obj,
                               MDefinition *guard, MDefinition *globalGuard)
     {
--- a/js/src/jsapi-tests/testGCHeapPostBarriers.cpp
+++ b/js/src/jsapi-tests/testGCHeapPostBarriers.cpp
@@ -5,16 +5,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/RootingAPI.h"
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testGCHeapPostBarriers)
 {
+#ifdef JS_GC_ZEAL
+    AutoLeaveZeal nozeal(cx);
+#endif /* JS_GC_ZEAL */
+
     /* Sanity check - objects start in the nursery and then become tenured. */
     JS_GC(cx->runtime());
     JS::RootedObject obj(cx, NurseryObject());
     CHECK(js::gc::IsInsideNursery(obj.get()));
     JS_GC(cx->runtime());
     CHECK(!js::gc::IsInsideNursery(obj.get()));
     JS::RootedObject tenuredObject(cx, obj);
 
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -407,9 +407,33 @@ class TestJSPrincipals : public JSPrinci
   public:
     explicit TestJSPrincipals(int rc = 0)
       : JSPrincipals()
     {
         refcount = rc;
     }
 };
 
+#ifdef JS_GC_ZEAL
+/*
+ * Temporarily disable the GC zeal setting. This is only useful in tests that
+ * need very explicit GC behavior and should not be used elsewhere.
+ */
+class AutoLeaveZeal
+{
+    JSContext *cx_;
+    uint8_t zeal_;
+    uint32_t frequency_;
+
+  public:
+    explicit AutoLeaveZeal(JSContext *cx) : cx_(cx) {
+        JS_GetGCZeal(cx_, &zeal_, &frequency_);
+        JS_SetGCZeal(cx_, 0, 0);
+        JS::PrepareForFullGC(JS_GetRuntime(cx_));
+        JS::ShrinkingGC(JS_GetRuntime(cx_), JS::gcreason::DEBUG_GC);
+    }
+    ~AutoLeaveZeal() {
+        JS_SetGCZeal(cx_, zeal_, frequency_);
+    }
+};
+#endif /* JS_GC_ZEAL */
+
 #endif /* jsapi_tests_tests_h */
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5721,16 +5721,22 @@ JS_AbortIfWrongThread(JSRuntime *rt)
     if (!CurrentThreadCanAccessRuntime(rt))
         MOZ_CRASH();
     if (!js::TlsPerThreadData.get()->associatedWith(rt))
         MOZ_CRASH();
 }
 
 #ifdef JS_GC_ZEAL
 JS_PUBLIC_API(void)
+JS_GetGCZeal(JSContext *cx, uint8_t *zeal, uint32_t *frequency)
+{
+    cx->runtime()->gc.getZeal(zeal, frequency);
+}
+
+JS_PUBLIC_API(void)
 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency)
 {
     cx->runtime()->gc.setZeal(zeal, frequency);
 }
 
 JS_PUBLIC_API(void)
 JS_ScheduleGC(JSContext *cx, uint32_t count)
 {
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5040,16 +5040,19 @@ extern JS_PUBLIC_API(JSObject *)
 JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const JS::CallArgs& args);
 
 /************************************************************************/
 
 #ifdef JS_GC_ZEAL
 #define JS_DEFAULT_ZEAL_FREQ 100
 
 extern JS_PUBLIC_API(void)
+JS_GetGCZeal(JSContext *cx, uint8_t *zeal, uint32_t *frequency);
+
+extern JS_PUBLIC_API(void)
 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
 
 extern JS_PUBLIC_API(void)
 JS_ScheduleGC(JSContext *cx, uint32_t count);
 #endif
 
 extern JS_PUBLIC_API(void)
 JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -479,34 +479,51 @@ js::fun_resolve(JSContext *cx, HandleObj
 
         if (!ResolveInterpretedFunctionPrototype(cx, fun))
             return false;
 
         *resolvedp = true;
         return true;
     }
 
-    if (JSID_IS_ATOM(id, cx->names().length) || JSID_IS_ATOM(id, cx->names().name)) {
+    bool isLength = JSID_IS_ATOM(id, cx->names().length);
+    if (isLength || JSID_IS_ATOM(id, cx->names().name)) {
         MOZ_ASSERT(!IsInternalFunctionObject(obj));
 
         RootedValue v(cx);
-        if (JSID_IS_ATOM(id, cx->names().length)) {
+        uint32_t attrs;
+        if (isLength) {
+            // Since f.length is configurable, it could be resolved and then deleted:
+            //     function f(x) {}
+            //     assertEq(f.length, 1);
+            //     delete f.length;
+            // Afterwards, asking for f.length again will cause this resolve
+            // hook to run again. Defining the property again the second
+            // time through would be a bug.
+            //     assertEq(f.length, 0);  // gets Function.prototype.length!
+            // We use the RESOLVED_LENGTH flag as a hack to prevent this bug.
+            if (fun->hasResolvedLength())
+                return true;
+
             if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
                 return false;
             uint16_t length = fun->hasScript() ? fun->nonLazyScript()->funLength() :
                 fun->nargs() - fun->hasRest();
             v.setInt32(length);
+            attrs = JSPROP_READONLY;
         } else {
             v.setString(fun->atom() == nullptr ? cx->runtime()->emptyString : fun->atom());
+            attrs = JSPROP_READONLY | JSPROP_PERMANENT;
         }
 
-        if (!DefineNativeProperty(cx, fun, id, v, nullptr, nullptr,
-                                  JSPROP_PERMANENT | JSPROP_READONLY)) {
+        if (!DefineNativeProperty(cx, fun, id, v, nullptr, nullptr, attrs))
             return false;
-        }
+
+        if (isLength)
+            fun->setResolvedLength();
 
         *resolvedp = true;
         return true;
     }
 
     return true;
 }
 
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -44,16 +44,17 @@ class JSFunction : public js::NativeObje
         SELF_HOSTED      = 0x0100,  /* function is self-hosted builtin and must not be
                                        decompilable nor constructible. */
         SELF_HOSTED_CTOR = 0x0200,  /* function is self-hosted builtin constructor and
                                        must be constructible but not decompilable. */
         HAS_REST         = 0x0400,  /* function has a rest (...) parameter */
         ASMJS            = 0x0800,  /* function is an asm.js module or exported function */
         INTERPRETED_LAZY = 0x1000,  /* function is interpreted but doesn't have a script yet */
         ARROW            = 0x2000,  /* ES6 '(args) => body' syntax */
+        RESOLVED_LENGTH  = 0x4000,  /* f.length has been resolved (see js::fun_resolve). */
 
         /* Derived Flags values for convenience: */
         NATIVE_FUN = 0,
         ASMJS_CTOR = ASMJS | NATIVE_CTOR,
         ASMJS_LAMBDA_CTOR = ASMJS | NATIVE_CTOR | LAMBDA,
         INTERPRETED_LAMBDA = INTERPRETED | LAMBDA,
         INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW,
         STABLE_ACROSS_CLONES = NATIVE_CTOR | IS_FUN_PROTO | EXPR_CLOSURE | HAS_GUESSED_ATOM |
@@ -123,34 +124,31 @@ class JSFunction : public js::NativeObje
     /* Possible attributes of an interpreted function: */
     bool isFunctionPrototype()      const { return flags() & IS_FUN_PROTO; }
     bool isExprClosure()            const { return flags() & EXPR_CLOSURE; }
     bool hasGuessedAtom()           const { return flags() & HAS_GUESSED_ATOM; }
     bool isLambda()                 const { return flags() & LAMBDA; }
     bool isSelfHostedBuiltin()      const { return flags() & SELF_HOSTED; }
     bool isSelfHostedConstructor()  const { return flags() & SELF_HOSTED_CTOR; }
     bool hasRest()                  const { return flags() & HAS_REST; }
+    bool isInterpretedLazy()        const { return flags() & INTERPRETED_LAZY; }
+    bool hasScript()                const { return flags() & INTERPRETED; }
 
-    bool isInterpretedLazy()        const {
-        return flags() & INTERPRETED_LAZY;
-    }
-    bool hasScript()                const {
-        return flags() & INTERPRETED;
-    }
+    // Arrow functions store their lexical |this| in the first extended slot.
+    bool isArrow()                  const { return flags() & ARROW; }
+
+    bool hasResolvedLength()        const { return flags() & RESOLVED_LENGTH; }
 
     bool hasJITCode() const {
         if (!hasScript())
             return false;
 
         return nonLazyScript()->hasBaselineScript() || nonLazyScript()->hasIonScript();
     }
 
-    // Arrow functions store their lexical |this| in the first extended slot.
-    bool isArrow()                  const { return flags() & ARROW; }
-
     /* Compound attributes: */
     bool isBuiltin() const {
         return (isNative() && !isAsmJSNative()) || isSelfHostedBuiltin();
     }
     bool isInterpretedConstructor() const {
         // Note: the JITs inline this check, so be careful when making changes
         // here. See MacroAssembler::branchIfNotInterpretedConstructor.
         return isInterpreted() && !isFunctionPrototype() && !isArrow() &&
@@ -204,18 +202,26 @@ class JSFunction : public js::NativeObje
     void setIsExprClosure() {
         flags_ |= EXPR_CLOSURE;
     }
 
     void setArrow() {
         flags_ |= ARROW;
     }
 
+    void setResolvedLength() {
+        flags_ |= RESOLVED_LENGTH;
+    }
+
     JSAtom *atom() const { return hasGuessedAtom() ? nullptr : atom_.get(); }
-    js::PropertyName *name() const { return hasGuessedAtom() || !atom_ ? nullptr : atom_->asPropertyName(); }
+
+    js::PropertyName *name() const {
+        return hasGuessedAtom() || !atom_ ? nullptr : atom_->asPropertyName();
+    }
+
     void initAtom(JSAtom *atom) { atom_.init(atom); }
 
     JSAtom *displayAtom() const {
         return atom_;
     }
 
     void setGuessedAtom(JSAtom *atom) {
         MOZ_ASSERT(!atom_);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1180,16 +1180,23 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
     allocTask(rt, emptyChunks_),
     helperState(rt)
 {
     setGCMode(JSGC_MODE_GLOBAL);
 }
 
 #ifdef JS_GC_ZEAL
 
+void
+GCRuntime::getZeal(uint8_t *zeal, uint32_t *frequency)
+{
+    *zeal = zealMode;
+    *frequency = zealFrequency;
+}
+
 const char *gc::ZealModeHelpText =
     "  Specifies how zealous the garbage collector should be. Values for level:\n"
     "    0: Normal amount of collection\n"
     "    1: Collect when roots are added or removed\n"
     "    2: Collect when every N allocations (default: 100)\n"
     "    3: Collect when the window paints (browser only)\n"
     "    4: Verify pre write barriers between instructions\n"
     "    5: Verify pre write barriers between paints\n"
--- a/js/src/tests/ecma/Array/15.4.4.3-1.js
+++ b/js/src/tests/ecma/Array/15.4.4.3-1.js
@@ -25,18 +25,16 @@ var SECTION = "15.4.4.3-1";
 var VERSION = "ECMA_1";
 startTest();
 
 writeHeaderToLog( SECTION + " Array.prototype.join()");
 
 var ARR_PROTOTYPE = Array.prototype;
 
 new TestCase( SECTION, "Array.prototype.join.length",           1,      Array.prototype.join.length );
-new TestCase( SECTION, "delete Array.prototype.join.length",    false,  delete Array.prototype.join.length );
-new TestCase( SECTION, "delete Array.prototype.join.length; Array.prototype.join.length",    1, eval("delete Array.prototype.join.length; Array.prototype.join.length") );
 
 // case where array length is 0
 
 new TestCase(   SECTION,
 		"var TEST_ARRAY = new Array(); TEST_ARRAY.join()",
 		"",
 		eval("var TEST_ARRAY = new Array(); TEST_ARRAY.join()") );
 
--- a/js/src/tests/ecma/Array/15.4.4.4-1.js
+++ b/js/src/tests/ecma/Array/15.4.4.4-1.js
@@ -63,26 +63,16 @@ writeHeaderToLog( SECTION + " Array.prot
 
 var ARR_PROTOTYPE = Array.prototype;
 
 new TestCase( SECTION,
 	      "Array.prototype.reverse.length",          
 	      0,     
 	      Array.prototype.reverse.length );
 
-new TestCase( SECTION,
-	      "delete Array.prototype.reverse.length",   
-	      false, 
-	      delete Array.prototype.reverse.length );
-
-new TestCase( SECTION,
-	      "delete Array.prototype.reverse.length; Array.prototype.reverse.length",   
-	      0,
-	      eval("delete Array.prototype.reverse.length; Array.prototype.reverse.length") );
-
 // length of array is 0
 new TestCase( SECTION,
 	      "var A = new Array();   A.reverse(); A.length",
 	      0,
 	      eval("var A = new Array();   A.reverse(); A.length") );
 
 // length of array is 1
 var A = new Array(true);
--- a/js/src/tests/ecma/Array/15.4.4.4-2.js
+++ b/js/src/tests/ecma/Array/15.4.4.4-2.js
@@ -59,18 +59,16 @@ var SECTION = "15.4.4.4-1";
 var VERSION = "ECMA_1";
 startTest();
 
 writeHeaderToLog( SECTION + " Array.prototype.reverse()");
 
 var ARR_PROTOTYPE = Array.prototype;
 
 new TestCase( SECTION, "Array.prototype.reverse.length",           0,      Array.prototype.reverse.length );
-new TestCase( SECTION, "delete Array.prototype.reverse.length",    false,  delete Array.prototype.reverse.length );
-new TestCase( SECTION, "delete Array.prototype.reverse.length; Array.prototype.reverse.length",    0, eval("delete Array.prototype.reverse.length; Array.prototype.reverse.length") );
 
 // length of array is 0
 new TestCase(   SECTION,
 		"var A = new Array();   A.reverse(); A.length",
 		0,
 		eval("var A = new Array();   A.reverse(); A.length") );
 
 test();
--- a/js/src/tests/ecma/GlobalObject/15.1.2.2-1.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.2-1.js
@@ -95,31 +95,16 @@ new TestCase( SECTION,
 	      2,     
 	      eval("parseInt.length = 0; parseInt.length") );
 
 new TestCase( SECTION, 
 	      "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS",   "",
 	      eval("var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS") );
 
 new TestCase( SECTION, 
-	      "delete parseInt.length",  
-	      false, 
-	      delete parseInt.length );
-
-new TestCase( SECTION, 
-	      "delete parseInt.length; parseInt.length", 
-	      2, 
-	      eval("delete parseInt.length; parseInt.length") );
-
-new TestCase( SECTION, 
-	      "parseInt.length = null; parseInt.length", 
-	      2, 
-	      eval("parseInt.length = null; parseInt.length") );
-
-new TestCase( SECTION, 
 	      "parseInt()",      
 	      NaN,   
 	      parseInt() );
 
 new TestCase( SECTION, 
 	      "parseInt('')",    
 	      NaN,   
 	      parseInt("") );
--- a/js/src/tests/ecma/GlobalObject/15.1.2.3-1.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.3-1.js
@@ -49,18 +49,16 @@ var TITLE   = "parseFloat(string)";
 var BUGNUMBER="none";
 
 startTest();
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION, "parseFloat.length",     1,              parseFloat.length );
 
 new TestCase( SECTION, "parseFloat.length = null; parseFloat.length",   1,      eval("parseFloat.length = null; parseFloat.length") );
-new TestCase( SECTION, "delete parseFloat.length",                      false,  delete parseFloat.length );
-new TestCase( SECTION, "delete parseFloat.length; parseFloat.length",   1,      eval("delete parseFloat.length; parseFloat.length") );
 new TestCase( SECTION, "var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS", "", eval("var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS") );
 
 new TestCase( SECTION, "parseFloat()",          Number.NaN,     parseFloat() );
 new TestCase( SECTION, "parseFloat('')",        Number.NaN,     parseFloat('') );
 
 new TestCase( SECTION, "parseFloat(' ')",       Number.NaN,     parseFloat(' ') );
 new TestCase( SECTION, "parseFloat(true)",      Number.NaN,     parseFloat(true) );
 new TestCase( SECTION, "parseFloat(false)",     Number.NaN,     parseFloat(false) );
--- a/js/src/tests/ecma/GlobalObject/15.1.2.4.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.4.js
@@ -55,18 +55,16 @@ var SECTION = "15.1.2.4";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "escape(string)";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION, "escape.length",         1,          escape.length );
 new TestCase( SECTION, "escape.length = null; escape.length",   1,  eval("escape.length = null; escape.length") );
-new TestCase( SECTION, "delete escape.length",                  false,  delete escape.length );
-new TestCase( SECTION, "delete escape.length; escape.length",   1,      eval("delete escape.length; escape.length") );
 new TestCase( SECTION, "var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS",    "",    eval("var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS") );
 
 new TestCase( SECTION, "escape()",              "undefined",    escape() );
 new TestCase( SECTION, "escape('')",            "",             escape('') );
 new TestCase( SECTION, "escape( null )",        "null",         escape(null) );
 new TestCase( SECTION, "escape( void 0 )",      "undefined",    escape(void 0) );
 new TestCase( SECTION, "escape( true )",        "true",         escape( true ) );
 new TestCase( SECTION, "escape( false )",       "false",        escape( false ) );
--- a/js/src/tests/ecma/GlobalObject/15.1.2.5-1.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.5-1.js
@@ -53,18 +53,16 @@ var SECTION = "15.1.2.5-1";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "unescape(string)";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION, "unescape.length",       1,               unescape.length );
 new TestCase( SECTION, "unescape.length = null; unescape.length",   1,      eval("unescape.length=null; unescape.length") );
-new TestCase( SECTION, "delete unescape.length",                    false,  delete unescape.length );
-new TestCase( SECTION, "delete unescape.length; unescape.length",   1,      eval("delete unescape.length; unescape.length") );
 new TestCase( SECTION, "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS",    "", eval("var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS") );
 
 new TestCase( SECTION, "unescape()",              "undefined",    unescape() );
 new TestCase( SECTION, "unescape('')",            "",             unescape('') );
 new TestCase( SECTION, "unescape( null )",        "null",         unescape(null) );
 new TestCase( SECTION, "unescape( void 0 )",      "undefined",    unescape(void 0) );
 new TestCase( SECTION, "unescape( true )",        "true",         unescape( true ) );
 new TestCase( SECTION, "unescape( false )",       "false",        unescape( false ) );
--- a/js/src/tests/ecma/GlobalObject/15.1.2.6.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.6.js
@@ -22,18 +22,16 @@ var BUGNUMBER = "none";
 
 startTest();
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION, "isNaN.length",      1,                  isNaN.length );
 new TestCase( SECTION, "var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS", "", eval("var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS") );
 new TestCase( SECTION, "isNaN.length = null; isNaN.length", 1,      eval("isNaN.length=null; isNaN.length") );
-new TestCase( SECTION, "delete isNaN.length",               false,  delete isNaN.length );
-new TestCase( SECTION, "delete isNaN.length; isNaN.length", 1,      eval("delete isNaN.length; isNaN.length") );
 
 //     new TestCase( SECTION, "isNaN.__proto__",   Function.prototype, isNaN.__proto__ );
 
 new TestCase( SECTION, "isNaN()",           true,               isNaN() );
 new TestCase( SECTION, "isNaN( null )",     false,              isNaN(null) );
 new TestCase( SECTION, "isNaN( void 0 )",   true,               isNaN(void 0) );
 new TestCase( SECTION, "isNaN( true )",     false,              isNaN(true) );
 new TestCase( SECTION, "isNaN( false)",     false,              isNaN(false) );
--- a/js/src/tests/ecma/GlobalObject/15.1.2.7.js
+++ b/js/src/tests/ecma/GlobalObject/15.1.2.7.js
@@ -22,18 +22,16 @@ var TITLE   = "isFinite( x )";
 var BUGNUMBER= "none";
 
 startTest();
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION, "isFinite.length",      1,                  isFinite.length );
 new TestCase( SECTION, "isFinite.length = null; isFinite.length",   1,      eval("isFinite.length=null; isFinite.length") );
-new TestCase( SECTION, "delete isFinite.length",                    false,  delete isFinite.length );
-new TestCase( SECTION, "delete isFinite.length; isFinite.length",   1,      eval("delete isFinite.length; isFinite.length") );
 new TestCase( SECTION, "var MYPROPS=''; for ( p in isFinite ) { MYPROPS+= p }; MYPROPS",    "", eval("var MYPROPS=''; for ( p in isFinite ) { MYPROPS += p }; MYPROPS") );
 
 new TestCase( SECTION,  "isFinite()",           false,              isFinite() );
 new TestCase( SECTION, "isFinite( null )",      true,              isFinite(null) );
 new TestCase( SECTION, "isFinite( void 0 )",    false,             isFinite(void 0) );
 new TestCase( SECTION, "isFinite( false )",     true,              isFinite(false) );
 new TestCase( SECTION, "isFinite( true)",       true,              isFinite(true) );
 new TestCase( SECTION, "isFinite( ' ' )",       true,              isFinite( " " ) );
--- a/js/src/tests/ecma/String/15.5.4.10-1.js
+++ b/js/src/tests/ecma/String/15.5.4.10-1.js
@@ -47,18 +47,16 @@
 var SECTION = "15.5.4.10-1";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "String.prototype.substring( start, end )";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION,  "String.prototype.substring.length",        2,          String.prototype.substring.length );
-new TestCase( SECTION,  "delete String.prototype.substring.length", false,      delete String.prototype.substring.length );
-new TestCase( SECTION,  "delete String.prototype.substring.length; String.prototype.substring.length", 2,      eval("delete String.prototype.substring.length; String.prototype.substring.length") );
 
 // test cases for when substring is called with no arguments.
 
 // this is a string object
 
 new TestCase(   SECTION,
 		"var s = new String('this is a string object'); typeof s.substring()",
 		"string",
--- a/js/src/tests/ecma/String/15.5.4.11-1.js
+++ b/js/src/tests/ecma/String/15.5.4.11-1.js
@@ -28,18 +28,16 @@
 var SECTION = "15.5.4.11-1";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "String.prototype.toLowerCase()";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION,  "String.prototype.toLowerCase.length",        0,          String.prototype.toLowerCase.length );
-new TestCase( SECTION,  "delete String.prototype.toLowerCase.length", false,      delete String.prototype.toLowerCase.length );
-new TestCase( SECTION,  "delete String.prototype.toLowerCase.length; String.prototype.toLowerCase.length", 0,      eval("delete String.prototype.toLowerCase.length; String.prototype.toLowerCase.length") );
 
 // Basic Latin, Latin-1 Supplement, Latin Extended A
 for ( var i = 0; i <= 0x017f; i++ ) {
   var U = new Unicode(i);
 /*
   new TestCase(   SECTION,
   "var s = new String( String.fromCharCode("+i+") ); s.toLowerCase()",
   String.fromCharCode(U.lower),
--- a/js/src/tests/ecma/String/15.5.4.6-2.js
+++ b/js/src/tests/ecma/String/15.5.4.6-2.js
@@ -67,18 +67,16 @@ new TestCase( SECTION,
               "function f() { return this; }; function g() { var h = f; return h(); }; g().toString()",   
               GLOBAL, 
               g().toString()
   );
 
 
 new TestCase( SECTION, "String.prototype.indexOf.length",                                               1,     String.prototype.indexOf.length );
 new TestCase( SECTION, "String.prototype.indexOf.length = null; String.prototype.indexOf.length",       1,     eval("String.prototype.indexOf.length = null; String.prototype.indexOf.length") );
-new TestCase( SECTION, "delete String.prototype.indexOf.length",                                        false,  delete String.prototype.indexOf.length );
-new TestCase( SECTION, "delete String.prototype.indexOf.length; String.prototype.indexOf.length",       1,      eval("delete String.prototype.indexOf.length; String.prototype.indexOf.length") );
 
 new TestCase( SECTION,
               "var s = new String(); s.indexOf()",    
               -1,    
               eval("var s = new String(); s.indexOf()") );
 
 // some Unicode tests.
 
--- a/js/src/tests/ecma/String/15.5.4.7-2.js
+++ b/js/src/tests/ecma/String/15.5.4.7-2.js
@@ -48,18 +48,16 @@ var SECTION = "15.5.4.7-2";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "String.protoype.lastIndexOf";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 
 new TestCase( SECTION, "String.prototype.lastIndexOf.length",           1,          String.prototype.lastIndexOf.length );
-new TestCase( SECTION, "delete String.prototype.lastIndexOf.length",    false,      delete String.prototype.lastIndexOf.length );
-new TestCase( SECTION, "delete String.prototype.lastIndexOf.length; String.prototype.lastIndexOf.length",   1,  eval("delete String.prototype.lastIndexOf.length; String.prototype.lastIndexOf.length" ) );
 
 new TestCase( SECTION, "var s = new String(''); s.lastIndexOf('', 0)",          LastIndexOf("","",0),  eval("var s = new String(''); s.lastIndexOf('', 0)") );
 new TestCase( SECTION, "var s = new String(''); s.lastIndexOf('')",             LastIndexOf("",""),  eval("var s = new String(''); s.lastIndexOf('')") );
 new TestCase( SECTION, "var s = new String('hello'); s.lastIndexOf('', 0)",     LastIndexOf("hello","",0),  eval("var s = new String('hello'); s.lastIndexOf('',0)") );
 new TestCase( SECTION, "var s = new String('hello'); s.lastIndexOf('')",        LastIndexOf("hello",""),  eval("var s = new String('hello'); s.lastIndexOf('')") );
 
 new TestCase( SECTION, "var s = new String('hello'); s.lastIndexOf('ll')",     LastIndexOf("hello","ll"),  eval("var s = new String('hello'); s.lastIndexOf('ll')") );
 new TestCase( SECTION, "var s = new String('hello'); s.lastIndexOf('ll', 0)",  LastIndexOf("hello","ll",0),  eval("var s = new String('hello'); s.lastIndexOf('ll', 0)") );
--- a/js/src/tests/ecma/String/15.5.4.8-1.js
+++ b/js/src/tests/ecma/String/15.5.4.8-1.js
@@ -34,18 +34,16 @@
 var SECTION = "15.5.4.8-1";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "String.prototype.split";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION,  "String.prototype.split.length",        2,          String.prototype.split.length );
-new TestCase( SECTION,  "delete String.prototype.split.length", false,      delete String.prototype.split.length );
-new TestCase( SECTION,  "delete String.prototype.split.length; String.prototype.split.length", 2,      eval("delete String.prototype.split.length; String.prototype.split.length") );
 
 // test cases for when split is called with no arguments.
 
 // this is a string object
 
 new TestCase(   SECTION,
 		"var s = new String('this is a string object'); typeof s.split()",
 		"object",
--- a/js/src/tests/ecma/String/15.5.4.9-1.js
+++ b/js/src/tests/ecma/String/15.5.4.9-1.js
@@ -37,18 +37,16 @@
 var SECTION = "15.5.4.9-1";
 var VERSION = "ECMA_1";
 startTest();
 var TITLE   = "String.prototype.substring( start )";
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION,  "String.prototype.substring.length",        2,          String.prototype.substring.length );
-new TestCase( SECTION,  "delete String.prototype.substring.length", false,      delete String.prototype.substring.length );
-new TestCase( SECTION,  "delete String.prototype.substring.length; String.prototype.substring.length", 2,      eval("delete String.prototype.substring.length; String.prototype.substring.length") );
 
 // test cases for when substring is called with no arguments.
 
 // this is a string object
 
 new TestCase(   SECTION,
 		"var s = new String('this is a string object'); typeof s.substring()",
 		"string",
--- a/js/src/tests/ecma/extensions/15.1.2.1-1.js
+++ b/js/src/tests/ecma/extensions/15.1.2.1-1.js
@@ -18,17 +18,16 @@ var VERSION = "ECMA_1";
 var TITLE   = "eval(x)";
 var BUGNUMBER = "none";
 
 startTest();
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 new TestCase( SECTION,      "eval.length",              1,              eval.length );
-new TestCase( SECTION,      "delete eval.length",       false,          delete eval.length );
 new TestCase( SECTION,      "var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS",  "", eval("var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS") );
 new TestCase( SECTION,      "eval.length = null; eval.length",       1, eval( "eval.length = null; eval.length") );
 //     new TestCase( SECTION,     "eval.__proto__",                       Function.prototype,            eval.__proto__ );
 
 // test cases where argument is not a string.  should return the argument.
 
 new TestCase( SECTION,     "eval()",                                void 0,                     eval() );
 new TestCase( SECTION,     "eval(void 0)",                          void 0,                     eval( void 0) );
--- a/js/src/tests/ecma_5/Function/function-bind.js
+++ b/js/src/tests/ecma_5/Function/function-bind.js
@@ -207,24 +207,24 @@ assertEq(br.length, 0);
  * 17. Set the attributes of the length own property of F to the values
  *     specified in 15.3.5.1.
  */
 var len1Desc =
   Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(), "length");
 assertEq(len1Desc.value, 3);
 assertEq(len1Desc.writable, false);
 assertEq(len1Desc.enumerable, false);
-assertEq(len1Desc.configurable, false);
+assertEq(len1Desc.configurable, true);
 
 var len2Desc =
   Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(null, 2), "length");
 assertEq(len2Desc.value, 2);
 assertEq(len2Desc.writable, false);
 assertEq(len2Desc.enumerable, false);
-assertEq(len2Desc.configurable, false);
+assertEq(len2Desc.configurable, true);
 
 
 /*
  * 18. Set the [[Extensible]] internal property of F to true.
  */
 var bound = (function() { }).bind();
 
 var isExtensible = Object.isExtensible || function() { return true; };
--- a/js/src/tests/ecma_5/Object/15.2.3.3-01.js
+++ b/js/src/tests/ecma_5/Object/15.2.3.3-01.js
@@ -229,17 +229,17 @@ function foo() { }
 o = foo;
 
 pd = Object.getOwnPropertyDescriptor(o, "length");
 expected =
   {
     value: 0,
     writable: false,
     enumerable: false,
-    configurable: false
+    configurable: true
   };
 
 expectDescriptor(pd, expected);
 
 pd = Object.getOwnPropertyDescriptor(o, "prototype");
 expected =
   {
     value: foo.prototype,
@@ -253,17 +253,17 @@ expectDescriptor(pd, expected);
 /******************************************************************************/
 
 pd = Object.getOwnPropertyDescriptor(Function, "length");
 expected =
   {
     value: 1,
     writable: false,
     enumerable: false,
-    configurable: false
+    configurable: true
   };
 
 expectDescriptor(pd, expected);
 
 /******************************************************************************/
 
 o = /foo/im;
 
--- a/js/src/tests/ecma_5/Object/defineProperty-setup.js
+++ b/js/src/tests/ecma_5/Object/defineProperty-setup.js
@@ -515,45 +515,34 @@ function mapTestDescriptors(filter)
   });
 
   return descs;
 }
 
 var ALL_DESCRIPTORS = mapTestDescriptors(function(d) { return true; });
 var VALID_DESCRIPTORS = mapTestDescriptors(isValidDescriptor);
 
-var SKIP_FULL_FUNCTION_LENGTH_TESTS = true;
-
 function TestRunner()
 {
   this._logLines = [];
 }
 TestRunner.prototype =
   {
     // MAIN METHODS
 
     runFunctionLengthTests: function runFunctionLengthTests()
     {
       var self = this;
       function functionLengthTests()
       {
-        if (SKIP_FULL_FUNCTION_LENGTH_TESTS)
-        {
-          print("Skipping full tests for redefining Function.length for now " +
-                "because we don't support redefinition of properties with " +
-                "native getter or setter...");
-          self._simpleFunctionLengthTests();
-        }
-        else
-        {
-          self._simpleFunctionLengthTests();
-          self._fullFunctionLengthTests(function() { }, 0);
-          self._fullFunctionLengthTests(function(one) { }, 1);
-          self._fullFunctionLengthTests(function(one, two) { }, 2);
-        }
+        self._fullFunctionLengthTests(() => Function("one", "/* body */"), 1);
+        self._fullFunctionLengthTests(() => function(one, two, three=null) { }, 2);
+        self._fullFunctionLengthTests(() => (one, two, ...etc) => 0, 2);
+        self._fullFunctionLengthTests(() => ({method(){}}.method), 0);
+        self._fullFunctionLengthTests(() => Object.getOwnPropertyDescriptor({set x(v){}}, "x").set, 1);
       }
 
       this._runTestSet(functionLengthTests, "Function length tests completed!");
     },
 
     runNotPresentTests: function runNotPresentTests()
     {
       var self = this;
@@ -732,49 +721,25 @@ TestRunner.prototype =
     },
     _reportAllErrors: function _reportAllErrors()
     {
       var errorCount = this._logLines.length;
       print("Full accumulated number of errors: " + errorCount);
       if (errorCount > 0)
         throw errorCount + " errors detected, FAIL";
     },
-    _simpleFunctionLengthTests: function _simpleFunctionLengthTests(fun)
+    _fullFunctionLengthTests: function _fullFunctionLengthTests(funFactory, len)
     {
-      print("Running simple Function.length tests now..");
+      print("Running Function.length (" + funFactory + ") tests now...");
 
-      function expectThrowTypeError(o, p, desc)
+      for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++)
       {
-        var err = "<none>", passed = false;
-        try
-        {
-          Object.defineProperty(o, p, desc);
-        }
-        catch (e)
-        {
-          err = e;
-          passed = e instanceof TypeError;
-        }
-        assertEq(passed, true, fun + " didn't throw TypeError when called: " + err);
+        var desc = VALID_DESCRIPTORS[i];
+        this._runSingleFunctionLengthTest(funFactory(), len, desc);
       }
-
-      expectThrowTypeError(function a() { }, "length", { value: 1 });
-      expectThrowTypeError(function a() { }, "length", { enumerable: true });
-      expectThrowTypeError(function a() { }, "length", { configurable: true });
-      expectThrowTypeError(function a() { }, "length", { writable: true });
-    },
-    _fullFunctionLengthTests: function _fullFunctionLengthTests(fun)
-    {
-      var len = fun.length;
-      print("Running Function.length (" + len + ") tests now...");
-
-      var desc;
-      var gen = new DescriptorState();
-      while ((desc = gen.nextDescriptor()))
-        this._runSingleFunctionLengthTest(fun, len, desc);
     },
     _log: function _log(v)
     {
       var m = "" + v;
       print(m);
       this._logLines.push(m);
     },
     _runSingleNotPresentTest: function _runSingleNotPresentTest(desc)
@@ -977,17 +942,17 @@ TestRunner.prototype =
     _runSingleFunctionLengthTest: function _runSingleFunctionLengthTest(fun, len, desc)
     {
       var nativeObj = fun;
       var reimplObj = ReimplTest.newObject();
       ReimplTest.defineProperty(reimplObj, "length",
       {
         value: len,
         enumerable: false,
-        configurable: false,
+        configurable: true,
         writable: false
       });
 
       try
       {
         NativeTest.defineProperty(nativeObj, "length", desc);
       }
       catch (e)
--- a/js/src/tests/ecma_5/strict/15.3.5.1.js
+++ b/js/src/tests/ecma_5/strict/15.3.5.1.js
@@ -7,13 +7,10 @@
 
 function fn() {
   return function(a, b, c) { };
 }
 
 assertEq(testLenientAndStrict('var f = fn(); f.length = 1; f.length',
                               returns(3), raisesException(TypeError)),
          true);
-assertEq(testLenientAndStrict('var f = fn(); delete f.length',
-                              returns(false), raisesException(TypeError)),
-         true);
 
 reportCompare(true, true);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/configurable-length-builtins.js
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Deleting .length from a variety of builtin functions works as expected.
+for (var fun of [Math.sin, Array.prototype.map, eval]) {
+    assertEq(delete fun.length, true);
+    assertEq(fun.hasOwnProperty("length"), false);
+    assertEq("length" in fun, true);  // still inheriting Function.prototype.length
+    assertEq(fun.length, 0);
+
+    // The inherited property is nonwritable, so assigning still fails
+    // (silently, in sloppy mode).
+    fun.length = Math.hypot;
+    assertEq(fun.length, 0);
+
+    // It can be shadowed via defineProperty.
+    Object.defineProperty(fun, "length", {value: Math.hypot});
+    assertEq(fun.length, Math.hypot);
+}
+
+reportCompare(0, 0, 'ok');
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/configurable-length.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Very simple initial test that the "length" property of a function is
+// configurable. More thorough tests follow.
+var f = function (a1, a2, a3, a4) {};
+assertEq(delete f.length, true);
+assertEq(f.hasOwnProperty("length"), false);
+assertEq(f.length, 0);  // inherited from Function.prototype.length
+assertEq(delete Function.prototype.length, true);
+assertEq(f.length, undefined);
+
+
+// Now for the details.
+//
+// Many of these tests are poking at the "resolve hook" mechanism SM uses to
+// lazily create this property, which is wonky and deserving of some extra
+// skepticism.
+
+// We've deleted Function.prototype.length. Check that the resolve hook does
+// not resurrect it.
+assertEq("length" in Function.prototype, false);
+Function.prototype.length = 7;
+assertEq(Function.prototype.length, 7);
+delete Function.prototype.length;
+assertEq(Function.prototype.length, undefined);
+
+// OK, define Function.prototype.length back to its original state per spec, so
+// the remaining tests can run in a more typical environment.
+Object.defineProperty(Function.prototype, "length", {value: 0, configurable: true});
+
+// Check the property descriptor of a function length property.
+var g = function f(a1, a2, a3, a4, a5) {};
+var desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+assertEq(desc.value, 5);
+
+// After deleting the length property, assigning to f.length fails because
+// Function.prototype.length is non-writable. In strict mode it would throw.
+delete g.length;
+g.length = 12;
+assertEq(g.hasOwnProperty("length"), false);
+assertEq(g.length, 0);
+
+// After deleting both the length property and Function.prototype.length,
+// assigning to f.length creates a new plain old data property.
+delete Function.prototype.length;
+g.length = 13;
+var desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, true);
+assertEq(desc.writable, true);
+assertEq(desc.value, 13);
+
+// Deleting the .length of one instance of a FunctionDeclaration does not
+// affect other instances.
+function mkfun() {
+    function fun(a1, a2, a3, a4, a5) {}
+    return fun;
+}
+g = mkfun();
+var h = mkfun();
+delete h.length;
+assertEq(g.length, 5);
+assertEq(mkfun().length, 5);
+
+// Object.defineProperty on a brand-new function is sufficient to cause the
+// LENGTH_RESOLVED flag to be set.
+g = mkfun();
+Object.defineProperty(g, "length", {value: 0});
+assertEq(delete g.length, true);
+assertEq(g.hasOwnProperty("length"), false);
+
+// Object.defineProperty on a brand-new function correctly merges new
+// attributes with the builtin ones.
+g = mkfun();
+Object.defineProperty(g, "length", { value: 42 });
+desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+assertEq(desc.value, 42);
+
+reportCompare(0, 0, 'ok');
new file mode 100644
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -1,14 +1,44 @@
 # Manifest entries for imported test suites whose individual test cases
 # we don't want to change.
 
 skip-if(!this.hasOwnProperty("Intl")) include test262/intl402/jstests.list # Intl is not enabled in all builds
 skip script ecma_6/String/normalize-generateddata-input.js # input data for other test
 
+###################################################
+# Test262 tests skipped due to SpiderMonkey fixes #
+###################################################
+
+# These tests assert that function.length is non-configurable. It was
+# non-configurable in ES5, but ES6 changes this and we have implemented the
+# newer standard (bug 911142).
+skip script test262/intl402/ch13/13.1/13.1.1_L15.js
+skip script test262/intl402/ch13/13.2/13.2.1_L15.js
+skip script test262/intl402/ch13/13.3/13.3.1_L15.js
+skip script test262/intl402/ch13/13.3/13.3.2_L15.js
+skip script test262/intl402/ch13/13.3/13.3.3_L15.js
+skip script test262/intl402/ch10/10.2/10.2.2_L15.js
+skip script test262/intl402/ch10/10.3/10.3.2_1_a_L15.js
+skip script test262/intl402/ch10/10.3/10.3.3_L15.js
+skip script test262/intl402/ch10/10.3/10.3.2_L15.js
+skip script test262/intl402/ch10/10.1/10.1_L15.js
+skip script test262/intl402/ch11/11.2/11.2.2_L15.js
+skip script test262/intl402/ch11/11.1/11.1_L15.js
+skip script test262/intl402/ch11/11.3/11.3.3_L15.js
+skip script test262/intl402/ch11/11.3/11.3.2_L15.js
+skip script test262/intl402/ch11/11.3/11.3.2_1_a_L15.js
+skip script test262/intl402/ch12/12.3/12.3.3_L15.js
+skip script test262/intl402/ch12/12.3/12.3.2_L15.js
+skip script test262/intl402/ch12/12.3/12.3.2_1_a_L15.js
+skip script test262/intl402/ch12/12.1/12.1_L15.js
+skip script test262/intl402/ch12/12.2/12.2.2_L15.js
+skip script test262/ch13/13.2/13.2-15-1.js
+skip script test262/ch11/11.4/11.4.1/11.4.1-5-a-28-s.js
+
 ##################################################
 # Test262 tests skipped due to SpiderMonkey bugs #
 ##################################################
 
 skip script test262/ch10/10.4/10.4.3/10.4.3-1-104.js # bug 603201
 skip script test262/ch10/10.4/10.4.3/10.4.3-1-106.js # bug 603201
 
 #######################################################################
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1380,17 +1380,16 @@ Debugger::onTrap(JSContext *cx, MutableH
 
     for (Breakpoint **p = triggered.begin(); p != triggered.end(); p++) {
         Breakpoint *bp = *p;
 
         /* Handlers can clear breakpoints. Check that bp still exists. */
         if (!site || !site->hasBreakpoint(bp))
             continue;
 
-
         /*
          * There are two reasons we have to check whether dbg is enabled and
          * debugging scriptGlobal.
          *
          * One is just that one breakpoint handler can disable other Debuggers
          * or remove debuggees.
          *
          * The other has to do with non-compile-and-go scripts, which have no
@@ -1617,16 +1616,23 @@ Debugger::slowPathOnLogAllocationSite(JS
             return false;
         }
     }
 
     return true;
 }
 
 bool
+Debugger::isDebuggee(const JSCompartment *compartment) const
+{
+    MOZ_ASSERT(compartment);
+    return compartment->isDebuggee() && debuggees.has(compartment->maybeGlobal());
+}
+
+bool
 Debugger::appendAllocationSite(JSContext *cx, HandleSavedFrame frame, int64_t when)
 {
     AutoCompartment ac(cx, object);
     RootedObject wrapped(cx, frame);
     if (!cx->compartment()->wrap(cx, &wrapped))
         return false;
 
     AllocationSite *allocSite = cx->new_<AllocationSite>(wrapped, when);
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -17,23 +17,23 @@
 #include "jswrapper.h"
 
 #include "gc/Barrier.h"
 #include "js/Debug.h"
 #include "js/HashTable.h"
 #include "vm/GlobalObject.h"
 #include "vm/SavedStacks.h"
 
-typedef enum JSTrapStatus {
+enum JSTrapStatus {
     JSTRAP_ERROR,
     JSTRAP_CONTINUE,
     JSTRAP_RETURN,
     JSTRAP_THROW,
     JSTRAP_LIMIT
-} JSTrapStatus;
+};
 
 namespace js {
 
 class Breakpoint;
 class DebuggerMemory;
 
 /*
  * A weakmap from GC thing keys to JSObject values that supports the keys being
@@ -229,20 +229,17 @@ class Debugger : private mozilla::Linked
     // must be 0 and Observing must be 1.
     enum IsObserving {
         NotObserving = 0,
         Observing = 1
     };
 
     // Return true if the given compartment is a debuggee of this debugger,
     // false otherwise.
-    bool isDebuggee(const JSCompartment *compartment) const {
-        MOZ_ASSERT(compartment);
-        return compartment->isDebuggee() && debuggees.has(compartment->maybeGlobal());
-    }
+    bool isDebuggee(const JSCompartment *compartment) const;
 
   private:
     HeapPtrNativeObject object;         /* The Debugger object. Strong reference. */
     GlobalObjectSet debuggees;          /* Debuggee globals. Cross-compartment weak references. */
     js::HeapPtrObject uncaughtExceptionHook; /* Strong reference. */
     bool enabled;
     JSCList breakpoints;                /* Circular list of all js::Breakpoints in this debugger */
 
--- a/netwerk/protocol/http/ASpdySession.h
+++ b/netwerk/protocol/http/ASpdySession.h
@@ -45,22 +45,36 @@ public:
   const static uint32_t kTCPSendBufferSize = 131072;
 
   // until we have an API that can push back on receiving data (right now
   // WriteSegments is obligated to accept data and buffer) there is no
   // reason to throttle with the rwin other than in server push
   // scenarios.
   const static uint32_t kInitialRwin = 256 * 1024 * 1024;
 
+  // soft errors are errors that terminate a stream without terminating the
+  // connection. In general non-network errors are stream errors as well
+  // as network specific items like cancels.
   bool SoftStreamError(nsresult code)
   {
     if (NS_SUCCEEDED(code)) {
       return false;
     }
 
+    // this could go either way, but because there are network instances of
+    // it being a hard error we should consider it hard.
+    if (code == NS_ERROR_FAILURE) {
+      return false;
+    }
+
+    if (NS_ERROR_GET_MODULE(code) != NS_ERROR_MODULE_NETWORK) {
+      return true;
+    }
+
+    // these are network specific soft errors
     return (code == NS_BASE_STREAM_CLOSED || code == NS_BINDING_FAILED ||
             code == NS_BINDING_ABORTED || code == NS_BINDING_REDIRECTED ||
             code == NS_ERROR_INVALID_CONTENT_ENCODING ||
             code == NS_BINDING_RETARGETED || code == NS_ERROR_CORRUPTED_CONTENT);
   }
 };
 
 typedef bool (*ALPNCallback) (nsISupports *); // nsISSLSocketControl is typical
--- a/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini
+++ b/testing/web-platform/meta/js/builtins/WeakMap.prototype-properties.html.ini
@@ -1,8 +1,19 @@
 [WeakMap.prototype-properties.html]
   type: testharness
+  [WeakMap.prototype.clear.length]
+    expected: FAIL
+
+  [WeakMap.prototype.delete.length]
+    expected: FAIL
+
   [WeakMap.prototype.get.length]
     expected: FAIL
 
   [WeakMap.prototype.get: return undefined]
     expected: FAIL
 
+  [WeakMap.prototype.has.length]
+    expected: FAIL
+
+  [WeakMap.prototype.set.length]
+    expected: FAIL