void
GlobalObject::clear(JSContext *cx)
{
    for (int key = JSProto_Null; key < JSProto_LIMIT * 3; key++)
        setSlot(key, UndefinedValue());

    /* Clear regexp statics. */
    getRegExpStatics()->clear();

    /* Clear the runtime-codegen-enabled cache. */
    setSlot(RUNTIME_CODEGEN_ENABLED, UndefinedValue());

    /*
     * Clear all slots storing values in case throwing trying to execute a
     * script for this global must reinitialize standard classes.  See
     * bug 470150.
     */
    setSlot(BOOLEAN_VALUEOF, UndefinedValue());
    setSlot(EVAL, UndefinedValue());
    setSlot(CREATE_DATAVIEW_FOR_THIS, UndefinedValue());
    setSlot(THROWTYPEERROR, UndefinedValue());
    setSlot(INTRINSICS, UndefinedValue());
    setSlot(PROTO_GETTER, UndefinedValue());

    /*
     * Mark global as cleared. If we try to execute any compile-and-go
     * scripts from here on, we will throw.
     */
    int32_t flags = getSlot(FLAGS).toInt32();
    flags |= FLAGS_CLEARED;
    setSlot(FLAGS, Int32Value(flags));

    /*
     * Reset the new object cache in the compartment, which assumes that
     * prototypes cached on the global object are immutable.
     */
    cx->runtime->newObjectCache.purge();

#ifdef JS_METHODJIT
    /*
     * Destroy compiled code for any scripts parented to this global. Call ICs
     * can directly call scripts which have associated JIT code, and do so
     * without checking whether the script's global has been cleared.
     */
    for (gc::CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
        JSScript *script = i.get<JSScript>();
        if (script->compileAndGo && script->hasMJITInfo() && script->hasClearedGlobal()) {
            mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
            mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
        }
    }
#endif
}