Backed out 7 changesets (bug 1145491) for ggc orange
authorWes Kocher <wkocher@mozilla.com>
Fri, 20 Mar 2015 22:39:44 -0700
changeset 263685 3b7a4d9da546f962e8f3deae22a7cc3b96c0a8d4
parent 263684 8bd7b499e291c8a5d554a746df559f22c95d6075
child 263686 9bffa3aa7ea99085daddbdc6a92f965324562877
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1145491
milestone39.0a1
backs out8d14c6661f003cbe0aabf38268bddf2b20abba04
7be39afdf528795236b3d2bd82ff796947e195a7
8066b21e74a00e4613ddbf27d70777c95dd27c69
151e4cdb34cfe930c221bb2e84377e3f260c5414
97b16da6169bb0abc619d95ebddbcc22ba53b1c6
cddba378a563030c6a0e76f8b034f1eb8c5c53a1
80344fd40d6bd9cc46d0941e5ca597bf31f142a0
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
Backed out 7 changesets (bug 1145491) for ggc orange Backed out changeset 8d14c6661f00 (bug 1145491) Backed out changeset 7be39afdf528 (bug 1145491) Backed out changeset 8066b21e74a0 (bug 1145491) Backed out changeset 151e4cdb34cf (bug 1145491) Backed out changeset 97b16da6169b (bug 1145491) Backed out changeset cddba378a563 (bug 1145491) Backed out changeset 80344fd40d6b (bug 1145491)
js/src/builtin/TestingFunctions.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/jit-test/tests/basic/bug1106982-2.js
js/src/jit-test/tests/basic/bug1106982.js
js/src/jit-test/tests/basic/eval-scopes.js
js/src/jit-test/tests/basic/weird-scopechains.js
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/BytecodeAnalysis.cpp
js/src/jit/IonBuilder.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsscript.cpp
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
js/src/vm/Opcodes.h
js/src/vm/ScopeObject.cpp
js/src/vm/Xdr.h
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -2427,33 +2427,16 @@ DumpStringRepresentation(JSContext *cx, 
 
     str->dumpRepresentation(stderr, 0);
 
     args.rval().setUndefined();
     return true;
 }
 #endif
 
-static bool
-SetLazyParsingEnabled(JSContext *cx, unsigned argc, Value *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (argc < 1) {
-        JS_ReportError(cx, "setLazyParsingEnabled: need an argument");
-        return false;
-    }
-
-    bool arg = ToBoolean(args.get(0));
-    JS::CompartmentOptionsRef(cx->compartment()).setDiscardSource(!arg);
-
-    args.rval().setUndefined();
-    return true;
-}
-
 static const JSFunctionSpecWithHelp TestingFunctions[] = {
     JS_FN_HELP("gc", ::GC, 0, 0,
 "gc([obj] | 'compartment' [, 'shrinking'])",
 "  Run the garbage collector. When obj is given, GC only its compartment.\n"
 "  If 'compartment' is given, GC any compartments that were scheduled for\n"
 "  GC via schedulegc.\n"
 "  If 'shrinking' is passed as the optional second argument, perform a\n"
 "  shrinking GC rather than a normal GC."),
@@ -2826,20 +2809,16 @@ gc::ZealModeHelpText),
 "  because the object is a revoked proxy)."),
 
 #ifdef DEBUG
     JS_FN_HELP("dumpStringRepresentation", DumpStringRepresentation, 1, 0,
 "dumpStringRepresentation(str)",
 "  Print a human-readable description of how the string |str| is represented.\n"),
 #endif
 
-    JS_FN_HELP("setLazyParsingEnabled", SetLazyParsingEnabled, 1, 0,
-"setLazyParsingEnabled(bool)",
-"  Enable or disable lazy parsing in the current compartment.  The default is enabled."),
-
     JS_FS_HELP_END
 };
 
 static const JSPropertySpec TestingProperties[] = {
     JS_PSG("timesAccessed", TimesAccessed, 0),
     JS_PS_END
 };
 
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -287,24 +287,27 @@ frontend::CompileScript(ExclusiveContext
 
     bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction();
     Rooted<JSScript*> script(cx, JSScript::Create(cx, evalStaticScope, savedCallerFun,
                                                   options, staticLevel, sourceObject, 0,
                                                   srcBuf.length()));
     if (!script)
         return nullptr;
 
-    bool insideNonGlobalEval =
-        evalStaticScope && evalStaticScope->enclosingScopeForStaticScopeIter();
+    // We can specialize a bit for the given scope chain if that scope chain is the global object.
+    JSObject *globalScope =
+        scopeChain && scopeChain == &scopeChain->global() ? (JSObject*) scopeChain : nullptr;
+    MOZ_ASSERT_IF(globalScope, globalScope->isNative());
+    MOZ_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass()));
+
     BytecodeEmitter::EmitterMode emitterMode =
         options.selfHostingMode ? BytecodeEmitter::SelfHosting : BytecodeEmitter::Normal;
     BytecodeEmitter bce(/* parent = */ nullptr, &parser, &globalsc, script,
                         /* lazyScript = */ js::NullPtr(), options.forEval,
-                        evalCaller, evalStaticScope, insideNonGlobalEval,
-                        options.lineno, emitterMode);
+                        evalCaller, evalStaticScope, !!globalScope, options.lineno, emitterMode);
     if (!bce.init())
         return nullptr;
 
     // Syntax parsing may cause us to restart processing of top level
     // statements in the script. Use Maybe<> so that the parse context can be
     // reset when this occurs.
     Maybe<ParseContext<FullParseHandler> > pc;
 
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -112,18 +112,17 @@ struct LoopStmtInfo : public StmtInfoBCE
 
 } // anonymous namespace
 
 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent,
                                  Parser<FullParseHandler> *parser, SharedContext *sc,
                                  HandleScript script, Handle<LazyScript *> lazyScript,
                                  bool insideEval, HandleScript evalCaller,
                                  Handle<StaticEvalObject *> staticEvalScope,
-                                 bool insideNonGlobalEval, uint32_t lineNum,
-                                 EmitterMode emitterMode)
+                                 bool hasGlobalScope, uint32_t lineNum, EmitterMode emitterMode)
   : sc(sc),
     parent(parent),
     script(sc->context, script),
     lazyScript(sc->context, lazyScript),
     prolog(sc->context, lineNum),
     main(sc->context, lineNum),
     current(&main),
     parser(parser),
@@ -143,17 +142,17 @@ BytecodeEmitter::BytecodeEmitter(Bytecod
     blockScopeList(sc->context),
     yieldOffsetList(sc->context),
     typesetCount(0),
     hasSingletons(false),
     hasTryFinally(false),
     emittingForInit(false),
     emittingRunOnceLambda(false),
     insideEval(insideEval),
-    insideNonGlobalEval(insideNonGlobalEval),
+    hasGlobalScope(hasGlobalScope),
     emitterMode(emitterMode)
 {
     MOZ_ASSERT_IF(evalCaller, insideEval);
     MOZ_ASSERT_IF(emitterMode == LazyFunction, lazyScript);
     // Function scripts are never eval scripts.
     MOZ_ASSERT_IF(evalStaticScope, !sc->isFunctionBox());
 }
 
@@ -1630,23 +1629,18 @@ TryConvertFreeName(BytecodeEmitter *bce,
             }
 
             if (script->funHasExtensibleScope() || script->directlyInsideEval())
                 return false;
         }
     }
 
     // Unbound names aren't recognizable global-property references if the
-    // script is inside a non-global eval call.
-    if (bce->insideNonGlobalEval)
-        return false;
-
-    // Skip trying to use GNAME ops if we know our script has a polluted
-    // global scope, since they'll just get treated as NAME ops anyway.
-    if (bce->script->hasPollutedGlobalScope())
+    // script isn't running against its global object.
+    if (!bce->script->compileAndGo() || !bce->hasGlobalScope)
         return false;
 
     // Deoptimized names also aren't necessarily globals.
     if (pn->isDeoptimized())
         return false;
 
     if (bce->sc->isFunctionBox()) {
         // Unbound names in function code may not be globals if new locals can
@@ -2336,17 +2330,17 @@ EmitNameOp(ExclusiveContext *cx, Bytecod
         } else {
             if (!EmitAtomOp(cx, pn, op, bce))
                 return false;
         }
     }
 
     /* Need to provide |this| value for call */
     if (callContext) {
-        if (op == JSOP_GETNAME || op == JSOP_GETGNAME) {
+        if (op == JSOP_GETNAME) {
             JSOp thisOp =
                 bce->needsImplicitThis() ? JSOP_IMPLICITTHIS : JSOP_GIMPLICITTHIS;
             if (!EmitAtomOp(cx, pn, thisOp, bce))
                 return false;
         } else {
             if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
                 return false;
         }
@@ -5413,17 +5407,17 @@ EmitFunc(ExclusiveContext *cx, BytecodeE
                 return false;
 
             script->bindings = funbox->bindings;
 
             uint32_t lineNum = bce->parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin);
             BytecodeEmitter bce2(bce, bce->parser, funbox, script, /* lazyScript = */ js::NullPtr(),
                                  bce->insideEval, bce->evalCaller,
                                  /* evalStaticScope = */ js::NullPtr(),
-                                 bce->insideNonGlobalEval, lineNum, bce->emitterMode);
+                                 bce->hasGlobalScope, lineNum, bce->emitterMode);
             if (!bce2.init())
                 return false;
 
             /* We measured the max scope depth when we parsed the function. */
             if (!EmitFunctionScript(cx, &bce2, pn->pn_body))
                 return false;
 
             if (funbox->usesArguments && funbox->usesApply && funbox->usesThis)
@@ -6899,17 +6893,17 @@ EmitLexicalInitialization(ExclusiveConte
     if (!BindNameToSlot(cx, bce, pn))
         return false;
 
     jsatomid atomIndex;
     if (!MaybeEmitVarDecl(cx, bce, globalDefOp, pn, &atomIndex))
         return false;
 
     if (pn->getOp() != JSOP_INITLEXICAL) {
-        bool global = IsGlobalOp(pn->getOp());
+        bool global = js_CodeSpec[pn->getOp()].format & JOF_GNAME;
         if (!EmitIndex32(cx, global ? JSOP_BINDGNAME : JSOP_BINDNAME, atomIndex, bce))
             return false;
         if (Emit1(cx, bce, JSOP_SWAP) < 0)
             return false;
     }
 
     if (!pn->pn_cookie.isFree()) {
         if (!EmitVarOp(cx, pn, pn->getOp(), bce))
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -169,18 +169,18 @@ struct BytecodeEmitter
     bool            emittingRunOnceLambda:1; /* true while emitting a lambda which is only
                                                 expected to run once. */
 
     bool isRunOnceLambda();
 
     bool            insideEval:1;       /* True if compiling an eval-expression or a function
                                            nested inside an eval. */
 
-    const bool      insideNonGlobalEval:1;  /* True if this is a direct eval
-                                               call in some non-global scope. */
+    const bool      hasGlobalScope:1;   /* frontend::CompileScript's scope chain is the
+                                           global object */
 
     enum EmitterMode {
         Normal,
 
         /*
          * Emit JSOP_GETINTRINSIC instead of JSOP_GETNAME and assert that
          * JSOP_GETNAME and JSOP_*GNAME don't ever get emitted. See the comment
          * for the field |selfHostingMode| in Parser.h for details.
@@ -200,17 +200,17 @@ struct BytecodeEmitter
      * Note that BytecodeEmitters are magic: they own the arena "top-of-stack"
      * space above their tempMark points. This means that you cannot alloc from
      * tempLifoAlloc and save the pointer beyond the next BytecodeEmitter
      * destruction.
      */
     BytecodeEmitter(BytecodeEmitter *parent, Parser<FullParseHandler> *parser, SharedContext *sc,
                     HandleScript script, Handle<LazyScript *> lazyScript,
                     bool insideEval, HandleScript evalCaller,
-                    Handle<StaticEvalObject *> evalStaticScope, bool insideNonGlobalEval,
+                    Handle<StaticEvalObject *> evalStaticScope, bool hasGlobalScope,
                     uint32_t lineNum, EmitterMode emitterMode = Normal);
     bool init();
     bool updateLocalsToFrameSlots();
 
     bool isAliasedName(ParseNode *pn);
 
     MOZ_ALWAYS_INLINE
     bool makeAtomIndex(JSAtom *atom, jsatomid *indexp) {
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug1106982-2.js
+++ /dev/null
@@ -1,20 +0,0 @@
-var x = "wrong";
-var t = {x: "x"};
-var hits = 0;
-var p = new Proxy(t, {
-    has(t, id) {
-        var found = id in t;
-        if (++hits == 2)
-            delete t[id];
-        return found;
-    },
-    get(t, id) { return t[id]; }
-});
-evaluate(`function testFunc() {
-    x += " x";
-}`, { compileAndGo: false });
-
-var cloneFunc = clone(testFunc, p);
-cloneFunc();
-assertEq(hits, 2);
-assertEq(t.x, "undefined x");
--- a/js/src/jit-test/tests/basic/bug1106982.js
+++ b/js/src/jit-test/tests/basic/bug1106982.js
@@ -7,13 +7,10 @@ var p = new Proxy(t, {
         if (++hits == 2)
             delete t[id];
         return found;
     },
     get(t, id) { return t[id]; }
 });
 with (p)
     x += " x";
-// If you change this testcase (e.g. because we fix the number of
-// has() calls we end up making to match spec better), don't forget to
-// update bug1106982-2.js too.  See also bug 1145641.
 assertEq(hits, 2);
 assertEq(t.x, "undefined x");
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/eval-scopes.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var x = "outer";
-
-setLazyParsingEnabled(false);
-{
-    let x = "inner";
-    eval("function g() { assertEq(x, 'inner');} g()");
-}
-setLazyParsingEnabled(true);
-
-{
-    let x = "inner";
-    eval("function h() { assertEq(x, 'inner');} h()");
-}
-
-setLazyParsingEnabled(false);
-with ({}) {
-    let x = "inner";
-    eval("function i() { assertEq(x, 'inner');} i()");
-}
-setLazyParsingEnabled(true);
-
-with ({}) {
-    let x = "inner";
-    eval("function j() { assertEq(x, 'inner');} j()");
-}
-
-setLazyParsingEnabled(false);
-(function () {
-    var x = "inner";
-    eval("function k() { assertEq(x, 'inner');} k()");
-})();
-setLazyParsingEnabled(true);
-
-(function () {
-    let x = "inner";
-    eval("function l() { assertEq(x, 'inner');} l()");
-})();
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/weird-scopechains.js
+++ /dev/null
@@ -1,36 +0,0 @@
-function checkNameLookup() {
-    return "global";
-}
-
-function assertWithMessage(got, expected, message) {
-    assertEq(message + ": " + got, message + ": " + expected);
-}
-
-// Create our test func via "evaluate" so it won't be compileAndGo and
-// we can clone it.
-evaluate(`function testFunc() {
-    assertWithMessage(checkNameLookup(), "local", "nameLookup");
-    assertWithMessage(checkThisBinding(), "local", "thisBinding");
-
-    // Important: lambda needs to close over "reason", so it won't just get the
-    // scope of testFunc as its scope.  Instead it'll get the Call object
-    // "reason" lives in.
-    var reason = " in lambda in Call";
-    (function() {
-	assertWithMessage(checkNameLookup(), "local", "nameLookup" + reason);
-	assertWithMessage(checkThisBinding(), "local", "thisBinding" + reason);
-    })();
-}`, { compileAndGo: false });
-
-var obj = {
-    checkNameLookup: function() {
-	return "local";
-    },
-
-    checkThisBinding: function() {
-	return this.checkNameLookup();
-    },
-};
-
-var cloneFunc = clone(testFunc, obj);
-cloneFunc();
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -2051,19 +2051,16 @@ BaselineCompiler::emit_JSOP_IN()
 
     frame.push(R0);
     return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_GETGNAME()
 {
-    if (script->hasPollutedGlobalScope())
-        return emit_JSOP_GETNAME();
-
     RootedPropertyName name(cx, script->getName(pc));
 
     if (name == cx->names().undefined) {
         frame.push(UndefinedValue());
         return true;
     }
     if (name == cx->names().NaN) {
         frame.push(cx->runtime()->NaNValue);
@@ -2086,22 +2083,18 @@ BaselineCompiler::emit_JSOP_GETGNAME()
     // Mark R0 as pushed stack value.
     frame.push(R0);
     return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_BINDGNAME()
 {
-    if (!script->hasPollutedGlobalScope()) {
-        frame.push(ObjectValue(script->global()));
-        return true;
-    }
-
-    return emit_JSOP_BINDNAME();
+    frame.push(ObjectValue(script->global()));
+    return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_SETPROP()
 {
     // Keep lhs in R0, rhs in R1.
     frame.popRegsAndSync(2);
 
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -6056,18 +6056,16 @@ DoGetNameFallback(JSContext *cx, Baselin
     jsbytecode *pc = stub->icEntry()->pc(script);
     mozilla::DebugOnly<JSOp> op = JSOp(*pc);
     FallbackICSpew(cx, stub, "GetName(%s)", js_CodeName[JSOp(*pc)]);
 
     MOZ_ASSERT(op == JSOP_GETNAME || op == JSOP_GETGNAME);
 
     RootedPropertyName name(cx, script->getName(pc));
 
-    static_assert(JSOP_GETGNAME_LENGTH == JSOP_GETNAME_LENGTH,
-                  "Otherwise our check for JSOP_TYPEOF isn't ok");
     if (JSOp(pc[JSOP_GETGNAME_LENGTH]) == JSOP_TYPEOF) {
         if (!GetScopeNameForTypeOf(cx, scopeChain, name, res))
             return false;
     } else {
         if (!GetScopeName(cx, scopeChain, name, res))
             return false;
     }
 
@@ -6084,17 +6082,17 @@ DoGetNameFallback(JSContext *cx, Baselin
     // Attach new stub.
     if (stub->numOptimizedStubs() >= ICGetName_Fallback::MAX_OPTIMIZED_STUBS) {
         // TODO: Discard all stubs in this IC and replace with generic stub.
         return true;
     }
 
     bool attached = false;
     bool isTemporarilyUnoptimizable = false;
-    if (IsGlobalOp(JSOp(*pc)) && !script->hasPollutedGlobalScope()) {
+    if (js_CodeSpec[*pc].format & JOF_GNAME) {
         Handle<GlobalObject*> global = scopeChain.as<GlobalObject>();
         if (!TryAttachGlobalNameStub(cx, script, pc, stub, global, name, &attached,
                                      &isTemporarilyUnoptimizable))
         {
             return false;
         }
     } else {
         if (!TryAttachScopeNameStub(cx, script, stub, scopeChain, name, &attached))
@@ -6199,17 +6197,17 @@ ICGetName_Scope<NumHops>::Compiler::gene
 static bool
 DoBindNameFallback(JSContext *cx, BaselineFrame *frame, ICBindName_Fallback *stub,
                    HandleObject scopeChain, MutableHandleValue res)
 {
     jsbytecode *pc = stub->icEntry()->pc(frame->script());
     mozilla::DebugOnly<JSOp> op = JSOp(*pc);
     FallbackICSpew(cx, stub, "BindName(%s)", js_CodeName[JSOp(*pc)]);
 
-    MOZ_ASSERT(op == JSOP_BINDNAME || op == JSOP_BINDGNAME);
+    MOZ_ASSERT(op == JSOP_BINDNAME);
 
     RootedPropertyName name(cx, frame->script()->getName(pc));
 
     RootedObject scope(cx);
     if (!LookupNameUnqualified(cx, name, scopeChain, &scope))
         return false;
 
     res.setObject(*scope);
--- a/js/src/jit/BytecodeAnalysis.cpp
+++ b/js/src/jit/BytecodeAnalysis.cpp
@@ -146,36 +146,28 @@ BytecodeAnalysis::init(TempAllocator &al
                 if (catchFinallyRanges[i].contains(offset))
                     infos_[offset].loopEntryInCatchOrFinally = true;
             }
             break;
 
           case JSOP_GETNAME:
           case JSOP_BINDNAME:
           case JSOP_SETNAME:
-          case JSOP_STRICTSETNAME:
           case JSOP_DELNAME:
           case JSOP_GETALIASEDVAR:
           case JSOP_SETALIASEDVAR:
           case JSOP_LAMBDA:
           case JSOP_LAMBDA_ARROW:
           case JSOP_DEFFUN:
           case JSOP_DEFVAR:
           case JSOP_DEFCONST:
           case JSOP_SETCONST:
             usesScopeChain_ = true;
             break;
 
-          case JSOP_GETGNAME:
-          case JSOP_SETGNAME:
-          case JSOP_STRICTSETGNAME:
-            if (script_->hasPollutedGlobalScope())
-                usesScopeChain_ = true;
-            break;
-
           case JSOP_FINALLY:
             hasTryFinally_ = true;
             break;
 
           case JSOP_SETARG:
             hasSetArg_ = true;
             break;
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1813,47 +1813,42 @@ IonBuilder::inspectOpcode(JSOp op)
         return pushConstant(Int32Value(GET_INT8(pc)));
 
       case JSOP_UINT16:
         return pushConstant(Int32Value(GET_UINT16(pc)));
 
       case JSOP_GETGNAME:
       {
         PropertyName *name = info().getAtom(pc)->asPropertyName();
-        if (!script()->hasPollutedGlobalScope())
-            return jsop_getgname(name);
-        return jsop_getname(name);
+        return jsop_getgname(name);
       }
 
+      case JSOP_BINDGNAME:
+        return pushConstant(ObjectValue(script()->global()));
+
       case JSOP_SETGNAME:
       case JSOP_STRICTSETGNAME:
       {
         PropertyName *name = info().getAtom(pc)->asPropertyName();
-        if (script()->hasPollutedGlobalScope())
-            return jsop_setprop(name);
         JSObject *obj = &script()->global();
         return setStaticName(obj, name);
       }
 
       case JSOP_GETNAME:
       {
         PropertyName *name = info().getAtom(pc)->asPropertyName();
         return jsop_getname(name);
       }
 
       case JSOP_GETINTRINSIC:
       {
         PropertyName *name = info().getAtom(pc)->asPropertyName();
         return jsop_intrinsic(name);
       }
 
-      case JSOP_BINDGNAME:
-        if (!script()->hasPollutedGlobalScope())
-            return pushConstant(ObjectValue(script()->global()));
-        // Fall through to JSOP_BINDNAME
       case JSOP_BINDNAME:
         return jsop_bindname(info().getName(pc));
 
       case JSOP_DUP:
         current->pushSlot(current->stackDepth() - 1);
         return true;
 
       case JSOP_DUP2:
@@ -7570,17 +7565,17 @@ IonBuilder::jsop_getgname(PropertyName *
 
     return jsop_getname(name);
 }
 
 bool
 IonBuilder::jsop_getname(PropertyName *name)
 {
     MDefinition *object;
-    if (IsGlobalOp(JSOp(*pc)) && !script()->hasPollutedGlobalScope()) {
+    if (js_CodeSpec[*pc].format & JOF_GNAME) {
         MInstruction *global = constant(ObjectValue(script()->global()));
         object = global;
     } else {
         current->push(current->scopeChain());
         object = current->pop();
     }
 
     MGetNameCache *ins;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -638,18 +638,17 @@ js::XDRInterpretedFunction(XDRState<mode
 
 template bool
 js::XDRInterpretedFunction(XDRState<XDR_ENCODE> *, HandleObject, HandleScript, MutableHandleFunction);
 
 template bool
 js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, MutableHandleFunction);
 
 JSObject *
-js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun,
-                           PollutedGlobalScopeOption polluted)
+js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun)
 {
     /* NB: Keep this in sync with XDRInterpretedFunction. */
     RootedObject cloneProto(cx);
     if (srcFun->isStarGenerator()) {
         cloneProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, cx->global());
         if (!cloneProto)
             return nullptr;
     }
@@ -661,17 +660,17 @@ js::CloneFunctionAndScript(JSContext *cx
                                                   JSFunction::INTERPRETED, NullPtr(), NullPtr(),
                                                   cloneProto, allocKind, TenuredObject));
     if (!clone)
         return nullptr;
 
     RootedScript srcScript(cx, srcFun->getOrCreateScript(cx));
     if (!srcScript)
         return nullptr;
-    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript, polluted));
+    RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript));
     if (!clonedScript)
         return nullptr;
 
     clone->setArgCount(srcFun->nargs());
     clone->setFlags(srcFun->flags());
     clone->initAtom(srcFun->displayAtom());
     clone->initScript(clonedScript);
     clonedScript->setFunction(clone);
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -649,18 +649,17 @@ namespace js {
 JSString *FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen);
 
 template<XDRMode mode>
 bool
 XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope,
                        HandleScript enclosingScript, MutableHandleFunction objp);
 
 extern JSObject *
-CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
-                       PollutedGlobalScopeOption polluted);
+CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);
 
 /*
  * Report an error that call.thisv is not compatible with the specified class,
  * assuming that the method (clasp->name).prototype.<name of callee function>
  * is what was called.
  */
 extern void
 ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3026,17 +3026,17 @@ js::CloneScript(JSContext *cx, HandleObj
                     RootedObject enclosingScope(cx);
                     if (ssi.done() || ssi.type() == StaticScopeIter<CanGC>::Function)
                         enclosingScope = fun;
                     else if (ssi.type() == StaticScopeIter<CanGC>::Block)
                         enclosingScope = objects[FindScopeObjectIndex(src, ssi.block())];
                     else
                         enclosingScope = objects[FindScopeObjectIndex(src, ssi.staticWith())];
 
-                    clone = CloneFunctionAndScript(cx, enclosingScope, innerFun, polluted);
+                    clone = CloneFunctionAndScript(cx, enclosingScope, innerFun);
                 }
             } else {
                 /*
                  * Clone object literals emitted for the JSOP_NEWOBJECT opcode. We only emit that
                  * instead of the less-optimized JSOP_NEWINIT for self-hosted code or code compiled
                  * with JSOPTION_COMPILE_N_GO set. As we don't clone the latter type of code, this
                  * case should only ever be hit when cloning objects from self-hosted code.
                  */
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -298,20 +298,18 @@ SetAliasedVarOperation(JSContext *cx, JS
 inline bool
 SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject scope,
                  HandleValue val)
 {
     MOZ_ASSERT(*pc == JSOP_SETNAME ||
                *pc == JSOP_STRICTSETNAME ||
                *pc == JSOP_SETGNAME ||
                *pc == JSOP_STRICTSETGNAME);
-    MOZ_ASSERT_IF(*pc == JSOP_SETGNAME && !script->hasPollutedGlobalScope(),
-                  scope == cx->global());
-    MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME && !script->hasPollutedGlobalScope(),
-                  scope == cx->global());
+    MOZ_ASSERT_IF(*pc == JSOP_SETGNAME, scope == cx->global());
+    MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME, scope == cx->global());
 
     bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME;
     RootedPropertyName name(cx, script->getName(pc));
     RootedValue valCopy(cx, val);
 
     // In strict mode, assigning to an undeclared global variable is an
     // error. To detect this, we call NativeSetProperty directly and pass
     // Unqualified. It stores the error, if any, in |result|.
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -283,17 +283,17 @@ GetNameOperation(JSContext *cx, Interpre
      * Skip along the scope chain to the enclosing global object. This is
      * used for GNAME opcodes where the bytecode emitter has determined a
      * name access must be on the global. It also insulates us from bugs
      * in the emitter: type inference will assume that GNAME opcodes are
      * accessing the global object, and the inferred behavior should match
      * the actual behavior even if the id could be found on the scope chain
      * before the global object.
      */
-    if (IsGlobalOp(JSOp(*pc)) && !fp->script()->hasPollutedGlobalScope())
+    if (IsGlobalOp(JSOp(*pc)))
         obj = &obj->global();
 
     Shape *shape = nullptr;
     JSObject *scope = nullptr, *pobj = nullptr;
     if (LookupNameNoGC(cx, name, obj, &scope, &pobj, &shape)) {
         if (FetchNameNoGC(pobj, shape, vp))
             return CheckUninitializedLexical(cx, name, vp);
     }
@@ -2033,43 +2033,38 @@ CASE(JSOP_SETCONST)
     RootedObject &obj = rootObject0;
     obj = &REGS.fp()->varObj();
 
     if (!SetConstOperation(cx, obj, name, rval))
         goto error;
 }
 END_CASE(JSOP_SETCONST)
 
+CASE(JSOP_BINDGNAME)
+    PUSH_OBJECT(REGS.fp()->global());
+END_CASE(JSOP_BINDGNAME)
+
 CASE(JSOP_BINDINTRINSIC)
     PUSH_OBJECT(*cx->global()->intrinsicsHolder());
 END_CASE(JSOP_BINDINTRINSIC)
 
-CASE(JSOP_BINDGNAME)
 CASE(JSOP_BINDNAME)
 {
-    JSOp op = JSOp(*REGS.pc);
-    if (op == JSOP_BINDNAME || script->hasPollutedGlobalScope()) {
-        RootedObject &scopeChain = rootObject0;
-        scopeChain = REGS.fp()->scopeChain();
-
-        RootedPropertyName &name = rootName0;
-        name = script->getName(REGS.pc);
-
-        /* Assigning to an undeclared name adds a property to the global object. */
-        RootedObject &scope = rootObject1;
-        if (!LookupNameUnqualified(cx, name, scopeChain, &scope))
-            goto error;
-
-        PUSH_OBJECT(*scope);
-    } else {
-        PUSH_OBJECT(REGS.fp()->global());
-    }
-
-    static_assert(JSOP_BINDNAME_LENGTH == JSOP_BINDGNAME_LENGTH,
-                  "We're sharing the END_CASE so the lengths better match");
+    RootedObject &scopeChain = rootObject0;
+    scopeChain = REGS.fp()->scopeChain();
+
+    RootedPropertyName &name = rootName0;
+    name = script->getName(REGS.pc);
+
+    /* Assigning to an undeclared name adds a property to the global object. */
+    RootedObject &scope = rootObject1;
+    if (!LookupNameUnqualified(cx, name, scopeChain, &scope))
+        goto error;
+
+    PUSH_OBJECT(*scope);
 }
 END_CASE(JSOP_BINDNAME)
 
 #define BITWISE_OP(OP)                                                        \
     JS_BEGIN_MACRO                                                            \
         int32_t i, j;                                                         \
         if (!ToInt32(cx, REGS.stackHandleAt(-2), &i))                         \
             goto error;                                                       \
@@ -2466,19 +2461,16 @@ CASE(JSOP_SETGNAME)
 CASE(JSOP_STRICTSETGNAME)
 CASE(JSOP_SETNAME)
 CASE(JSOP_STRICTSETNAME)
 {
     static_assert(JSOP_SETNAME_LENGTH == JSOP_STRICTSETNAME_LENGTH,
                   "setname and strictsetname must be the same size");
     static_assert(JSOP_SETGNAME_LENGTH == JSOP_STRICTSETGNAME_LENGTH,
                   "setganem adn strictsetgname must be the same size");
-    static_assert(JSOP_SETNAME_LENGTH == JSOP_SETGNAME_LENGTH,
-                  "We're sharing the END_CASE so the lengths better match");
-
     RootedObject &scope = rootObject0;
     scope = &REGS.sp[-2].toObject();
     HandleValue value = REGS.stackHandleAt(-1);
 
     if (!SetNameOperation(cx, script, REGS.pc, scope, value))
         goto error;
 
     REGS.sp[-2] = REGS.sp[-1];
@@ -2724,33 +2716,29 @@ CASE(JSOP_GIMPLICITTHIS)
         RootedValue &v = rootValue0;
         if (!ComputeImplicitThis(cx, scope, &v))
             goto error;
         PUSH_COPY(v);
     } else {
         // Treat it like JSOP_UNDEFINED.
         PUSH_UNDEFINED();
     }
-    static_assert(JSOP_IMPLICITTHIS_LENGTH == JSOP_GIMPLICITTHIS_LENGTH,
-                  "We're sharing the END_CASE so the lengths better match");
 }
 END_CASE(JSOP_IMPLICITTHIS)
 
 CASE(JSOP_GETGNAME)
 CASE(JSOP_GETNAME)
 {
     RootedValue &rval = rootValue0;
 
     if (!GetNameOperation(cx, REGS.fp(), REGS.pc, &rval))
         goto error;
 
     PUSH_COPY(rval);
     TypeScript::Monitor(cx, script, REGS.pc, rval);
-    static_assert(JSOP_GETNAME_LENGTH == JSOP_GETGNAME_LENGTH,
-                  "We're sharing the END_CASE so the lengths better match");
 }
 END_CASE(JSOP_GETNAME)
 
 CASE(JSOP_GETINTRINSIC)
 {
     RootedValue &rval = rootValue0;
 
     if (!GetIntrinsicOperation(cx, REGS.pc, &rval))
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -1494,48 +1494,44 @@ 1234567890123456789012345678901234567890
      *   Category: Statements
      *   Type: Function
      *   Operands:
      *   Stack: =>
      */ \
     macro(JSOP_RETRVAL,       153,"retrval",    NULL,       1,  0,  0,  JOF_BYTE) \
     \
     /*
-     * Looks up name on global scope and pushes its value onto the stack, unless
-     * the script has a polluted global, in which case it acts just like
-     * JSOP_NAME.
+     * Looks up name on global scope and pushes its value onto the stack.
      *
      * Free variable references that must either be found on the global or a
      * ReferenceError.
      *   Category: Variables and Scopes
      *   Type: Free Variables
      *   Operands: uint32_t nameIndex
      *   Stack: => val
      */ \
     macro(JSOP_GETGNAME,      154,"getgname",  NULL,       5,  0,  1, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME) \
     /*
      * Pops the top two values on the stack as 'val' and 'scope', sets property
      * of 'scope' as 'val' and pushes 'val' back on the stack.
      *
-     * 'scope' should be the global scope unless the script has a polluted
-     * global scope, in which case acts like JSOP_SETNAME.
+     * 'scope' should be the global scope.
      *   Category: Variables and Scopes
      *   Type: Free Variables
      *   Operands: uint32_t nameIndex
      *   Stack: scope, val => val
      */ \
     macro(JSOP_SETGNAME,      155,"setgname",  NULL,       5,  2,  1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSLOPPY) \
     \
     /*
      * Pops the top two values on the stack as 'val' and 'scope', sets property
      * of 'scope' as 'val' and pushes 'val' back on the stack. Throws a
      * TypeError if the set fails, per strict mode semantics.
      *
-     * 'scope' should be the global scope unless the script has a polluted
-     * global scope, in which case acts like JSOP_STRICTSETNAME.
+     * 'scope' should be the global scope.
      *   Category: Variables and Scopes
      *   Type: Free Variables
      *   Operands: uint32_t nameIndex
      *   Stack: scope, val => val
      */ \
     macro(JSOP_STRICTSETGNAME, 156, "strict-setgname",  NULL,       5,  2,  1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSTRICT) \
     /*
      * Pushes the implicit 'this' value for calls to the associated name onto
@@ -1768,20 +1764,19 @@ 1234567890123456789012345678901234567890
      */ \
     macro(JSOP_DEBUGAFTERYIELD,  208, "debugafteryield",  NULL,  1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED209,     209, "unused209",    NULL,  1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED210,     210, "unused210",    NULL,  1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED211,     211, "unused211",    NULL,  1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED212,     212, "unused212",    NULL,  1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED213,     213, "unused213",    NULL,  1,  0,  0,  JOF_BYTE) \
     /*
-     * Pushes the global scope onto the stack if the script doesn't have a
-     * polluted global scope.  Otherwise will act like JSOP_BINDNAME.
+     * Pushes the global scope onto the stack.
      *
-     * 'nameIndex' is only used when acting like JSOP_BINDNAME.
+     * 'nameIndex' is not used.
      *   Category: Variables and Scopes
      *   Type: Free Variables
      *   Operands: uint32_t nameIndex
      *   Stack: => global
      */ \
     macro(JSOP_BINDGNAME,     214, "bindgname",    NULL,  5,  0,  1,  JOF_ATOM|JOF_NAME|JOF_SET|JOF_GNAME) \
     \
     /*
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -2563,29 +2563,19 @@ RemoveReferencedNames(JSContext *cx, Han
     //   care about entraining variables unnecessarily.
 
     for (jsbytecode *pc = script->code(); pc != script->codeEnd(); pc += GetBytecodeLength(pc)) {
         PropertyName *name;
 
         switch (JSOp(*pc)) {
           case JSOP_GETNAME:
           case JSOP_SETNAME:
-          case JSOP_STRICTSETNAME:
             name = script->getName(pc);
             break;
 
-          case JSOP_GETGNAME:
-          case JSOP_SETGNAME:
-          case JSOP_STRICTSETGNAME:
-            if (script->hasPollutedGlobalScope())
-                name = script->getName(pc);
-            else
-                name = nullptr;
-            break;
-
           case JSOP_GETALIASEDVAR:
           case JSOP_SETALIASEDVAR:
             name = ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc);
             break;
 
           default:
             name = nullptr;
             break;
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -24,17 +24,17 @@ namespace js {
  * versions.  If deserialization fails, the data should be invalidated if
  * possible.
  *
  * When you change this, run make_opcode_doc.py and copy the new output into
  * this wiki page:
  *
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  */
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 267;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 265;
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
 
 static_assert(JSErr_Limit == 388,
               "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
               "removed MSG_DEFs from js.msg, you should increment "
               "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
               "expected JSErr_Limit value.");