Bug 739808: Remove method cloning optimization and method barrier, r=luke
authorDavid Mandelin <dmandelin@mozilla.com>
Fri, 23 Mar 2012 17:59:56 -0700
changeset 90467 a09e61d9c648
parent 90466 9d39733e4683
child 90468 15d5cdd96147
push id7678
push userdmandelin@mozilla.com
push dateWed, 28 Mar 2012 00:15:47 +0000
treeherdermozilla-inbound@a09e61d9c648 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs739808
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 739808: Remove method cloning optimization and method barrier, r=luke
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/SemanticAnalysis.cpp
js/src/jit-test/tests/basic/testInitDictionary.js
js/src/jsanalyze.cpp
js/src/jsapi-tests/testLookup.cpp
js/src/jsapi.cpp
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsfuninlines.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/jspropertytree.cpp
js/src/jsscope.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsstr.cpp
js/src/jswatchpoint.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/PolyIC.h
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4561,53 +4561,16 @@ EmitWith(JSContext *cx, BytecodeEmitter 
     if (!EmitTree(cx, bce, pn->pn_right))
         return false;
     if (Emit1(cx, bce, JSOP_LEAVEWITH) < 0)
         return false;
     return PopStatementBCE(cx, bce);
 }
 
 static bool
-SetMethodFunction(JSContext *cx, FunctionBox *funbox, JSAtom *atom)
-{
-    RootedVarObject parent(cx);
-    parent = funbox->function()->getParent();
-
-    /*
-     * Replace a boxed function with a new one with a method atom. Methods
-     * require a function with the extended size finalize kind, which normal
-     * functions don't have. We don't eagerly allocate functions with the
-     * expanded size for boxed functions, as most functions are not methods.
-     */
-    JSFunction *fun = js_NewFunction(cx, NULL, NULL,
-                                     funbox->function()->nargs,
-                                     funbox->function()->flags,
-                                     parent,
-                                     funbox->function()->atom,
-                                     JSFunction::ExtendedFinalizeKind);
-    if (!fun)
-        return false;
-
-    JSScript *script = funbox->function()->script();
-    if (script) {
-        fun->setScript(script);
-        if (!script->typeSetFunction(cx, fun))
-            return false;
-    }
-
-    JS_ASSERT(funbox->function()->joinable());
-    fun->setJoinable();
-
-    fun->setMethodAtom(atom);
-
-    funbox->object = fun;
-    return true;
-}
-
-static bool
 EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
 {
     StmtInfo stmtInfo;
     PushStatement(bce, &stmtInfo, STMT_FOR_IN_LOOP, top);
 
     ParseNode *forHead = pn->pn_left;
     ParseNode *forBody = pn->pn_right;
 
@@ -5366,33 +5329,16 @@ EmitStatement(JSContext *cx, BytecodeEmi
         if (!wantval &&
             pn2->isKind(PNK_ASSIGN) &&
             !MaybeEmitGroupAssignment(cx, bce, op, pn2, &op))
         {
             return false;
         }
 #endif
         if (op != JSOP_NOP) {
-            /*
-             * Specialize JSOP_SETPROP to JSOP_SETMETHOD to defer or
-             * avoid null closure cloning. Do this only for assignment
-             * statements that are not completion values wanted by a
-             * script evaluator, to ensure that the joined function
-             * can't escape directly.
-             */
-            if (!wantval &&
-                pn2->isKind(PNK_ASSIGN) &&
-                pn2->pn_left->isOp(JSOP_SETPROP) &&
-                pn2->pn_right->isOp(JSOP_LAMBDA) &&
-                pn2->pn_right->pn_funbox->joinable())
-            {
-                if (!SetMethodFunction(cx, pn2->pn_right->pn_funbox, pn2->pn_left->pn_atom))
-                    return false;
-                pn2->pn_left->setOp(JSOP_SETMETHOD);
-            }
             if (!EmitTree(cx, bce, pn2))
                 return false;
             if (Emit1(cx, bce, op) < 0)
                 return false;
         }
     } else if (!pn->isDirectivePrologueMember()) {
         /* Don't complain about directive prologue members; just don't emit their code. */
         bce->current->currentLine = pn2->pn_pos.begin.lineno;
@@ -5889,38 +5835,23 @@ EmitObject(JSContext *cx, BytecodeEmitte
             if (Emit1(cx, bce, JSOP_INITELEM) < 0)
                 return false;
         } else {
             JS_ASSERT(pn3->isKind(PNK_NAME) || pn3->isKind(PNK_STRING));
             jsatomid index;
             if (!bce->makeAtomIndex(pn3->pn_atom, &index))
                 return false;
 
-            /* Check whether we can optimize to JSOP_INITMETHOD. */
-            ParseNode *init = pn2->pn_right;
-            bool lambda = init->isOp(JSOP_LAMBDA);
-            if (lambda)
-                ++methodInits;
-            if (op == JSOP_INITPROP && lambda && init->pn_funbox->joinable()) {
+            /*
+             * Disable NEWOBJECT on initializers that set __proto__, which has
+             * a non-standard setter on objects.
+             */
+            if (pn3->pn_atom == cx->runtime->atomState.protoAtom)
                 obj = NULL;
-                op = JSOP_INITMETHOD;
-                if (!SetMethodFunction(cx, init->pn_funbox, pn3->pn_atom))
-                    return JS_FALSE;
-                pn2->setOp(op);
-            } else {
-                /*
-                 * Disable NEWOBJECT on initializers that set __proto__, which has
-                 * a non-standard setter on objects.
-                 */
-                if (pn3->pn_atom == cx->runtime->atomState.protoAtom)
-                    obj = NULL;
-                op = JSOP_INITPROP;
-                if (lambda)
-                    ++slowMethodInits;
-            }
+            op = JSOP_INITPROP;
 
             if (obj) {
                 JS_ASSERT(!obj->inDictionaryMode());
                 if (!DefineNativeProperty(cx, obj, ATOM_TO_JSID(pn3->pn_atom),
                                           UndefinedValue(), NULL, NULL,
                                           JSPROP_ENUMERATE, 0, 0))
                 {
                     return false;
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -104,25 +104,16 @@ ParseNode::clear()
     pn_type = PNK_LIMIT;
     setOp(JSOP_NOP);
     pn_used = pn_defn = false;
     pn_arity = PN_NULLARY;
     pn_parens = false;
 }
 
 bool
-FunctionBox::joinable() const
-{
-    return function()->isNullClosure() &&
-           (tcflags & (TCF_FUN_USES_ARGUMENTS |
-                       TCF_FUN_USES_OWN_NAME |
-                       TCF_COMPILE_N_GO)) == TCF_COMPILE_N_GO;
-}
-
-bool
 FunctionBox::inAnyDynamicScope() const
 {
     for (const FunctionBox *funbox = this; funbox; funbox = funbox->parent) {
         if (funbox->tcflags & (TCF_IN_WITH | TCF_FUN_EXTENSIBLE_SCOPE))
             return true;
     }
     return false;
 }
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -1549,18 +1549,16 @@ struct FunctionBox : public ObjectBox
     Bindings            bindings;               /* bindings for this function */
     uint32_t            queued:1,
                         inLoop:1,               /* in a loop in parent function */
                         level:JSFB_LEVEL_BITS;
     uint32_t            tcflags;
 
     JSFunction *function() const { return (JSFunction *) object; }
 
-    bool joinable() const;
-
     /*
      * True if this function is inside the scope of a with-statement, an E4X
      * filter-expression, or a function that uses direct eval.
      */
     bool inAnyDynamicScope() const;
 
     /* 
      * Must this function's descendants be marked as having an extensible
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1064,18 +1064,16 @@ LeaveFunction(ParseNode *fn, TreeContext
             JSAtom *atom = r.front().key();
             Definition *dn = r.front().value();
             JS_ASSERT(dn->isPlaceholder());
 
             if (atom == funName && kind == Expression) {
                 dn->setOp(JSOP_CALLEE);
                 dn->pn_cookie.set(funtc->staticLevel, UpvarCookie::CALLEE_SLOT);
                 dn->pn_dflags |= PND_BOUND;
-
-                funbox->tcflags |= TCF_FUN_USES_OWN_NAME;
                 foundCallee = 1;
                 continue;
             }
 
             Definition *outer_dn = tc->decls.lookupFirst(atom);
 
             /*
              * Make sure to deoptimize lexical dependencies that are polluted
@@ -2044,17 +2042,17 @@ DefineGlobal(ParseNode *pn, BytecodeEmit
              *   2) Configurable properties.
              *   3) Properties without slots, or with getters/setters.
              */
             const Shape *shape = (const Shape *)prop;
             if (funbox ||
                 globalObj != holder ||
                 shape->configurable() ||
                 !shape->hasSlot() ||
-                !shape->hasDefaultGetterOrIsMethod() ||
+                !shape->hasDefaultGetter() ||
                 !shape->hasDefaultSetter()) {
                 return true;
             }
 
             def = GlobalScope::GlobalDef(shape->slot());
         } else {
             def = GlobalScope::GlobalDef(name, funbox);
         }
--- a/js/src/frontend/SemanticAnalysis.cpp
+++ b/js/src/frontend/SemanticAnalysis.cpp
@@ -212,19 +212,16 @@ SetFunctionKinds(FunctionBox *funbox, ui
 
             for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
                 Definition *defn = r.front().value();
                 Definition *lexdep = defn->resolve();
                 if (!lexdep->isFreeVar())
                     FlagHeavyweights(lexdep, funbox, tcflags);
             }
         }
-
-        if (funbox->joinable())
-            fun->setJoinable();
     }
 }
 
 /*
  * Walk the FunctionBox tree looking for functions whose call objects may
  * acquire new bindings as they execute: non-strict functions that call eval,
  * and functions that contain function statements (definitions not appearing
  * within the top statement list, which don't take effect unless they are
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/testInitDictionary.js
+++ /dev/null
@@ -1,51 +0,0 @@
-
-var shapes = {};
-
-function stringify(a) {
-  assertEq(shapes[shapeOf(a)], undefined);
-  shapes[shapeOf(a)] = 1;
-  var b = "";
-  for (var c in a) {
-    b += c + ":";
-    if (typeof a[c] == "function")
-      b += "function,";
-    else
-      b += a[c] + ",";
-  }
-  return b;
-}
-
-function test1() {
-  return stringify({a: 0, b: 1, a: function() {} });
-}
-for (var i = 0; i < 3; i++)
-  assertEq(test1(), "a:function,b:1,");
-
-// This does not cause the object to go to dictionary mode, unlike the above.
-function test2() {
-  return stringify({a: 0, b: 1, a: 2, b: 3});
-}
-assertEq(test2(), "a:2,b:3,");
-
-function test3() {
-  return stringify({
-    aa:0,ab:1,ac:2,ad:3,ae:4,af:5,ag:6,ah:7,ai:8,aj:9,
-    ba:0,bb:1,bc:2,bd:3,be:4,bf:5,bg:6,bh:7,bi:8,bj:9,
-    ca:0,cb:1,cc:2,cd:3,ce:4,cf:5,cg:6,ch:7,ci:8,cj:9,
-    da:0,db:1,dc:2,dd:3,de:4,df:5,dg:6,dh:7,di:8,dj:9,
-    ea:0,eb:1,ec:2,ed:3,ee:4,ef:5,eg:6,eh:7,ei:8,ej:9,
-    fa:0,fb:1,fc:2,fd:3,fe:4,ff:5,fg:6,fh:7,fi:8,fj:9,
-    ga:0,gb:1,gc:2,gd:3,ge:4,gf:5,gg:6,gh:7,gi:8,gj:9,
-    ha:0,hb:1,hc:2,hd:3,he:4,hf:5,hg:6,hh:7,hi:8,hj:9,
-    ia:0,ib:1,ic:2,id:3,ie:4,if:5,ig:6,ih:7,ii:8,ij:9,
-    ja:0,jb:1,jc:2,jd:3,je:4,jf:5,jg:6,jh:7,ji:8,jj:9,
-    ka:0,kb:1,kc:2,kd:3,ke:4,kf:5,kg:6,kh:7,ki:8,kj:9,
-    la:0,lb:1,lc:2,ld:3,le:4,lf:5,lg:6,lh:7,li:8,lj:9,
-    ma:0,mb:1,mc:2,md:3,me:4,mf:5,mg:6,mh:7,mi:8,mj:9,
-    na:0,nb:1,nc:2,nd:3,ne:4,nf:5,ng:6,nh:7,ni:8,nj:9,
-    oa:0,ob:1,oc:2,od:3,oe:4,of:5,og:6,oh:7,oi:8,oj:9,
-    pa:0,pb:1,pc:2,pd:3,pe:4,pf:5,pg:6,ph:7,pi:8,pj:9,
-        });
-}
-for (var i = 0; i < 10; i++)
-  assertEq(test3(), "aa:0,ab:1,ac:2,ad:3,ae:4,af:5,ag:6,ah:7,ai:8,aj:9,ba:0,bb:1,bc:2,bd:3,be:4,bf:5,bg:6,bh:7,bi:8,bj:9,ca:0,cb:1,cc:2,cd:3,ce:4,cf:5,cg:6,ch:7,ci:8,cj:9,da:0,db:1,dc:2,dd:3,de:4,df:5,dg:6,dh:7,di:8,dj:9,ea:0,eb:1,ec:2,ed:3,ee:4,ef:5,eg:6,eh:7,ei:8,ej:9,fa:0,fb:1,fc:2,fd:3,fe:4,ff:5,fg:6,fh:7,fi:8,fj:9,ga:0,gb:1,gc:2,gd:3,ge:4,gf:5,gg:6,gh:7,gi:8,gj:9,ha:0,hb:1,hc:2,hd:3,he:4,hf:5,hg:6,hh:7,hi:8,hj:9,ia:0,ib:1,ic:2,id:3,ie:4,if:5,ig:6,ih:7,ii:8,ij:9,ja:0,jb:1,jc:2,jd:3,je:4,jf:5,jg:6,jh:7,ji:8,jj:9,ka:0,kb:1,kc:2,kd:3,ke:4,kf:5,kg:6,kh:7,ki:8,kj:9,la:0,lb:1,lc:2,ld:3,le:4,lf:5,lg:6,lh:7,li:8,lj:9,ma:0,mb:1,mc:2,md:3,me:4,mf:5,mg:6,mh:7,mi:8,mj:9,na:0,nb:1,nc:2,nd:3,ne:4,nf:5,ng:6,nh:7,ni:8,nj:9,oa:0,ob:1,oc:2,od:3,oe:4,of:5,og:6,oh:7,oi:8,oj:9,pa:0,pb:1,pc:2,pd:3,pe:4,pf:5,pg:6,ph:7,pi:8,pj:9,");
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -612,21 +612,19 @@ ScriptAnalysis::analyzeBytecode(JSContex
           case JSOP_GETARG:
           case JSOP_CALLARG:
           case JSOP_BINDGNAME:
           case JSOP_UINT16:
           case JSOP_NEWINIT:
           case JSOP_NEWARRAY:
           case JSOP_NEWOBJECT:
           case JSOP_ENDINIT:
-          case JSOP_INITMETHOD:
           case JSOP_INITPROP:
           case JSOP_INITELEM:
           case JSOP_SETPROP:
-          case JSOP_SETMETHOD:
           case JSOP_IN:
           case JSOP_INSTANCEOF:
           case JSOP_LINENO:
           case JSOP_ENUMELEM:
           case JSOP_CONDSWITCH:
           case JSOP_LABEL:
           case JSOP_RETRVAL:
           case JSOP_GETGNAME:
@@ -1517,17 +1515,16 @@ ScriptAnalysis::analyzeSSA(JSContext *cx
 
           /* Short circuit ops which push back one of their operands. */
 
           case JSOP_MOREITER:
             stack[stackDepth - 2].v = code->poppedValues[0];
             break;
 
           case JSOP_INITPROP:
-          case JSOP_INITMETHOD:
             stack[stackDepth - 1].v = code->poppedValues[1];
             break;
 
           case JSOP_INITELEM:
             stack[stackDepth - 1].v = code->poppedValues[2];
             break;
 
           case JSOP_DUP:
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -23,17 +23,16 @@ BEGIN_TEST(testLookup_bug522590)
 
     // This lookup must not return an internal function object.
     jsvalRoot r(cx);
     CHECK(JS_LookupProperty(cx, xobj, "f", r.addr()));
     CHECK(JSVAL_IS_OBJECT(r));
     JSObject *funobj = JSVAL_TO_OBJECT(r);
     CHECK(funobj->isFunction());
     CHECK(!js::IsInternalFunctionObject(funobj));
-    CHECK(funobj->toFunction()->isClonedMethod());
 
     return true;
 }
 END_TEST(testLookup_bug522590)
 
 JSBool
 document_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags, JSObject **objp)
 {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3450,21 +3450,16 @@ LookupResult(JSContext *cx, JSObject *ob
         /* XXX bad API: no way to tell "not defined" from "void value" */
         vp->setUndefined();
         return JS_TRUE;
     }
 
     if (obj2->isNative()) {
         Shape *shape = (Shape *) prop;
 
-        if (shape->isMethod()) {
-            vp->setObject(*obj2->nativeGetMethod(shape));
-            return !!obj2->methodReadBarrier(cx, *shape, vp);
-        }
-
         /* Peek at the native property's slot value, without doing a Get. */
         if (shape->hasSlot()) {
             *vp = obj2->nativeGetSlot(shape->slot());
             return true;
         }
     } else {
         if (obj2->isDenseArray())
             return js_GetDenseArrayElementValue(cx, obj2, id, vp);
@@ -3850,29 +3845,22 @@ GetPropertyDescriptorById(JSContext *cx,
         desc->value.setUndefined();
         return JS_TRUE;
     }
 
     desc->obj = obj2;
     if (obj2->isNative()) {
         Shape *shape = (Shape *) prop;
         desc->attrs = shape->attributes();
-
-        if (shape->isMethod()) {
-            desc->getter = JS_PropertyStub;
-            desc->setter = JS_StrictPropertyStub;
-            desc->value.setObject(*obj2->nativeGetMethod(shape));
-        } else {
-            desc->getter = shape->getter();
-            desc->setter = shape->setter();
-            if (shape->hasSlot())
-                desc->value = obj2->nativeGetSlot(shape->slot());
-            else
-                desc->value.setUndefined();
-        }
+        desc->getter = shape->getter();
+        desc->setter = shape->setter();
+        if (shape->hasSlot())
+            desc->value = obj2->nativeGetSlot(shape->slot());
+        else
+            desc->value.setUndefined();
     } else {
         if (obj2->isProxy()) {
             JSAutoResolveFlags rf(cx, flags);
             return own
                    ? Proxy::getOwnPropertyDescriptor(cx, obj2, id, false, desc)
                    : Proxy::getPropertyDescriptor(cx, obj2, id, false, desc);
         }
         if (!obj2->getGenericAttributes(cx, id, &desc->attrs))
@@ -3963,18 +3951,19 @@ SetPropertyAttributesById(JSContext *cx,
     JSProperty *prop;
 
     if (!LookupPropertyById(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
         return false;
     if (!prop || obj != obj2) {
         *foundp = false;
         return true;
     }
+    Shape *shape = (Shape *) prop;
     JSBool ok = obj->isNative()
-                ? js_SetNativeAttributes(cx, obj, (Shape *) prop, attrs)
+                ? obj->changePropertyAttributes(cx, shape, attrs)
                 : obj->setGenericAttributes(cx, id, &attrs);
     if (ok)
         *foundp = true;
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
@@ -4067,17 +4056,17 @@ JS_GetUCProperty(JSContext *cx, JSObject
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, jsval *vp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
-    if (!js_GetMethod(cx, obj, id, JSGET_METHOD_BARRIER, vp))
+    if (!js_GetMethod(cx, obj, id, 0, vp))
         return JS_FALSE;
     if (objp)
         *objp = obj;
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp)
@@ -5361,17 +5350,17 @@ JS_CallFunctionName(JSContext *cx, JSObj
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, JSValueArray(argv, argc));
     AutoLastFrameCheck lfc(cx);
 
     Value v;
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     return atom &&
-           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, &v) &&
+           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &v) &&
            Invoke(cx, ObjectOrNullValue(obj), v, argc, argv, rval);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, unsigned argc, jsval *argv,
                      jsval *rval)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -640,27 +640,16 @@ JS_IsConstructorFrame(JSContext *cx, JSS
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)
 {
     return Valueify(fp)->maybeCalleev().toObjectOrNull();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp)
-{
-    Value v;
-
-    if (!Valueify(fp)->getValidCalleeObject(cx, &v))
-        return false;
-    *vp = v.isObject() ? v : JSVAL_VOID;
-    return true;
-}
-
-JS_PUBLIC_API(JSBool)
 JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
 {
     return Valueify(fp)->isDebuggerFrame();
 }
 
 JS_PUBLIC_API(JSBool)
 JS_IsGlobalFrame(JSContext *cx, JSStackFrame *fp)
 {
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -287,49 +287,20 @@ JS_GetFrameReturnValue(JSContext *cx, JS
 
 extern JS_PUBLIC_API(void)
 JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval);
 
 /**
  * Return fp's callee function object (fp->callee) if it has one. Note that
  * this API cannot fail. A null return means "no callee": fp is a global or
  * eval-from-global frame, not a call frame.
- *
- * This API began life as an infallible getter, but now it can return either:
- *
- * 1. An optimized closure that was compiled assuming the function could not
- *    escape and be called from sites the compiler could not see.
- *
- * 2. A "joined function object", an optimization whereby SpiderMonkey avoids
- *    creating fresh function objects for every evaluation of a function
- *    expression that is used only once by a consumer that either promises to
- *    clone later when asked for the value or that cannot leak the value.
- *
- * Because Mozilla's Gecko embedding of SpiderMonkey (and no doubt other
- * embeddings) calls this API in potentially performance-sensitive ways (e.g.
- * in nsContentUtils::GetDocumentFromCaller), we are leaving this API alone. It
- * may now return an unwrapped non-escaping optimized closure, or a joined
- * function object. Such optimized objects may work well if called from the
- * correct context, never mutated or compared for identity, etc.
- *
- * However, if you really need to get the same callee object that JS code would
- * see, which means undoing the optimizations, where an undo attempt can fail,
- * then use JS_GetValidFrameCalleeObject.
  */
 extern JS_PUBLIC_API(JSObject *)
 JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp);
 
-/**
- * Return fp's callee function object after running the deferred closure
- * cloning "method read barrier". This API can fail! If the frame has no
- * callee, this API returns true with JSVAL_IS_VOID(*vp).
- */
-extern JS_PUBLIC_API(JSBool)
-JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp);
-
 /************************************************************************/
 
 extern JS_PUBLIC_API(const char *)
 JS_GetScriptFilename(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(const jschar *)
 JS_GetScriptSourceMap(JSContext *cx, JSScript *script);
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -92,117 +92,16 @@
 #include "vm/ScopeObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace mozilla;
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
-bool
-StackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
-{
-    if (!isFunctionFrame()) {
-        vp->setNull();
-        return true;
-    }
-
-    JSFunction *fun = this->callee().toFunction();
-    vp->setObject(*fun);
-
-    /*
-     * Check for an escape attempt by a joined function object, which must go
-     * through the frame's |this| object's method read barrier for the method
-     * atom by which it was uniquely associated with a property.
-     */
-    const Value &thisv = functionThis();
-    if (thisv.isObject() && fun->methodAtom() && !fun->isClonedMethod()) {
-        JSObject *thisp = &thisv.toObject();
-        JSObject *first_barriered_thisp = NULL;
-
-        do {
-            /*
-             * While a non-native object is responsible for handling its
-             * entire prototype chain, notable non-natives including dense
-             * and typed arrays have native prototypes, so keep going.
-             */
-            if (!thisp->isNative())
-                continue;
-
-            const Shape *shape = thisp->nativeLookup(cx, ATOM_TO_JSID(fun->methodAtom()));
-            if (shape) {
-                /*
-                 * Two cases follow: the method barrier was not crossed
-                 * yet, so we cross it here; the method barrier *was*
-                 * crossed but after the call, in which case we fetch
-                 * and validate the cloned (unjoined) funobj from the
-                 * method property's slot.
-                 *
-                 * In either case we must allow for the method property
-                 * to have been replaced, or its value overwritten.
-                 */
-                if (shape->isMethod() && thisp->nativeGetMethod(shape) == fun) {
-                    if (!thisp->methodReadBarrier(cx, *shape, vp))
-                        return false;
-                    overwriteCallee(vp->toObject());
-                    return true;
-                }
-
-                if (shape->hasSlot()) {
-                    Value v = thisp->getSlot(shape->slot());
-                    JSFunction *clone;
-
-                    if (IsFunctionObject(v, &clone) &&
-                        clone->isInterpreted() &&
-                        clone->script() == fun->script() &&
-                        clone->methodObj() == thisp) {
-                        /*
-                         * N.B. If the method barrier was on a function
-                         * with singleton type, then while crossing the
-                         * method barrier CloneFunctionObject will have
-                         * ignored the attempt to clone the function.
-                         */
-                        JS_ASSERT_IF(!clone->hasSingletonType(), clone != fun);
-                        *vp = v;
-                        overwriteCallee(*clone);
-                        return true;
-                    }
-                }
-            }
-
-            if (!first_barriered_thisp)
-                first_barriered_thisp = thisp;
-        } while ((thisp = thisp->getProto()) != NULL);
-
-        if (!first_barriered_thisp)
-            return true;
-
-        /*
-         * At this point, we couldn't find an already-existing clone (or
-         * force to exist a fresh clone) created via thisp's method read
-         * barrier, so we must clone fun and store it in fp's callee to
-         * avoid re-cloning upon repeated foo.caller access.
-         *
-         * This must mean the code in js_DeleteGeneric could not find this
-         * stack frame on the stack when the method was deleted. We've lost
-         * track of the method, so we associate it with the first barriered
-         * object found starting from thisp on the prototype chain.
-         */
-        JSFunction *newfunobj = CloneFunctionObject(cx, fun);
-        if (!newfunobj)
-            return false;
-        newfunobj->setMethodObj(*first_barriered_thisp);
-        overwriteCallee(*newfunobj);
-        vp->setObject(*newfunobj);
-        return true;
-    }
-
-    return true;
-}
-
 static JSBool
 fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     while (!obj->isFunction()) {
         obj = obj->getProto();
         if (!obj)
             return true;
     }
@@ -222,20 +121,17 @@ fun_getProperty(JSContext *cx, JSObject 
     /* Set to early to null in case of error */
     vp->setNull();
 
     /* Find fun's top-most activation record. */
     StackFrame *fp = js_GetTopStackFrame(cx, FRAME_EXPAND_NONE);
     for (; fp; fp = fp->prev()) {
         if (!fp->isFunctionFrame() || fp->isEvalFrame())
             continue;
-        Value callee;
-        if (!fp->getValidCalleeObject(cx, &callee))
-            return false;
-        if (&callee.toObject() == fun)
+        if (fp->callee().toFunction() == fun)
             break;
     }
     if (!fp)
         return true;
 
 #ifdef JS_METHODJIT
     if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom) && fp && fp->prev()) {
         /*
@@ -272,24 +168,23 @@ fun_getProperty(JSContext *cx, JSObject 
     if (JSID_IS_ATOM(id, cx->runtime->atomState.callerAtom)) {
         if (!fp->prev())
             return true;
 
         StackFrame *frame = fp->prev();
         while (frame && frame->isDummyFrame())
             frame = frame->prev();
 
-        if (frame && !frame->getValidCalleeObject(cx, vp))
-            return false;
-
-        if (!vp->isObject()) {
+        if (!frame || !frame->isFunctionFrame()) {
             JS_ASSERT(vp->isNull());
             return true;
         }
 
+        vp->setObject(frame->callee());
+
         /* Censor the caller if it is from another compartment. */
         JSObject &caller = vp->toObject();
         if (caller.compartment() != cx->compartment) {
             vp->setNull();
         } else if (caller.isFunction()) {
             JSFunction *callerFun = caller.toFunction();
             if (callerFun->isInterpreted() && callerFun->inStrictMode()) {
                 JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
@@ -1258,17 +1153,16 @@ LookupInterpretedFunctionPrototype(JSCon
     if (!shape) {
         if (!ResolveInterpretedFunctionPrototype(cx, funobj))
             return NULL;
         shape = funobj->nativeLookup(cx, id);
     }
     JS_ASSERT(!shape->configurable());
     JS_ASSERT(shape->isDataDescriptor());
     JS_ASSERT(shape->hasSlot());
-    JS_ASSERT(!shape->isMethod());
     return shape;
 }
 
 } /* namespace js */
 
 JSFunction *
 js_NewFunction(JSContext *cx, JSObject *funobj, Native native, unsigned nargs,
                unsigned flags, HandleObject parent, JSAtom *atom, js::gc::AllocKind kind)
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -62,20 +62,16 @@
  *
  * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag
  * bit only, never stored in fun->flags.
  *
  * If we need more bits in the future, all flags for interpreted functions can
  * move to u.i.script->flags. For now we use function flag bits to minimize
  * pointer-chasing.
  */
-#define JSFUN_JOINABLE      0x0001  /* function is null closure that does not
-                                       appear to call itself via its own name
-                                       or arguments.callee */
-
 #define JSFUN_PROTOTYPE     0x0800  /* function is Function.prototype for some
                                        global object */
 
 #define JSFUN_EXPR_CLOSURE  0x1000  /* expression closure: function(x) x*x */
 #define JSFUN_EXTENDED      0x2000  /* structure is FunctionExtended */
 #define JSFUN_INTERPRETED   0x4000  /* use u.i if kind >= this value else u.native */
 #define JSFUN_NULL_CLOSURE  0x8000  /* null closure entrains no scope chain */
 #define JSFUN_KINDMASK      0xc000  /* encode interp vs. native and closure
@@ -124,36 +120,26 @@ struct JSFunction : public JSObject
     }
 
     /* uint16_t representation bounds number of call object dynamic slots. */
     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
 
 #define JS_LOCAL_NAME_TO_ATOM(nameWord)  ((JSAtom *) ((nameWord) & ~uintptr_t(1)))
 #define JS_LOCAL_NAME_IS_CONST(nameWord) ((((nameWord) & uintptr_t(1))) != 0)
 
-    bool mightEscape() const {
-        return isInterpreted() && isNullClosure();
-    }
-
-    bool joinable() const {
-        return flags & JSFUN_JOINABLE;
-    }
-
     /*
      * For an interpreted function, accessors for the initial scope object of
      * activations (stack frames) of the function.
      */
     inline JSObject *environment() const;
     inline void setEnvironment(JSObject *obj);
     inline void initEnvironment(JSObject *obj);
 
     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
 
-    inline void setJoinable();
-
     js::HeapPtrScript &script() const {
         JS_ASSERT(isInterpreted());
         return *(js::HeapPtrScript *)&u.i.script_;
     }
 
     inline void setScript(JSScript *script_);
     inline void initScript(JSScript *script_);
 
@@ -213,43 +199,20 @@ struct JSFunction : public JSObject
     inline bool isExtended() const {
         JS_STATIC_ASSERT(FinalizeKind != ExtendedFinalizeKind);
         JS_ASSERT(!!(flags & JSFUN_EXTENDED) == (getAllocKind() == ExtendedFinalizeKind));
         return !!(flags & JSFUN_EXTENDED);
     }
 
   public:
     /* Accessors for data stored in extended functions. */
-
     inline void initializeExtended();
-
     inline void setExtendedSlot(size_t which, const js::Value &val);
     inline const js::Value &getExtendedSlot(size_t which) const;
 
-    /* Slot holding associated method property, needed for foo.caller handling. */
-    static const uint32_t METHOD_PROPERTY_SLOT = 0;
-
-    /* For cloned methods, slot holding the object this was cloned as a property from. */
-    static const uint32_t METHOD_OBJECT_SLOT = 1;
-
-    /* Whether this is a function cloned from a method. */
-    inline bool isClonedMethod() const;
-
-    /* For a cloned method, pointer to the object the method was cloned for. */
-    inline JSObject *methodObj() const;
-    inline void setMethodObj(JSObject& obj);
-
-    /*
-     * Method name imputed from property uniquely assigned to or initialized,
-     * where the function does not need to be cloned to carry a scope chain.
-     * This is set on both the original and cloned function.
-     */
-    inline JSAtom *methodAtom() const;
-    inline void setMethodAtom(JSAtom *atom);
-
   private:
     /* 
      * These member functions are inherited from JSObject, but should never be applied to
      * a value statically known to be a JSFunction.
      */
     inline JSFunction *toFunction() MOZ_DELETE;
     inline const JSFunction *toFunction() const MOZ_DELETE;
 };
--- a/js/src/jsfuninlines.h
+++ b/js/src/jsfuninlines.h
@@ -80,58 +80,16 @@ JSFunction::initializeExtended()
     JS_ASSERT(isExtended());
 
     JS_ASSERT(js::ArrayLength(toExtended()->extendedSlots) == 2);
     toExtended()->extendedSlots[0].init(js::UndefinedValue());
     toExtended()->extendedSlots[1].init(js::UndefinedValue());
 }
 
 inline void
-JSFunction::setJoinable()
-{
-    JS_ASSERT(isInterpreted());
-    flags |= JSFUN_JOINABLE;
-}
-
-inline bool
-JSFunction::isClonedMethod() const
-{
-    return joinable() && isExtended() && getExtendedSlot(METHOD_OBJECT_SLOT).isObject();
-}
-
-inline JSAtom *
-JSFunction::methodAtom() const
-{
-    return (joinable() && isExtended() && getExtendedSlot(METHOD_PROPERTY_SLOT).isString())
-           ? (JSAtom *) getExtendedSlot(METHOD_PROPERTY_SLOT).toString()
-           : NULL;
-}
-
-inline void
-JSFunction::setMethodAtom(JSAtom *atom)
-{
-    JS_ASSERT(joinable());
-    setExtendedSlot(METHOD_PROPERTY_SLOT, js::StringValue(atom));
-}
-
-inline JSObject *
-JSFunction::methodObj() const
-{
-    JS_ASSERT(joinable());
-    return isClonedMethod() ? &getExtendedSlot(METHOD_OBJECT_SLOT).toObject() : NULL;
-}
-
-inline void
-JSFunction::setMethodObj(JSObject& obj)
-{
-    JS_ASSERT(joinable());
-    setExtendedSlot(METHOD_OBJECT_SLOT, js::ObjectValue(obj));
-}
-
-inline void
 JSFunction::setExtendedSlot(size_t which, const js::Value &val)
 {
     JS_ASSERT(which < js::ArrayLength(toExtended()->extendedSlots));
     toExtended()->extendedSlots[which] = val;
 }
 
 inline const js::Value &
 JSFunction::getExtendedSlot(size_t which) const
@@ -283,20 +241,20 @@ CloneFunctionObject(JSContext *cx, JSFun
 
     return js_CloneFunctionObject(cx, fun, parent, proto, kind);
 }
 
 inline JSFunction *
 CloneFunctionObjectIfNotSingleton(JSContext *cx, JSFunction *fun, JSObject *parent)
 {
     /*
-     * For attempts to clone functions at a function definition opcode or from
-     * a method barrier, don't perform the clone if the function has singleton
-     * type. This was called pessimistically, and we need to preserve the
-     * type's property that if it is singleton there is only a single object
+     * For attempts to clone functions at a function definition opcode,
+     * don't perform the clone if the function has singleton type. This
+     * was called pessimistically, and we need to preserve the type's
+     * property that if it is singleton there is only a single object
      * with its type in existence.
      */
     if (fun->hasSingletonType()) {
         if (!fun->setParent(cx, SkipScopeParent(parent)))
             return NULL;
         fun->setEnvironment(parent);
         return fun;
     }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -795,17 +795,17 @@ TypeSet::addFilterPrimitives(JSContext *
     add(cx, cx->typeLifoAlloc().new_<TypeConstraintFilterPrimitive>(target, filter));
 }
 
 /* If id is a normal slotful 'own' property of an object, get its shape. */
 static inline const Shape *
 GetSingletonShape(JSContext *cx, JSObject *obj, jsid id)
 {
     const Shape *shape = obj->nativeLookup(cx, id);
-    if (shape && shape->hasDefaultGetterOrIsMethod() && shape->hasSlot())
+    if (shape && shape->hasDefaultGetter() && shape->hasSlot())
         return shape;
     return NULL;
 }
 
 void
 ScriptAnalysis::pruneTypeBarriers(JSContext *cx, uint32_t offset)
 {
     TypeBarrier **pbarrier = &getCode(offset).typeBarriers;
@@ -2734,17 +2734,17 @@ UpdatePropertyType(JSContext *cx, TypeSe
 {
     types->setOwnProperty(cx, false);
     if (!shape->writable())
         types->setOwnProperty(cx, true);
 
     if (shape->hasGetterValue() || shape->hasSetterValue()) {
         types->setOwnProperty(cx, true);
         types->addType(cx, Type::UnknownType());
-    } else if (shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) {
+    } else if (shape->hasDefaultGetter() && shape->hasSlot()) {
         const Value &value = obj->nativeGetSlot(shape->slot());
 
         /*
          * Don't add initial undefined types for singleton properties that are
          * not collated into the JSID_VOID property (see propertySet comment).
          */
         if (force || !value.isUndefined()) {
             Type type = GetValueType(cx, value);
@@ -3662,18 +3662,17 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
       case JSOP_ARGUMENTS:
         /* Compute a precise type only when we know the arguments won't escape. */
         if (script->needsArgsObj())
             pushed[0].addType(cx, Type::UnknownType());
         else
             pushed[0].addType(cx, Type::LazyArgsType());
         break;
 
-      case JSOP_SETPROP:
-      case JSOP_SETMETHOD: {
+      case JSOP_SETPROP: {
         jsid id = GetAtomId(cx, script, pc, 0);
         poppedTypes(pc, 1)->addSetProperty(cx, script, pc, poppedTypes(pc, 0), id);
         poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
         break;
       }
 
       case JSOP_LENGTH:
       case JSOP_GETPROP:
@@ -3870,18 +3869,17 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
       case JSOP_SETTER:
         state.hasGetSet = true;
         break;
 
       case JSOP_HOLE:
         state.hasHole = true;
         break;
 
-      case JSOP_INITPROP:
-      case JSOP_INITMETHOD: {
+      case JSOP_INITPROP: {
         const SSAValue &objv = poppedValue(pc, 1);
         jsbytecode *initpc = script->code + objv.pushedOffset();
         TypeObject *initializer = GetInitializerType(cx, script, initpc);
 
         if (initializer) {
             pushed[0].addType(cx, Type::ObjectType(initializer));
             if (!initializer->unknownProperties()) {
                 jsid id = GetAtomId(cx, script, pc, 0);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -364,17 +364,17 @@ Class js_NoSuchMethodClass = {
  * call by name, and args is an Array containing this invocation's actual
  * parameters.
  */
 bool
 js::OnUnknownMethod(JSContext *cx, JSObject *obj, Value idval, Value *vp)
 {
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
     AutoValueRooter tvr(cx);
-    if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, tvr.addr()))
+    if (!js_GetMethod(cx, obj, id, 0, tvr.addr()))
         return false;
     TypeScript::MonitorUnknown(cx, cx->fp()->script(), cx->regs().pc);
 
     if (tvr.value().isPrimitive()) {
         *vp = tvr.value();
     } else {
 #if JS_HAS_XML_SUPPORT
         /* Extract the function name from function::name qname. */
@@ -1210,21 +1210,19 @@ js::AssertValidPropertyCacheHit(JSContex
  */
 JS_STATIC_ASSERT(JSOP_NAME_LENGTH == JSOP_CALLNAME_LENGTH);
 JS_STATIC_ASSERT(JSOP_GETARG_LENGTH == JSOP_CALLARG_LENGTH);
 JS_STATIC_ASSERT(JSOP_GETLOCAL_LENGTH == JSOP_CALLLOCAL_LENGTH);
 JS_STATIC_ASSERT(JSOP_XMLNAME_LENGTH == JSOP_CALLXMLNAME_LENGTH);
 
 /*
  * Same for JSOP_SETNAME and JSOP_SETPROP, which differ only slightly but
- * remain distinct for the decompiler. Likewise for JSOP_INIT{PROP,METHOD}.
+ * remain distinct for the decompiler.
  */
 JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
-JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETMETHOD_LENGTH);
-JS_STATIC_ASSERT(JSOP_INITPROP_LENGTH == JSOP_INITMETHOD_LENGTH);
 
 /* See TRY_BRANCH_AFTER_COND. */
 JS_STATIC_ASSERT(JSOP_IFNE_LENGTH == JSOP_IFEQ_LENGTH);
 JS_STATIC_ASSERT(JSOP_IFNE == JSOP_IFEQ + 1);
 
 /* For the fastest case inder JSOP_INCNAME, etc. */
 JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_DECNAME_LENGTH);
 JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEINC_LENGTH);
@@ -1709,16 +1707,18 @@ ADD_EMPTY_CASE(JSOP_UNUSED20)
 ADD_EMPTY_CASE(JSOP_UNUSED21)
 ADD_EMPTY_CASE(JSOP_UNUSED22)
 ADD_EMPTY_CASE(JSOP_UNUSED23)
 ADD_EMPTY_CASE(JSOP_UNUSED24)
 ADD_EMPTY_CASE(JSOP_UNUSED25)
 ADD_EMPTY_CASE(JSOP_UNUSED26)
 ADD_EMPTY_CASE(JSOP_UNUSED27)
 ADD_EMPTY_CASE(JSOP_UNUSED28)
+ADD_EMPTY_CASE(JSOP_UNUSED29)
+ADD_EMPTY_CASE(JSOP_UNUSED30)
 ADD_EMPTY_CASE(JSOP_CONDSWITCH)
 ADD_EMPTY_CASE(JSOP_TRY)
 #if JS_HAS_XML_SUPPORT
 ADD_EMPTY_CASE(JSOP_STARTXML)
 ADD_EMPTY_CASE(JSOP_STARTXMLEXPR)
 #endif
 ADD_EMPTY_CASE(JSOP_LOOPHEAD)
 ADD_EMPTY_CASE(JSOP_LOOPENTRY)
@@ -2580,17 +2580,16 @@ BEGIN_CASE(JSOP_CALLPROP)
     regs.sp[-1] = rval;
     assertSameCompartment(cx, regs.sp[-1]);
 }
 END_CASE(JSOP_GETPROP)
 
 BEGIN_CASE(JSOP_SETGNAME)
 BEGIN_CASE(JSOP_SETNAME)
 BEGIN_CASE(JSOP_SETPROP)
-BEGIN_CASE(JSOP_SETMETHOD)
 {
     const Value &rval = regs.sp[-1];
     const Value &lval = regs.sp[-2];
 
     if (!SetPropertyOperation(cx, regs.pc, lval, rval))
         goto error;
 
     regs.sp[-2] = regs.sp[-1];
@@ -3154,83 +3153,16 @@ BEGIN_CASE(JSOP_LAMBDA)
     JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
     JSObject *obj = fun;
 
     /* do-while(0) so we can break instead of using a goto. */
     do {
         JSObject *parent;
         if (fun->isNullClosure()) {
             parent = &regs.fp()->scopeChain();
-
-            if (fun->joinable()) {
-                jsbytecode *pc2 = regs.pc + JSOP_LAMBDA_LENGTH;
-                JSOp op2 = JSOp(*pc2);
-
-                /*
-                 * Optimize var obj = {method: function () { ... }, ...},
-                 * this.method = function () { ... }; and other significant
-                 * single-use-of-null-closure bytecode sequences.
-                 */
-                if (op2 == JSOP_INITMETHOD) {
-#ifdef DEBUG
-                    const Value &lref = regs.sp[-1];
-                    JS_ASSERT(lref.isObject());
-                    JSObject *obj2 = &lref.toObject();
-                    JS_ASSERT(obj2->isObject());
-#endif
-                    JS_ASSERT(fun->methodAtom() ==
-                              script->getAtom(GET_UINT32_INDEX(regs.pc + JSOP_LAMBDA_LENGTH)));
-                    break;
-                }
-
-                if (op2 == JSOP_SETMETHOD) {
-#ifdef DEBUG
-                    op2 = JSOp(pc2[JSOP_SETMETHOD_LENGTH]);
-                    JS_ASSERT(op2 == JSOP_POP || op2 == JSOP_POPV);
-#endif
-                    const Value &lref = regs.sp[-1];
-                    if (lref.isObject() && lref.toObject().canHaveMethodBarrier()) {
-                        JS_ASSERT(fun->methodAtom() ==
-                                  script->getAtom(GET_UINT32_INDEX(regs.pc + JSOP_LAMBDA_LENGTH)));
-                        break;
-                    }
-                } else if (op2 == JSOP_CALL) {
-                    /*
-                     * Array.prototype.sort and String.prototype.replace are
-                     * optimized as if they are special form. We know that they
-                     * won't leak the joined function object in obj, therefore
-                     * we don't need to clone that compiler-created function
-                     * object for identity/mutation reasons.
-                     */
-                    int iargc = GET_ARGC(pc2);
-
-                    /*
-                     * Note that we have not yet pushed obj as the final argument,
-                     * so regs.sp[1 - (iargc + 2)], and not regs.sp[-(iargc + 2)],
-                     * is the callee for this JSOP_CALL.
-                     */
-                    const Value &cref = regs.sp[1 - (iargc + 2)];
-                    JSFunction *fun;
-
-                    if (IsFunctionObject(cref, &fun)) {
-                        if (Native native = fun->maybeNative()) {
-                            if ((iargc == 1 && native == array_sort) ||
-                                (iargc == 2 && native == str_replace)) {
-                                break;
-                            }
-                        }
-                    }
-                } else if (op2 == JSOP_NULL) {
-                    pc2 += JSOP_NULL_LENGTH;
-                    op2 = JSOp(*pc2);
-
-                    if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0)
-                        break;
-                }
-            }
         } else {
             parent = GetScopeChain(cx, regs.fp());
             if (!parent)
                 goto error;
         }
 
         obj = CloneFunctionObjectIfNotSingleton(cx, fun, parent);
         if (!obj)
@@ -3400,35 +3332,33 @@ BEGIN_CASE(JSOP_ENDINIT)
 {
     /* FIXME remove JSOP_ENDINIT bug 588522 */
     JS_ASSERT(regs.sp - regs.fp()->base() >= 1);
     JS_ASSERT(regs.sp[-1].isObject());
 }
 END_CASE(JSOP_ENDINIT)
 
 BEGIN_CASE(JSOP_INITPROP)
-BEGIN_CASE(JSOP_INITMETHOD)
 {
     /* Load the property's initial value into rval. */
     JS_ASSERT(regs.sp - regs.fp()->base() >= 2);
     Value rval = regs.sp[-1];
 
     /* Load the object being initialized into lval/obj. */
     JSObject *obj = &regs.sp[-2].toObject();
     JS_ASSERT(obj->isObject());
 
     JSAtom *atom;
     LOAD_ATOM(0, atom);
     jsid id = ATOM_TO_JSID(atom);
 
-    unsigned defineHow = (op == JSOP_INITMETHOD) ? DNP_SET_METHOD : 0;
     if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
-        ? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode)
+        ? !js_SetPropertyHelper(cx, obj, id, 0, &rval, script->strictModeCode)
         : !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
-                                JSPROP_ENUMERATE, 0, 0, defineHow)) {
+                                JSPROP_ENUMERATE, 0, 0, 0)) {
         goto error;
     }
 
     regs.sp--;
 }
 END_CASE(JSOP_INITPROP);
 
 BEGIN_CASE(JSOP_INITELEM)
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -239,38 +239,34 @@ GetPropertyOperation(JSContext *cx, jsby
             }
         }
     }
 
     JSObject *obj = ValueToObject(cx, lval);
     if (!obj)
         return false;
 
-    unsigned flags = (op == JSOP_CALLPROP)
-                  ? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
-                  : JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER;
-
     PropertyCacheEntry *entry;
     JSObject *obj2;
     PropertyName *name;
     JS_PROPERTY_CACHE(cx).test(cx, pc, obj, obj2, entry, name);
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
-        if (!NativeGet(cx, obj, obj2, entry->prop, flags, vp))
+        if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp))
             return false;
         return true;
     }
 
     jsid id = ATOM_TO_JSID(name);
 
     if (obj->getOps()->getProperty) {
         if (!GetPropertyGenericMaybeCallXML(cx, op, obj, id, vp))
             return false;
     } else {
-        if (!GetPropertyHelper(cx, obj, id, flags, vp))
+        if (!GetPropertyHelper(cx, obj, id, JSGET_CACHE_RESULT, vp))
             return false;
     }
 
 #if JS_HAS_NO_SUCH_METHOD
     if (op == JSOP_CALLPROP &&
         JS_UNLIKELY(vp->isPrimitive()) &&
         lval.isObject())
     {
@@ -284,17 +280,16 @@ GetPropertyOperation(JSContext *cx, jsby
 
 inline bool
 SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Value &rval)
 {
     JSObject *obj = ValueToObject(cx, lval);
     if (!obj)
         return false;
 
-    JS_ASSERT_IF(*pc == JSOP_SETMETHOD, IsFunctionObject(rval));
     JS_ASSERT_IF(*pc == JSOP_SETNAME || *pc == JSOP_SETGNAME, lval.isObject());
     JS_ASSERT_IF(*pc == JSOP_SETGNAME, obj == &cx->fp()->scopeChain().global());
 
     PropertyCacheEntry *entry;
     JSObject *obj2;
     PropertyName *name;
     if (JS_PROPERTY_CACHE(cx).testForSet(cx, pc, obj, &entry, &obj2, &name)) {
         /*
@@ -317,17 +312,17 @@ SetPropertyOperation(JSContext *cx, jsby
             } else {
                 JS_ASSERT(obj2->nativeContains(cx, *shape));
                 JS_ASSERT(entry->isPrototypePropertyHit());
                 JS_ASSERT(entry->kshape != entry->pshape);
                 JS_ASSERT(!shape->hasSlot());
             }
 #endif
 
-            if (shape->hasDefaultSetter() && shape->hasSlot() && !shape->isMethod()) {
+            if (shape->hasDefaultSetter() && shape->hasSlot()) {
                 /* Fast path for, e.g., plain Object instance properties. */
                 obj->nativeSetSlotWithType(cx, shape, rval);
             } else {
                 Value rref = rval;
                 bool strict = cx->stack.currentScript()->strictModeCode;
                 if (!js_NativeSet(cx, obj, shape, false, strict, &rref))
                     return false;
             }
@@ -339,23 +334,19 @@ SetPropertyOperation(JSContext *cx, jsby
 
     bool strict = cx->stack.currentScript()->strictModeCode;
     Value rref = rval;
 
     JSOp op = JSOp(*pc);
 
     jsid id = ATOM_TO_JSID(name);
     if (JS_LIKELY(!obj->getOps()->setProperty)) {
-        unsigned defineHow;
-        if (op == JSOP_SETMETHOD)
-            defineHow = DNP_CACHE_RESULT | DNP_SET_METHOD;
-        else if (op == JSOP_SETNAME)
-            defineHow = DNP_CACHE_RESULT | DNP_UNQUALIFIED;
-        else
-            defineHow = DNP_CACHE_RESULT;
+        unsigned defineHow = (op == JSOP_SETNAME)
+                             ? DNP_CACHE_RESULT | DNP_UNQUALIFIED
+                             : DNP_CACHE_RESULT;
         if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rref, strict))
             return false;
     } else {
         if (!obj->setGeneric(cx, id, &rref, strict))
             return false;
     }
 
     return true;
@@ -379,17 +370,17 @@ NameOperation(JSContext *cx, jsbytecode 
         obj = &obj->global();
 
     PropertyCacheEntry *entry;
     JSObject *obj2;
     PropertyName *name;
     JS_PROPERTY_CACHE(cx).test(cx, pc, obj, obj2, entry, name);
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
-        if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, vp))
+        if (!NativeGet(cx, obj, obj2, entry->prop, 0, vp))
             return false;
         return true;
     }
 
     jsid id = ATOM_TO_JSID(name);
 
     JSProperty *prop;
     if (!FindPropertyHelper(cx, name, true, obj, &obj, &obj2, &prop))
@@ -411,17 +402,17 @@ NameOperation(JSContext *cx, jsbytecode 
     if (!obj->isNative() || !obj2->isNative()) {
         if (!obj->getGeneric(cx, id, vp))
             return false;
     } else {
         Shape *shape = (Shape *)prop;
         JSObject *normalized = obj;
         if (normalized->getClass() == &WithClass && !shape->hasDefaultGetter())
             normalized = &normalized->asWith().object();
-        if (!NativeGet(cx, normalized, obj2, shape, JSGET_METHOD_BARRIER, vp))
+        if (!NativeGet(cx, normalized, obj2, shape, 0, vp))
             return false;
     }
 
     return true;
 }
 
 inline bool
 DefVarOrConstOperation(JSContext *cx, JSObject &varobj, PropertyName *dn, unsigned attrs)
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -454,17 +454,17 @@ GetCustomIterator(JSContext *cx, JSObjec
     if (flags == JSITER_FOR_OF) {
         js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_ITERABLE,
                                  JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL, NULL, NULL);
         return false;
     }
 
     /* Check whether we have a valid __iterator__ method. */
     JSAtom *atom = cx->runtime->atomState.iteratorAtom;
-    if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, vp))
+    if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, vp))
         return false;
 
     /* If there is no custom __iterator__ method, we are done here. */
     if (!vp->isObject()) {
         vp->setUndefined();
         return true;
     }
 
@@ -1237,17 +1237,17 @@ js_IteratorMore(JSContext *cx, JSObject 
             return false;
         if (rval->isMagic(JS_NO_ITER_VALUE)) {
             rval->setBoolean(false);
             return true;
         }
     } else {
         /* Call the iterator object's .next method. */
         jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);
-        if (!js_GetMethod(cx, iterobj, id, JSGET_METHOD_BARRIER, rval))
+        if (!js_GetMethod(cx, iterobj, id, 0, rval))
             return false;
         if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
             /* Check for StopIteration. */
             if (!cx->isExceptionPending() || !IsStopIteration(cx->getPendingException()))
                 return false;
 
             cx->clearPendingException();
             cx->iterValue.setMagic(JS_NO_ITER_VALUE);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1958,17 +1958,17 @@ DefinePropertyOnObject(JSContext *cx, JS
                 if (!shape->configurable() &&
                     (!shape->hasDefaultGetter() || !shape->hasDefaultSetter()) &&
                     desc.isDataDescriptor() &&
                     (desc.hasWritable ? desc.writable() : shape->writable()))
                 {
                     return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
                 }
 
-                if (!js_NativeGet(cx, obj, obj2, shape, JSGET_NO_METHOD_BARRIER, &v))
+                if (!js_NativeGet(cx, obj, obj2, shape, 0, &v))
                     return JS_FALSE;
             }
 
             if (desc.isDataDescriptor()) {
                 if (!shape->isDataDescriptor())
                     break;
 
                 bool same;
@@ -2087,24 +2087,18 @@ DefinePropertyOnObject(JSContext *cx, JS
     if (desc.isGenericDescriptor()) {
         unsigned changed = 0;
         if (desc.hasConfigurable)
             changed |= JSPROP_PERMANENT;
         if (desc.hasEnumerable)
             changed |= JSPROP_ENUMERATE;
 
         attrs = (shape->attributes() & ~changed) | (desc.attrs & changed);
-        if (shape->isMethod()) {
-            JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
-            getter = JS_PropertyStub;
-            setter = JS_StrictPropertyStub;
-        } else {
-            getter = shape->getter();
-            setter = shape->setter();
-        }
+        getter = shape->getter();
+        setter = shape->setter();
     } else if (desc.isDataDescriptor()) {
         unsigned unchanged = 0;
         if (!desc.hasConfigurable)
             unchanged |= JSPROP_PERMANENT;
         if (!desc.hasEnumerable)
             unchanged |= JSPROP_ENUMERATE;
         /* Watch out for accessor -> data transformations here. */
         if (!desc.hasWritable && shape->isDataDescriptor())
@@ -2121,34 +2115,32 @@ DefinePropertyOnObject(JSContext *cx, JS
         /*
          * Getters and setters are just like watchpoints from an access
          * control point of view.
          */
         Value dummy;
         if (!CheckAccess(cx, obj2, id, JSACC_WATCH, &dummy, &attrs))
              return JS_FALSE;
 
-        JS_ASSERT_IF(shape->isMethod(), !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
-
         /* 8.12.9 step 12. */
         unsigned changed = 0;
         if (desc.hasConfigurable)
             changed |= JSPROP_PERMANENT;
         if (desc.hasEnumerable)
             changed |= JSPROP_ENUMERATE;
         if (desc.hasGet)
             changed |= JSPROP_GETTER | JSPROP_SHARED | JSPROP_READONLY;
         if (desc.hasSet)
             changed |= JSPROP_SETTER | JSPROP_SHARED | JSPROP_READONLY;
 
         attrs = (desc.attrs & changed) | (shape->attributes() & ~changed);
         if (desc.hasGet) {
             getter = desc.getter();
         } else {
-            getter = (shape->isMethod() || (shape->hasDefaultGetter() && !shape->hasGetterValue()))
+            getter = (shape->hasDefaultGetter() && !shape->hasGetterValue())
                      ? JS_PropertyStub
                      : shape->getter();
         }
         if (desc.hasSet) {
             setter = desc.setter();
         } else {
             setter = (shape->hasDefaultSetter() && !shape->hasSetterValue())
                      ? JS_StrictPropertyStub
@@ -4394,52 +4386,30 @@ js_PurgeScopeChainHelper(JSContext *cx, 
     return true;
 }
 
 Shape *
 js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
                      PropertyOp getter, StrictPropertyOp setter, uint32_t slot,
                      unsigned attrs, unsigned flags, int shortid)
 {
-    JS_ASSERT(!(flags & Shape::METHOD));
-
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     /*
      * Purge the property cache of now-shadowed id in obj's scope chain. Do
      * this optimistically (assuming no failure below) before locking obj, so
      * we can lock the shadowed scope.
      */
     if (!js_PurgeScopeChain(cx, obj, id))
         return NULL;
 
     return obj->putProperty(cx, id, getter, setter, slot, attrs, flags, shortid);
 }
 
-Shape *
-js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
-                             Shape *shape, unsigned attrs, unsigned mask,
-                             PropertyOp getter, StrictPropertyOp setter)
-{
-    /*
-     * Check for freezing an object with shape-memoized methods here, on a
-     * shape-by-shape basis.
-     */
-    if ((attrs & JSPROP_READONLY) && shape->isMethod()) {
-        Value v = ObjectValue(*obj->nativeGetMethod(shape));
-
-        shape = obj->methodReadBarrier(cx, *shape, &v);
-        if (!shape)
-            return NULL;
-    }
-
-    return obj->changeProperty(cx, shape, attrs, mask, getter, setter);
-}
-
 JSBool
 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *value,
                   PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
 }
 
 JSBool
@@ -4477,25 +4447,22 @@ CallAddPropertyHook(JSContext *cx, Class
 namespace js {
 
 const Shape *
 DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value_,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                      unsigned flags, int shortid, unsigned defineHow /* = 0 */)
 {
     JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE |
-                             DNP_SET_METHOD | DNP_SKIP_TYPE)) == 0);
+                             DNP_SKIP_TYPE)) == 0);
 
     RootObject objRoot(cx, &obj);
     RootId idRoot(cx, &id);
 
-    /*
-     * Make a local copy of value, in case a method barrier needs to update the
-     * value to define, and just so addProperty can mutate its inout parameter.
-     */
+    /* Make a local copy of value so addProperty can mutate its inout parameter. */
     RootedVarValue value(cx);
     value = value_;
 
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     /*
      * If defining a getter or setter, we must check for its counterpart and
@@ -4544,61 +4511,32 @@ DefineNativeProperty(JSContext *cx, JSOb
      */
     if (!(defineHow & DNP_DONT_PURGE)) {
         if (!js_PurgeScopeChain(cx, obj, id))
             return NULL;
     }
 
     /* Use the object's class getter and setter by default. */
     Class *clasp = obj->getClass();
-    if (!(defineHow & DNP_SET_METHOD)) {
-        if (!getter && !(attrs & JSPROP_GETTER))
-            getter = clasp->getProperty;
-        if (!setter && !(attrs & JSPROP_SETTER))
-            setter = clasp->setProperty;
-    }
-
-    if (((defineHow & DNP_SET_METHOD) || getter == JS_PropertyStub) &&
-        !(defineHow & DNP_SKIP_TYPE)) {
+    if (!getter && !(attrs & JSPROP_GETTER))
+        getter = clasp->getProperty;
+    if (!setter && !(attrs & JSPROP_SETTER))
+        setter = clasp->setProperty;
+
+    if ((getter == JS_PropertyStub) && !(defineHow & DNP_SKIP_TYPE)) {
         /*
          * Type information for normal native properties should reflect the
          * initial value of the property.
          */
         AddTypePropertyId(cx, obj, id, value);
         if (attrs & JSPROP_READONLY)
             MarkTypePropertyConfigured(cx, obj, id);
     }
 
     if (!shape) {
-        /* Add a new property, or replace an existing one of the same id. */
-        if (defineHow & DNP_SET_METHOD) {
-            JS_ASSERT(clasp == &ObjectClass);
-            JS_ASSERT(IsFunctionObject(value));
-            JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
-            JS_ASSERT(!getter && !setter);
-
-            JSObject *funobj = &value.raw().toObject();
-            if (!funobj->toFunction()->isClonedMethod())
-                flags |= Shape::METHOD;
-        }
-
-        if (const Shape *existingShape = obj->nativeLookup(cx, id)) {
-            if (existingShape->isMethod() &&
-                ObjectValue(*obj->nativeGetMethod(existingShape)) == value)
-            {
-                /*
-                 * Redefining an existing shape-memoized method object without
-                 * changing the property's value, perhaps to change attributes.
-                 * Clone now via the method read barrier.
-                 */
-                if (!obj->methodReadBarrier(cx, *existingShape, value.address()))
-                    return NULL;
-            }
-        }
-
         shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT,
                                  attrs, flags, shortid);
         if (!shape)
             return NULL;
     }
 
     /* Store valueCopy before calling addProperty, in case the latter GC's. */
     if (shape->hasSlot())
@@ -4965,44 +4903,38 @@ static JS_ALWAYS_INLINE JSBool
 js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *pobj,
                    const Shape *shape, unsigned getHow, Value *vp)
 {
     JS_ASSERT(pobj->isNative());
 
     if (shape->hasSlot()) {
         *vp = pobj->nativeGetSlot(shape->slot());
         JS_ASSERT(!vp->isMagic());
-        JS_ASSERT_IF(!pobj->hasSingletonType() && shape->hasDefaultGetterOrIsMethod(),
+        JS_ASSERT_IF(!pobj->hasSingletonType() && shape->hasDefaultGetter(),
                      js::types::TypeHasProperty(cx, pobj->type(), shape->propid(), *vp));
     } else {
         vp->setUndefined();
     }
     if (shape->hasDefaultGetter())
         return true;
 
-    if (JS_UNLIKELY(shape->isMethod()) && (getHow & JSGET_NO_METHOD_BARRIER))
-        return true;
-
     jsbytecode *pc;
     JSScript *script = cx->stack.currentScript(&pc);
     if (script && script->hasAnalysis()) {
         analyze::Bytecode *code = script->analysis()->maybeCode(pc);
         if (code)
             code->accessGetter = true;
     }
 
     if (!shape->get(cx, receiver, obj, pobj, vp))
         return false;
 
     /* Update slotful shapes according to the value produced by the getter. */
-    if (shape->hasSlot() && pobj->nativeContains(cx, *shape)) {
-        /* Method shapes were removed by methodReadBarrier under shape->get(). */
-        JS_ASSERT(!shape->isMethod());
+    if (shape->hasSlot() && pobj->nativeContains(cx, *shape))
         pobj->nativeSetSlot(shape->slot(), *vp);
-    }
 
     return true;
 }
 
 JSBool
 js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, unsigned getHow,
              Value *vp)
 {
@@ -5016,20 +4948,16 @@ js_NativeSet(JSContext *cx, JSObject *ob
 
     JS_ASSERT(obj->isNative());
 
     if (shape->hasSlot()) {
         uint32_t slot = shape->slot();
 
         /* If shape has a stub setter, just store *vp. */
         if (shape->hasDefaultSetter()) {
-            if (!added) {
-                if (shape->isMethod() && !obj->methodShapeChange(cx, *shape))
-                    return false;
-            }
             obj->nativeSetSlot(slot, *vp);
             return true;
         }
     } else {
         /*
          * Allow API consumers to create shared properties with stub setters.
          * Such properties effectively function as data descriptors which are
          * not writable, so attempting to set such a property should do nothing
@@ -5157,28 +5085,28 @@ js::GetPropertyHelper(JSContext *cx, JSO
 {
     return !!js_GetPropertyHelperInline(cx, obj, obj, id, getHow, vp);
 }
 
 JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
-    return js_GetPropertyHelperInline(cx, obj, receiver, id, JSGET_METHOD_BARRIER, vp);
+    return js_GetPropertyHelperInline(cx, obj, receiver, id, 0, vp);
 }
 
 JSBool
 js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
 
     /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
-    return js_GetPropertyHelperInline(cx, obj, receiver, id, JSGET_METHOD_BARRIER, vp);
+    return js_GetPropertyHelperInline(cx, obj, receiver, id, 0, vp);
 }
 
 JSBool
 js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp)
 {
     JSProperty *prop;
     JSObject *obj2;
     if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
@@ -5256,62 +5184,44 @@ JSObject::reportNotExtensible(JSContext 
                                     JSDVG_IGNORE_STACK, ObjectValue(*this),
                                     NULL, NULL, NULL);
 }
 
 bool
 JSObject::callMethod(JSContext *cx, jsid id, unsigned argc, Value *argv, Value *vp)
 {
     Value fval;
-    return js_GetMethod(cx, this, id, JSGET_NO_METHOD_BARRIER, &fval) &&
+    return js_GetMethod(cx, this, id, 0, &fval) &&
            Invoke(cx, ObjectValue(*this), fval, argc, argv, vp);
 }
 
-static bool
-CloneFunctionForSetMethod(JSContext *cx, Value *vp)
-{
-    JSFunction *fun = vp->toObject().toFunction();
-
-    /* Clone the fun unless it already has been. */
-    if (!fun->isClonedMethod()) {
-        fun = CloneFunctionObject(cx, fun);
-        if (!fun)
-            return false;
-        vp->setObject(*fun);
-    }
-    return true;
-}
-
 JSBool
 js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, unsigned defineHow,
                      Value *vp, JSBool strict)
 {
     JSObject *pobj;
     JSProperty *prop;
     const Shape *shape;
     unsigned attrs, flags;
     int shortid;
     Class *clasp;
     PropertyOp getter;
     StrictPropertyOp setter;
     bool added;
 
-    JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_SET_METHOD | DNP_UNQUALIFIED)) == 0);
+    JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
 
     /* Convert string indices to integers if appropriate. */
     id = js_CheckForStringIndex(id);
 
     if (JS_UNLIKELY(obj->watched())) {
         /* Fire watchpoints, if any. */
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
             return false;
-
-        /* A watchpoint handler may set *vp to a non-function value. */
-        defineHow &= ~DNP_SET_METHOD;
     }
 
     if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
         return false;
     if (prop) {
         if (!pobj->isNative()) {
             if (pobj->isProxy()) {
                 AutoPropertyDescriptorRooter pd(cx);
@@ -5376,22 +5286,16 @@ js_SetPropertyHelper(JSContext *cx, JSOb
         }
 
         attrs = shape->attributes();
         if (pobj != obj) {
             /*
              * We found id in a prototype object: prepare to share or shadow.
              */
             if (!shape->shadowable()) {
-                if (defineHow & DNP_SET_METHOD) {
-                    JS_ASSERT(!shape->isMethod());
-                    if (!CloneFunctionForSetMethod(cx, vp))
-                        return false;
-                }
-
                 if (defineHow & DNP_CACHE_RESULT)
                     JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, pobj, shape);
 
                 if (shape->hasDefaultSetter() && !shape->hasGetterValue())
                     return JS_TRUE;
 
                 return shape->set(cx, obj, strict, vp);
             }
@@ -5407,17 +5311,16 @@ js_SetPropertyHelper(JSContext *cx, JSOb
              *
              * A subset of slotless shared properties is the set of properties
              * with shortids, which must be preserved too. An old API requires
              * that the property's getter and setter receive the shortid, not
              * id, when they are called on the shadowing property that we are
              * about to create in obj.
              */
             if (!shape->hasSlot()) {
-                defineHow &= ~DNP_SET_METHOD;
                 if (shape->hasShortID()) {
                     flags = Shape::HAS_SHORTID;
                     shortid = shape->shortid();
                 }
                 attrs &= ~JSPROP_SHARED;
                 getter = shape->getter();
                 setter = shape->setter();
             } else {
@@ -5426,36 +5329,16 @@ js_SetPropertyHelper(JSContext *cx, JSOb
             }
 
             /*
              * Forget we found the proto-property now that we've copied any
              * needed member values.
              */
             shape = NULL;
         }
-
-        if (shape && (defineHow & DNP_SET_METHOD)) {
-            /*
-             * JSOP_SETMETHOD is assigning to an existing own property. If it
-             * is an identical method property, do nothing. Otherwise downgrade
-             * to ordinary assignment. Either way, do not fill the property
-             * cache, as the interpreter has no fast path for these unusual
-             * cases.
-             */
-            if (shape->isMethod()) {
-                if (obj->nativeGetMethod(shape) == &vp->toObject())
-                    return true;
-                shape = obj->methodShapeChange(cx, *shape);
-                if (!shape)
-                    return false;
-            }
-            if (!CloneFunctionForSetMethod(cx, vp))
-                return false;
-            return js_NativeSet(cx, obj, shape, false, strict, vp);
-        }
     }
 
     added = false;
     if (!shape) {
         if (!obj->isExtensible()) {
             /* Error in strict mode code, warn with strict option, otherwise do nothing. */
             if (strict)
                 return obj->reportNotExtensible(cx);
@@ -5466,29 +5349,16 @@ js_SetPropertyHelper(JSContext *cx, JSOb
 
         /*
          * Purge the property cache of now-shadowed id in obj's scope chain.
          * Do this early, before locking obj to avoid nesting locks.
          */
         if (!js_PurgeScopeChain(cx, obj, id))
             return JS_FALSE;
 
-        /*
-         * Check for Object class here to avoid defining a method on a class
-         * with magic resolve, addProperty, getProperty, etc. hooks.
-         */
-        if ((defineHow & DNP_SET_METHOD) && obj->canHaveMethodBarrier()) {
-            JS_ASSERT(IsFunctionObject(*vp));
-            JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
-
-            JSObject *funobj = &vp->toObject();
-            if (!funobj->toFunction()->isClonedMethod())
-                flags |= Shape::METHOD;
-        }
-
         shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT,
                                  attrs, flags, shortid);
         if (!shape)
             return JS_FALSE;
 
         /*
          * Initialize the new property value (passed to setter) to undefined.
          * Note that we store before calling addProperty, to match the order
@@ -5553,46 +5423,38 @@ js_GetElementAttributes(JSContext *cx, J
         return obj->getElementAttributes(cx, index, attrsp);
 
     const Shape *shape = (Shape *)prop;
     *attrsp = shape->attributes();
     return true;
 }
 
 JSBool
-js_SetNativeAttributes(JSContext *cx, JSObject *obj, Shape *shape, unsigned attrs)
-{
-    JS_ASSERT(obj->isNative());
-    return !!js_ChangeNativePropertyAttrs(cx, obj, shape, attrs, 0,
-                                          shape->getter(), shape->setter());
-}
-
-JSBool
 js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp)
 {
     JSProperty *prop;
     if (!js_LookupProperty(cx, obj, id, &obj, &prop))
         return false;
     if (!prop)
         return true;
     return obj->isNative()
-           ? js_SetNativeAttributes(cx, obj, (Shape *) prop, *attrsp)
+           ? obj->changePropertyAttributes(cx, (Shape *) prop, *attrsp)
            : obj->setGenericAttributes(cx, id, attrsp);
 }
 
 JSBool
 js_SetElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp)
 {
     JSProperty *prop;
     if (!js_LookupElement(cx, obj, index, &obj, &prop))
         return false;
     if (!prop)
         return true;
     return obj->isNative()
-           ? js_SetNativeAttributes(cx, obj, (Shape *) prop, *attrsp)
+           ? obj->changePropertyAttributes(cx, (Shape *) prop, *attrsp)
            : obj->setElementAttributes(cx, index, attrsp);
 }
 
 JSBool
 js_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
     JSObject *proto;
     JSProperty *prop;
@@ -5619,45 +5481,16 @@ js_DeleteGeneric(JSContext *cx, JSObject
             return obj->reportNotConfigurable(cx, id);
         rval->setBoolean(false);
         return true;
     }
 
     if (shape->hasSlot()) {
         const Value &v = obj->nativeGetSlot(shape->slot());
         GCPoke(cx->runtime, v);
-
-        /*
-         * Delete is rare enough that we can take the hit of checking for an
-         * active cloned method function object that must be homed to a callee
-         * slot on the active stack frame before this delete completes, in case
-         * someone saved the clone and checks it against foo.caller for a foo
-         * called from the active method.
-         *
-         * We do not check suspended frames. They can't be reached via caller,
-         * so the only way they could have the method's joined function object
-         * as callee is through an API abusage. We break any such edge case.
-         */
-        JSFunction *fun;
-        if (IsFunctionObject(v, &fun) && fun->isClonedMethod()) {
-            for (StackFrame *fp = cx->maybefp(); fp; fp = fp->prev()) {
-                if (fp->isFunctionFrame() &&
-                    fp->fun()->script() == fun->script() &&
-                    fp->thisValue().isObject())
-                {
-                    JSObject *tmp = &fp->thisValue().toObject();
-                    do {
-                        if (tmp == obj) {
-                            fp->overwriteCallee(*fun);
-                            break;
-                        }
-                    } while ((tmp = tmp->getProto()) != NULL);
-                }
-            }
-        }
     }
 
     if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
         return false;
     if (rval->isFalse())
         return true;
 
     return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
@@ -5686,17 +5519,17 @@ js_DeleteSpecial(JSContext *cx, JSObject
 
 namespace js {
 
 bool
 HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     JS_ASSERT(id == js_CheckForStringIndex(id));
     if (const Shape *shape = obj->nativeLookup(cx, id)) {
-        if (shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) {
+        if (shape->hasDefaultGetter() && shape->hasSlot()) {
             *vp = obj->nativeGetSlot(shape->slot());
             return true;
         }
     }
 
     return false;
 }
 
@@ -5706,17 +5539,17 @@ HasDataProperty(JSContext *cx, JSObject 
  * and |obj| as |this|, returning the result in *vp.
  *
  * This is a mini-abstraction for ES5 8.12.8 [[DefaultValue]], either steps 1-2
  * or steps 3-4.
  */
 static bool
 MaybeCallMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
-    if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, vp))
+    if (!js_GetMethod(cx, obj, id, 0, vp))
         return false;
     if (!js_IsCallable(*vp)) {
         *vp = ObjectValue(*obj);
         return true;
     }
     return Invoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp);
 }
 
@@ -6216,17 +6049,16 @@ DumpProperty(JSObject *obj, const Shape 
     jsid id = shape.propid();
     uint8_t attrs = shape.attributes();
 
     fprintf(stderr, "    ((Shape *) %p) ", (void *) &shape);
     if (attrs & JSPROP_ENUMERATE) fprintf(stderr, "enumerate ");
     if (attrs & JSPROP_READONLY) fprintf(stderr, "readonly ");
     if (attrs & JSPROP_PERMANENT) fprintf(stderr, "permanent ");
     if (attrs & JSPROP_SHARED) fprintf(stderr, "shared ");
-    if (shape.isMethod()) fprintf(stderr, "method ");
 
     if (shape.hasGetterValue())
         fprintf(stderr, "getterValue=%p ", (void *) shape.getterObject());
     else if (!shape.hasDefaultGetter())
         fprintf(stderr, "getterOp=%p ", JS_FUNC_TO_DATA_PTR(void *, shape.getterOp()));
 
     if (shape.hasSetterValue())
         fprintf(stderr, "setterValue=%p ", (void *) shape.setterObject());
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -504,29 +504,18 @@ struct JSObject : public js::ObjectImpl
     };
 
     bool setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag,
                  GenerateShape generateShape = GENERATE_NONE);
 
   public:
     inline bool nativeEmpty() const;
 
-    js::Shape *methodShapeChange(JSContext *cx, const js::Shape &shape);
     bool shadowingShapeChange(JSContext *cx, const js::Shape &shape);
 
-    /*
-     * Read barrier to clone a joined function object stored as a method.
-     * Defined in jsobjinlines.h, but not declared inline per standard style in
-     * order to avoid gcc warnings.
-     */
-    js::Shape *methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp);
-
-    /* Whether method shapes can be added to this object. */
-    inline bool canHaveMethodBarrier() const;
-
     /* Whether there may be indexed properties on this object. */
     inline bool isIndexed() const;
 
     inline uint32_t propertyCount() const;
 
     inline bool hasPropertyTable() const;
 
     inline size_t computedSizeOfThisSlotsElements() const;
@@ -568,18 +557,16 @@ struct JSObject : public js::ObjectImpl
      * Trigger the write barrier on a range of slots that will no longer be
      * reachable.
      */
     inline void prepareSlotRangeForOverwrite(size_t start, size_t end);
     inline void prepareElementRangeForOverwrite(size_t start, size_t end);
 
     void rollbackProperties(JSContext *cx, uint32_t slotSpan);
 
-    inline JSFunction *nativeGetMethod(const js::Shape *shape) const;
-
     inline void nativeSetSlot(unsigned slot, const js::Value &value);
     inline void nativeSetSlotWithType(JSContext *cx, const js::Shape *shape, const js::Value &value);
 
     inline const js::Value &getReservedSlot(unsigned index) const;
     inline js::HeapSlot &getReservedSlotRef(unsigned index);
     inline void initReservedSlot(unsigned index, const js::Value &v);
     inline void setReservedSlot(unsigned index, const js::Value &v);
 
@@ -935,16 +922,18 @@ struct JSObject : public js::ObjectImpl
                 uint32_t slot, unsigned attrs, unsigned flags, int shortid) {
         return putProperty(cx, js_CheckForStringIndex(ATOM_TO_JSID(name)), getter, setter, slot, attrs, flags, shortid);
     }
 
     /* Change the given property into a sibling with the same id in this scope. */
     js::Shape *changeProperty(JSContext *cx, js::Shape *shape, unsigned attrs, unsigned mask,
                               JSPropertyOp getter, JSStrictPropertyOp setter);
 
+    inline bool changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs);
+
     /* Remove the property named by id from this object. */
     bool removeProperty(JSContext *cx, jsid id);
 
     /* Clear the scope, making it empty. */
     void clear(JSContext *cx);
 
     inline JSBool lookupGeneric(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp);
     inline JSBool lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp);
@@ -1346,44 +1335,31 @@ js_CheckForStringIndex(jsid id);
  * Find or create a property named by id in obj's scope, with the given getter
  * and setter, slot, attributes, and other members.
  */
 extern js::Shape *
 js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
                      JSPropertyOp getter, JSStrictPropertyOp setter, uint32_t slot,
                      unsigned attrs, unsigned flags, int shortid);
 
-/*
- * Change shape to have the given attrs, getter, and setter in scope, morphing
- * it into a potentially new js::Shape.  Return a pointer to the changed
- * or identical property.
- */
-extern js::Shape *
-js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
-                             js::Shape *shape, unsigned attrs, unsigned mask,
-                             JSPropertyOp getter, JSStrictPropertyOp setter);
-
 extern JSBool
 js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
                      const js::Value &descriptor, JSBool *bp);
 
 namespace js {
 
 /*
  * Flags for the defineHow parameter of js_DefineNativeProperty.
  */
 const unsigned DNP_CACHE_RESULT = 1;   /* an interpreter call from JSOP_INITPROP */
 const unsigned DNP_DONT_PURGE   = 2;   /* suppress js_PurgeScopeChain */
-const unsigned DNP_SET_METHOD   = 4;   /* DefineNativeProperty,js_SetPropertyHelper
-                                       must pass the js::Shape::METHOD
-                                       flag on to JSObject::{add,put}Property */
-const unsigned DNP_UNQUALIFIED  = 8;   /* Unqualified property set.  Only used in
+const unsigned DNP_UNQUALIFIED  = 4;   /* Unqualified property set.  Only used in
                                        the defineHow argument of
                                        js_SetPropertyHelper. */
-const unsigned DNP_SKIP_TYPE = 0x10;   /* Don't update type information */
+const unsigned DNP_SKIP_TYPE    = 8;   /* Don't update type information */
 
 /*
  * Return successfully added or changed shape or NULL on error.
  */
 extern const Shape *
 DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                      unsigned flags, int shortid, unsigned defineHow = 0);
@@ -1455,32 +1431,18 @@ FindProperty(JSContext *cx, PropertyName
 extern JSObject *
 FindIdentifierBase(JSContext *cx, JSObject *scopeChain, PropertyName *name);
 
 }
 
 extern JSObject *
 js_FindVariableScope(JSContext *cx, JSFunction **funp);
 
-/*
- * JSGET_CACHE_RESULT is the analogue of JSDNP_CACHE_RESULT for js_GetMethod.
- *
- * JSGET_METHOD_BARRIER (the default, hence 0 but provided for documentation)
- * enables a read barrier that preserves standard function object semantics (by
- * default we assume our caller won't leak a joined callee to script, where it
- * would create hazardous mutable object sharing as well as observable identity
- * according to == and ===.
- *
- * JSGET_NO_METHOD_BARRIER avoids the performance overhead of the method read
- * barrier, which is not needed when invoking a lambda that otherwise does not
- * leak its callee reference (via arguments.callee or its name).
- */
-const unsigned JSGET_METHOD_BARRIER    = 0; // get can leak joined function object
-const unsigned JSGET_NO_METHOD_BARRIER = 1; // call to joined function can't leak
-const unsigned JSGET_CACHE_RESULT      = 2; // from a caching interpreter opcode
+/* JSGET_CACHE_RESULT is the analogue of DNP_CACHE_RESULT for js_GetMethod. */
+const unsigned JSGET_CACHE_RESULT = 1; // from a caching interpreter opcode
 
 /*
  * NB: js_NativeGet and js_NativeSet are called with the scope containing shape
  * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
  * scope is again locked.  But on failure, both functions return false with the
  * scope containing shape unlocked.
  */
 extern JSBool
@@ -1521,24 +1483,16 @@ namespace js {
 inline bool
 GetMethod(JSContext *cx, JSObject *obj, PropertyName *name, unsigned getHow, Value *vp)
 {
     return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
 }
 
 } /* namespace js */
 
-/*
- * Change attributes for the given native property. The caller must ensure
- * that obj is locked and this function always unlocks obj on return.
- */
-extern JSBool
-js_SetNativeAttributes(JSContext *cx, JSObject *obj, js::Shape *shape,
-                       unsigned attrs);
-
 namespace js {
 
 /*
  * If obj has an already-resolved data property for id, return true and
  * store the property value in *vp. This helper assumes the caller has already
  * called js_CheckForStringIndex.
  */
 extern bool
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -165,16 +165,22 @@ JSObject::setElementAttributes(JSContext
 }
 
 inline JSBool
 JSObject::setSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp)
 {
     return setGenericAttributes(cx, SPECIALID_TO_JSID(sid), attrsp);
 }
 
+inline bool
+JSObject::changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs)
+{
+    return !!changeProperty(cx, shape, attrs, 0, shape->getter(), shape->setter());
+}
+
 inline JSBool
 JSObject::getGeneric(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp)
 {
     js::GenericIdOp op = getOps()->getGeneric;
     if (op) {
         if (!op(cx, this, receiver, id, vp))
             return false;
     } else {
@@ -260,60 +266,16 @@ JSObject::getParent() const
 }
 
 inline JSObject *
 JSObject::enclosingScope()
 {
     return isScope() ? &asScope().enclosingScope() : getParent();
 }
 
-/*
- * Property read barrier for deferred cloning of compiler-created function
- * objects optimized as typically non-escaping, ad-hoc methods in obj.
- */
-inline js::Shape *
-JSObject::methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp)
-{
-    JS_ASSERT(nativeContains(cx, shape));
-    JS_ASSERT(shape.isMethod());
-    JS_ASSERT(shape.hasSlot());
-    JS_ASSERT(shape.hasDefaultSetter());
-    JS_ASSERT(!isGlobal());  /* i.e. we are not changing the global shape */
-
-    JSFunction *fun = vp->toObject().toFunction();
-    JS_ASSERT(!fun->isClonedMethod());
-    JS_ASSERT(fun->isNullClosure());
-
-    fun = js::CloneFunctionObject(cx, fun);
-    if (!fun)
-        return NULL;
-    fun->setMethodObj(*this);
-
-    /*
-     * Replace the method property with an ordinary data property. This is
-     * equivalent to this->setProperty(cx, shape.id, vp) except that any
-     * watchpoint on the property is not triggered.
-     */
-    uint32_t slot = shape.slot();
-    js::Shape *newshape = methodShapeChange(cx, shape);
-    if (!newshape)
-        return NULL;
-    JS_ASSERT(!newshape->isMethod());
-    JS_ASSERT(newshape->slot() == slot);
-    vp->setObject(*fun);
-    nativeSetSlot(slot, *vp);
-    return newshape;
-}
-
-inline bool
-JSObject::canHaveMethodBarrier() const
-{
-    return isObject() || isFunction() || isPrimitive() || isDate();
-}
-
 inline bool
 JSObject::isFixedSlot(size_t slot)
 {
     JS_ASSERT(!isDenseArray());
     return slot < numFixedSlots();
 }
 
 inline size_t
@@ -959,32 +921,16 @@ JSObject::isCallable()
 inline JSPrincipals *
 JSObject::principals(JSContext *cx)
 {
     if (JSObjectPrincipalsFinder find = cx->runtime->securityCallbacks->findObjectPrincipals)
         return find(this);
     return cx->compartment ? cx->compartment->principals : NULL;
 }
 
-inline JSFunction *
-JSObject::nativeGetMethod(const js::Shape *shape) const
-{
-    /*
-     * For method shapes, this object must have an uncloned function object in
-     * the shape's slot.
-     */
-    JS_ASSERT(shape->isMethod());
-#ifdef DEBUG
-    JSObject *obj = &nativeGetSlot(shape->slot()).toObject();
-    JS_ASSERT(obj->isFunction() && !obj->toFunction()->isClonedMethod());
-#endif
-
-    return static_cast<JSFunction *>(&nativeGetSlot(shape->slot()).toObject());
-}
-
 inline void
 JSObject::nativeSetSlot(unsigned slot, const js::Value &value)
 {
     JS_ASSERT(isNative());
     JS_ASSERT(slot < slotSpan());
     return setSlot(slot, value);
 }
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -307,17 +307,17 @@ static bool
 PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, StringifyContext *scx)
 {
     JSString *keyStr = NULL;
 
     /* Step 2. */
     if (vp->isObject()) {
         Value toJSON;
         jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
-        if (!js_GetMethod(cx, &vp->toObject(), id, JSGET_NO_METHOD_BARRIER, &toJSON))
+        if (!js_GetMethod(cx, &vp->toObject(), id, 0, &toJSON))
             return false;
 
         if (js_IsCallable(toJSON)) {
             keyStr = KeyStringifier<KeyType>::toString(cx, key);
             if (!keyStr)
                 return false;
 
             InvokeArgsGuard args;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -4510,17 +4510,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                 PROPAGATE_CALLNESS();
                 lval = PopStr(ss, op, &lvalpc);
                 todo = ss->sprinter.getOffset();
                 SprintOpcode(ss, lval, lvalpc, pc, todo);
                 Sprint(&ss->sprinter, fmt, rval);
                 break;
 
               case JSOP_SETPROP:
-              case JSOP_SETMETHOD:
               {
                 LOAD_ATOM(0);
                 GET_QUOTE_AND_FMT("[%s] %s= ", ".%s %s= ", xval);
                 rval = PopStrDupe(ss, op, &rvalpc);
 
                 /*
                  * Force precedence below the numeric literal opcodes, so that
                  * 42..foo or 10000..toString(16), e.g., decompile with parens
@@ -5115,17 +5114,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                     goto do_initprop;
                 }
                 maybeComma = isFirst ? "" : ", ";
                 todo = Sprint(&ss->sprinter, "%s%s", lval, maybeComma);
                 SprintOpcode(ss, rval, rvalpc, pc, todo);
                 break;
 
               case JSOP_INITPROP:
-              case JSOP_INITMETHOD:
                 LOAD_ATOM(0);
                 xval = QuoteString(&ss->sprinter, atom, jschar(IsIdentifier(atom) ? 0 : '\''));
                 if (!xval)
                     return NULL;
                 isFirst = IsInitializerOp(ss->opcodes[ss->top - 2]);
                 rval = PopStrDupe(ss, op, &rvalpc);
                 lval = PopStr(ss, op, &lvalpc);
                 /* fall through */
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -564,17 +564,17 @@ class OpcodeCounts
         ACCESS_COUNT
     };
 
     static bool accessOp(JSOp op) {
         /*
          * Access ops include all name, element and property reads, as well as
          * SETELEM and SETPROP (for ElementCounts/PropertyCounts alignment).
          */
-        if (op == JSOP_SETELEM || op == JSOP_SETPROP || op == JSOP_SETMETHOD)
+        if (op == JSOP_SETELEM || op == JSOP_SETPROP)
             return true;
         int format = js_CodeSpec[op].format;
         return !!(format & (JOF_NAME | JOF_GNAME | JOF_ELEM | JOF_PROP))
             && !(format & (JOF_SET | JOF_INCDEC));
     }
 
     enum ElementCounts {
         ELEM_ID_INT = ACCESS_COUNT,
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -527,25 +527,20 @@ OPDEF(JSOP_LENGTH,        217, "length",
 /*
  * Push a JSVAL_HOLE value onto the stack, representing an omitted property in
  * an array literal (e.g. property 0 in the array [, 1]).  This opcode is used
  * with the JSOP_NEWARRAY opcode.
  */
 OPDEF(JSOP_HOLE,          218, "hole",         NULL,  1,  0,  1,  0,  JOF_BYTE)
 
 OPDEF(JSOP_UNUSED17,      219,"unused17",      NULL,  1,  0,  0,  0,  JOF_BYTE)
-OPDEF(JSOP_UNUSED24,      220,"unused18",      NULL,  1,  0,  0,  0,  JOF_BYTE)
-OPDEF(JSOP_UNUSED25,      221,"unused19",      NULL,  1,  0,  0,  0,  JOF_BYTE)
-
-/*
- * Joined function object as method optimization support.
- */
-OPDEF(JSOP_SETMETHOD,     222,"setmethod",     NULL,  5,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
-OPDEF(JSOP_INITMETHOD,    223,"initmethod",    NULL,  5,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
-
+OPDEF(JSOP_UNUSED24,      220,"unused24",      NULL,  1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED25,      221,"unused25",      NULL,  1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED29,      222,"unused29",      NULL,  1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED30,      223,"unused30",      NULL,  1,  0,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_UNUSED16,      224,"unused16",      NULL,  1,  0,  0,  0,  JOF_BYTE)
 
 /* Pop the stack, convert to a jsid (int or string), and push back. */
 OPDEF(JSOP_TOID,          225, "toid",         NULL,  1,  1,  1,  0,  JOF_BYTE)
 
 /* Push the implicit 'this' value for calls to the associated name. */
 OPDEF(JSOP_IMPLICITTHIS,  226, "implicitthis", "",    5,  0,  1,  0,  JOF_ATOM)
 
--- a/js/src/jspropertytree.cpp
+++ b/js/src/jspropertytree.cpp
@@ -292,17 +292,16 @@ Shape::dump(JSContext *cx, FILE *fp) con
     }
 
     fprintf(fp, "flags %x ", flags);
     if (flags) {
         int first = 1;
         fputs("(", fp);
 #define DUMP_FLAG(name, display) if (flags & name) fputs(&(" " #display)[first], fp), first = 0
         DUMP_FLAG(HAS_SHORTID, has_shortid);
-        DUMP_FLAG(METHOD, method);
         DUMP_FLAG(IN_DICTIONARY, in_dictionary);
 #undef  DUMP_FLAG
         fputs(") ", fp);
     }
 
     fprintf(fp, "shortid %d\n", shortid());
 }
 
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -493,26 +493,19 @@ NormalizeGetterAndSetter(JSContext *cx, 
                          jsid id, unsigned attrs, unsigned flags,
                          PropertyOp &getter,
                          StrictPropertyOp &setter)
 {
     if (setter == JS_StrictPropertyStub) {
         JS_ASSERT(!(attrs & JSPROP_SETTER));
         setter = NULL;
     }
-    if (flags & Shape::METHOD) {
-        JS_ASSERT_IF(getter, getter == JS_PropertyStub);
-        JS_ASSERT(!setter);
-        JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
+    if (getter == JS_PropertyStub) {
+        JS_ASSERT(!(attrs & JSPROP_GETTER));
         getter = NULL;
-    } else {
-        if (getter == JS_PropertyStub) {
-            JS_ASSERT(!(attrs & JSPROP_GETTER));
-            getter = NULL;
-        }
     }
 
     return true;
 }
 
 Shape *
 JSObject::addProperty(JSContext *cx, jsid id,
                       PropertyOp getter, StrictPropertyOp setter,
@@ -803,19 +796,16 @@ JSObject::changeProperty(JSContext *cx, 
     JS_ASSERT(nativeContains(cx, *shape));
 
     attrs |= shape->attrs & mask;
 
     /* Allow only shared (slotless) => unshared (slotful) transition. */
     JS_ASSERT(!((attrs ^ shape->attrs) & JSPROP_SHARED) ||
               !(attrs & JSPROP_SHARED));
 
-    /* Don't allow method properties to be changed to have a getter or setter. */
-    JS_ASSERT_IF(shape->isMethod(), !getter && !setter);
-
     types::MarkTypePropertyConfigured(cx, this, shape->propid());
     if (attrs & (JSPROP_GETTER | JSPROP_SETTER))
         types::AddTypePropertyId(cx, this, shape->propid(), types::Type::UnknownType());
 
     if (getter == JS_PropertyStub)
         getter = NULL;
     if (setter == JS_StrictPropertyStub)
         setter = NULL;
@@ -1036,54 +1026,16 @@ JSObject::replaceWithNewEquivalentShape(
     if (newShape == lastProperty())
         oldShape->handoffTableTo(newShape);
 
     if (spp)
         SHAPE_STORE_PRESERVING_COLLISION(spp, newShape);
     return newShape;
 }
 
-Shape *
-JSObject::methodShapeChange(JSContext *cx, const Shape &shape)
-{
-    JS_ASSERT(shape.isMethod());
-
-    if (!inDictionaryMode() && !toDictionaryMode(cx))
-        return NULL;
-
-    Shape *spare = js_NewGCShape(cx);
-    if (!spare)
-        return NULL;
-    new (spare) Shape(shape.base()->unowned(), 0);
-
-#ifdef DEBUG
-    JS_ASSERT(canHaveMethodBarrier());
-    JS_ASSERT(!shape.setter());
-    JS_ASSERT(!shape.hasShortID());
-#endif
-
-    /*
-     * Clear Shape::METHOD from flags as we are despecializing from a
-     * method memoized in the property tree to a plain old function-valued
-     * property.
-     */
-    Shape *result =
-        putProperty(cx, shape.propid(), NULL, NULL, shape.slot(),
-                    shape.attrs,
-                    shape.getFlags() & ~Shape::METHOD,
-                    0);
-    if (!result)
-        return NULL;
-
-    if (result != lastProperty())
-        JS_ALWAYS_TRUE(generateOwnShape(cx, spare));
-
-    return result;
-}
-
 bool
 JSObject::shadowingShapeChange(JSContext *cx, const Shape &shape)
 {
     return generateOwnShape(cx);
 }
 
 bool
 JSObject::clearParent(JSContext *cx)
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -644,53 +644,25 @@ struct Shape : public js::gc::Cell
      * assigned yet. After construction, hasSlot() implies !hasMissingSlot().
      */
     bool hasMissingSlot() const { return maybeSlot() == SHAPE_INVALID_SLOT; }
 
   public:
     /* Public bits stored in shape->flags. */
     enum {
         HAS_SHORTID     = 0x40,
-        METHOD          = 0x80,
-        PUBLIC_FLAGS    = HAS_SHORTID | METHOD
+        PUBLIC_FLAGS    = HAS_SHORTID
     };
 
     bool inDictionary() const   { return (flags & IN_DICTIONARY) != 0; }
     unsigned getFlags() const  { return flags & PUBLIC_FLAGS; }
     bool hasShortID() const { return (flags & HAS_SHORTID) != 0; }
 
-    /*
-     * A shape has a method barrier when some compiler-created "null closure"
-     * function objects (functions that do not use lexical bindings above their
-     * scope, only free variable names) that have a correct JSSLOT_PARENT value
-     * thanks to the COMPILE_N_GO optimization are stored in objects without
-     * cloning.
-     *
-     * The de-facto standard JS language requires each evaluation of such a
-     * closure to result in a unique (according to === and observable effects)
-     * function object. When storing a function to a property, we use method
-     * shapes to speculate that these effects will never be observed: the
-     * property will only be used in calls, and f.callee will not be used
-     * to get a handle on the object.
-     *
-     * If either a non-call use or callee access occurs, then the function is
-     * cloned and the object is reshaped with a non-method property.
-     *
-     * Note that method shapes do not imply the object has a particular
-     * uncloned function, just that the object has *some* uncloned function
-     * in the shape's slot.
-     */
-    bool isMethod() const {
-        JS_ASSERT_IF(flags & METHOD, !base()->rawGetter);
-        return (flags & METHOD) != 0;
-    }
-
     PropertyOp getter() const { return base()->rawGetter; }
-    bool hasDefaultGetterOrIsMethod() const { return !base()->rawGetter; }
-    bool hasDefaultGetter() const  { return !base()->rawGetter && !isMethod(); }
+    bool hasDefaultGetter() const  { return !base()->rawGetter; }
     PropertyOp getterOp() const { JS_ASSERT(!hasGetterValue()); return base()->rawGetter; }
     JSObject *getterObject() const { JS_ASSERT(hasGetterValue()); return base()->getterObj; }
 
     // Per ES5, decode null getterObj as the undefined value, which encodes as null.
     Value getterValue() const {
         JS_ASSERT(hasGetterValue());
         return base()->getterObj ? js::ObjectValue(*base()->getterObj) : js::UndefinedValue();
     }
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -277,26 +277,20 @@ Shape::matchesParamsAfterId(BaseShape *b
 }
 
 inline bool
 Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
 {
     JS_ASSERT(!hasDefaultGetter());
 
     if (hasGetterValue()) {
-        JS_ASSERT(!isMethod());
         js::Value fval = getterValue();
         return js::InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
     }
 
-    if (isMethod()) {
-        vp->setObject(*pobj->nativeGetMethod(this));
-        return pobj->methodReadBarrier(cx, *this, vp);
-    }
-
     /*
      * |with (it) color;| ends up here, as do XML filter-expressions.
      * Avoid exposing the With object to native getters.
      */
     if (obj->isWith())
         obj = &obj->asWith().object();
     return js::CallJSPropertyOp(cx, getterOp(), receiver, getUserId(), vp);
 }
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3307,17 +3307,17 @@ js_ValueToSource(JSContext *cx, const Va
             return js_NewStringCopyN(cx, js_negzero_ucNstr, 2);
         }
         return ToString(cx, v);
     }
 
     Value rval = NullValue();
     Value fval;
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
-    if (!js_GetMethod(cx, &v.toObject(), id, JSGET_NO_METHOD_BARRIER, &fval))
+    if (!js_GetMethod(cx, &v.toObject(), id, 0, &fval))
         return NULL;
     if (js_IsCallable(fval)) {
         if (!Invoke(cx, v, fval, 0, NULL, &rval))
             return NULL;
     }
 
     return ToString(cx, rval);
 }
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -144,36 +144,18 @@ WatchpointMap::triggerWatchpoint(JSConte
     JSWatchPointHandler handler = p->value.handler;
     JSObject *closure = p->value.closure;
 
     /* Determine the property's old value. */
     Value old;
     old.setUndefined();
     if (obj->isNative()) {
         if (const Shape *shape = obj->nativeLookup(cx, id)) {
-            if (shape->hasSlot()) {
-                if (shape->isMethod()) {
-                    /*
-                     * The existing watched property is a method. Trip
-                     * the method read barrier in order to avoid
-                     * passing an uncloned function object to the
-                     * handler.
-                     */
-                    old = UndefinedValue();
-                    Value method = ObjectValue(*obj->nativeGetMethod(shape));
-                    if (!obj->methodReadBarrier(cx, *shape, &method))
-                        return false;
-                    shape = obj->nativeLookup(cx, id);
-                    JS_ASSERT(shape->isDataDescriptor());
-                    JS_ASSERT(!shape->isMethod());
-                    old = method;
-                } else {
-                    old = obj->nativeGetSlot(shape->slot());
-                }
-            }
+            if (shape->hasSlot())
+                old = obj->nativeGetSlot(shape->slot());
         }
     }
 
     /* Call the handler. */
     return handler(cx, obj, id, old, vp, closure);
 }
 
 bool
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1710,18 +1710,17 @@ mjit::Compiler::finishThisUp()
 
         jitPics[i].shapeGuard = masm.distanceOf(pics[i].shapeGuard) -
                                 masm.distanceOf(pics[i].fastPathStart);
         JS_ASSERT(jitPics[i].shapeGuard == masm.distanceOf(pics[i].shapeGuard) -
                                            masm.distanceOf(pics[i].fastPathStart));
         jitPics[i].shapeRegHasBaseShape = true;
         jitPics[i].pc = pics[i].pc;
 
-        if (pics[i].kind == ic::PICInfo::SET ||
-            pics[i].kind == ic::PICInfo::SETMETHOD) {
+        if (pics[i].kind == ic::PICInfo::SET) {
             jitPics[i].u.vr = pics[i].vr;
         } else if (pics[i].kind != ic::PICInfo::NAME) {
             if (pics[i].hasTypeCheck) {
                 int32_t distance = stubcc.masm.distanceOf(pics[i].typeCheck) -
                                  stubcc.masm.distanceOf(pics[i].slowPathStart);
                 JS_ASSERT(distance <= 0);
                 jitPics[i].u.get.typeCheckOffset = distance;
             }
@@ -2895,21 +2894,16 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_NEWOBJECT)
             if (!jsop_newinit())
                 return Compile_Error;
           END_CASE(JSOP_NEWOBJECT)
 
           BEGIN_CASE(JSOP_ENDINIT)
           END_CASE(JSOP_ENDINIT)
 
-          BEGIN_CASE(JSOP_INITMETHOD)
-            jsop_initmethod();
-            frame.pop();
-          END_CASE(JSOP_INITMETHOD)
-
           BEGIN_CASE(JSOP_INITPROP)
             jsop_initprop();
             frame.pop();
           END_CASE(JSOP_INITPROP)
 
           BEGIN_CASE(JSOP_INITELEM)
             jsop_initelem();
             frame.popn(2);
@@ -2966,17 +2960,16 @@ mjit::Compiler::generateMethod()
             jsbytecode *next = &PC[JSOP_SETPROP_LENGTH];
             bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
             if (!jsop_setprop(script->getName(GET_UINT32_INDEX(PC)), pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETPROP)
 
           BEGIN_CASE(JSOP_SETNAME)
-          BEGIN_CASE(JSOP_SETMETHOD)
           {
             jsbytecode *next = &PC[JSOP_SETNAME_LENGTH];
             bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
             if (!jsop_setprop(script->getName(GET_UINT32_INDEX(PC)), pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETNAME)
 
@@ -3073,39 +3066,16 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_LAMBDA)
           {
             JSFunction *fun = script->getFunction(GET_UINT32_INDEX(PC));
 
             JSObjStubFun stub = stubs::Lambda;
             uint32_t uses = 0;
 
-            jsbytecode *pc2 = NULL;
-            if (fun->joinable()) {
-                pc2 = PC + JSOP_LAMBDA_LENGTH;
-                JSOp next = JSOp(*pc2);
-
-                if (next == JSOP_INITMETHOD) {
-                    stub = stubs::LambdaJoinableForInit;
-                } else if (next == JSOP_SETMETHOD) {
-                    stub = stubs::LambdaJoinableForSet;
-                    uses = 1;
-                } else if (next == JSOP_CALL) {
-                    int iargc = GET_ARGC(pc2);
-                    if (iargc == 1 || iargc == 2) {
-                        stub = stubs::LambdaJoinableForCall;
-                        uses = frame.frameSlots();
-                    }
-                } else if (next == JSOP_NULL) {
-                    pc2 += JSOP_NULL_LENGTH;
-                    if (JSOp(*pc2) == JSOP_CALL && GET_ARGC(pc2) == 0)
-                        stub = stubs::LambdaJoinableForNull;
-                }
-            }
-
             prepareStubCall(Uses(uses));
             masm.move(ImmPtr(fun), Registers::ArgReg1);
 
             INLINE_STUBCALL(stub, REJOIN_PUSH_OBJECT);
 
             frame.takeReg(Registers::ReturnReg);
             frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
           }
@@ -3244,17 +3214,17 @@ mjit::Compiler::generateMethod()
                 if (PC == lastPC + GetBytecodeLength(lastPC))
                     pushed = frame.peek(-1);
                 updateArithCounters(lastPC, pushed, arithFirstUseType, arithSecondUseType);
                 typesUpdated = true;
             }
 
             /* Update information about the result type of access operations. */
             if (OpcodeCounts::accessOp(op) &&
-                op != JSOP_SETPROP && op != JSOP_SETMETHOD && op != JSOP_SETELEM) {
+                op != JSOP_SETPROP && op != JSOP_SETELEM) {
                 FrameEntry *fe = (GetDefCount(script, lastPC - script->code) == 1)
                     ? frame.peek(-1)
                     : frame.peek(-2);
                 updatePCTypes(lastPC, fe);
                 typesUpdated = true;
             }
 
             if (countersUpdated || typesUpdated || length != 0) {
@@ -5262,17 +5232,17 @@ mjit::Compiler::testSingletonProperty(JS
         return false;
 
     Shape *shape = (Shape *) prop;
     if (shape->hasDefaultGetter()) {
         if (!shape->hasSlot())
             return false;
         if (holder->getSlot(shape->slot()).isUndefined())
             return false;
-    } else if (!shape->isMethod()) {
+    } else {
         return false;
     }
 
     return true;
 }
 
 bool
 mjit::Compiler::testSingletonPropertyTypes(FrameEntry *top, jsid id, bool *testObject)
@@ -5595,20 +5565,17 @@ mjit::Compiler::jsop_setprop(PropertyNam
     if (cx->compartment->needsBarrier() &&
         (!types || op == JSOP_SETNAME || types->propertyNeedsBarrier(cx, id)))
     {
         jsop_setprop_slow(name);
         return true;
     }
 #endif
 
-    ic::PICInfo::Kind kind = (op == JSOP_SETMETHOD)
-                             ? ic::PICInfo::SETMETHOD
-                             : ic::PICInfo::SET;
-    PICGenInfo pic(kind, op);
+    PICGenInfo pic(ic::PICInfo::SET, op);
     pic.name = name;
 
     if (monitored(PC)) {
         pic.typeMonitored = true;
         types::TypeSet *types = frame.extra(rhs).types;
         if (!types) {
             /* Handle FORNAME and other compound opcodes. Yuck. */
             types = types::TypeSet::make(cx, "unknownRHS");
@@ -6369,17 +6336,17 @@ mjit::Compiler::jsop_getgname(uint32_t i
             return;
 
         /*
          * If we are accessing a defined global which is a normal data property
          * then bake its address into the jitcode and guard against future
          * reallocation of the global object's slots.
          */
         const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
-        if (shape && shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) {
+        if (shape && shape->hasDefaultGetter() && shape->hasSlot()) {
             HeapSlot *value = &globalObj->getSlotRef(shape->slot());
             if (!value->isUndefined() &&
                 !propertyTypes->isOwnProperty(cx, globalObj->getType(cx), true)) {
                 watchGlobalReallocation();
                 RegisterID reg = frame.allocReg();
                 masm.move(ImmPtr(value), reg);
 
                 BarrierState barrier = pushAddressMaybeBarrier(Address(reg), type, true);
@@ -6492,17 +6459,17 @@ mjit::Compiler::jsop_setgname(PropertyNa
          * branding there is no way to ensure that a non-function property
          * can't get a function later and cause the global object to become
          * branded, requiring a shape change if it changes again.
          */
         types::TypeSet *types = globalObj->getType(cx)->getProperty(cx, id, false);
         if (!types)
             return;
         const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
-        if (shape && !shape->isMethod() && shape->hasDefaultSetter() &&
+        if (shape && shape->hasDefaultSetter() &&
             shape->writable() && shape->hasSlot() &&
             !types->isOwnProperty(cx, globalObj->getType(cx), true)) {
             watchGlobalReallocation();
             HeapSlot *value = &globalObj->getSlotRef(shape->slot());
             RegisterID reg = frame.allocReg();
 #ifdef JSGC_INCREMENTAL_MJ
             /* Write barrier. */
             if (cx->compartment->needsBarrier() && types->needsBarrier(cx)) {
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -257,17 +257,17 @@ class Compiler : public BaseCompiler
             ic::ScopeNameLabels scopeNameLabels_;
         };
 
         ic::GetPropLabels &getPropLabels() {
             JS_ASSERT(kind == ic::PICInfo::GET);
             return getPropLabels_;
         }
         ic::SetPropLabels &setPropLabels() {
-            JS_ASSERT(kind == ic::PICInfo::SET || kind == ic::PICInfo::SETMETHOD);
+            JS_ASSERT(kind == ic::PICInfo::SET);
             return setPropLabels_;
         }
         ic::BindNameLabels &bindNameLabels() {
             JS_ASSERT(kind == ic::PICInfo::BIND);
             return bindNameLabels_;
         }
         ic::ScopeNameLabels &scopeNameLabels() {
             JS_ASSERT(kind == ic::PICInfo::NAME ||
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -2654,32 +2654,16 @@ mjit::Compiler::jsop_pos()
 
     stubcc.leave();
     OOL_STUBCALL(stubs::Pos, REJOIN_POS);
 
     stubcc.rejoin(Changes(1));
 }
 
 void
-mjit::Compiler::jsop_initmethod()
-{
-#ifdef DEBUG
-    FrameEntry *obj = frame.peek(-2);
-#endif
-    JSAtom *atom = script->getAtom(GET_UINT32_INDEX(PC));
-
-    /* Initializers with INITMETHOD are not fast yet. */
-    JS_ASSERT(!frame.extra(obj).initObject);
-
-    prepareStubCall(Uses(2));
-    masm.move(ImmPtr(atom), Registers::ArgReg1);
-    INLINE_STUBCALL(stubs::InitMethod, REJOIN_FALLTHROUGH);
-}
-
-void
 mjit::Compiler::jsop_initprop()
 {
     FrameEntry *obj = frame.peek(-2);
     FrameEntry *fe = frame.peek(-1);
     JSAtom *atom = script->getAtom(GET_UINT32_INDEX(PC));
 
     JSObject *baseobj = frame.extra(obj).initObject;
 
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -1864,18 +1864,17 @@ LoopState::analyzeLoopBody(unsigned fram
             SSAValue objValue = analysis->poppedValue(pc, 1);
             SSAValue elemValue = analysis->poppedValue(pc, 0);
 
             if (constrainedLoop && !definiteArrayAccess(objValue, elemValue))
                 constrainedLoop = false;
             break;
           }
 
-          case JSOP_SETPROP:
-          case JSOP_SETMETHOD: {
+          case JSOP_SETPROP: {
             JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
             jsid id = MakeTypeId(cx, ATOM_TO_JSID(atom));
 
             TypeSet *objTypes = analysis->poppedTypes(pc, 1);
             if (objTypes->unknownObject()) {
                 unknownModset = true;
                 break;
             }
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -94,17 +94,17 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlo
     const Shape *shape = obj.nativeLookup(f.cx, js_CheckForStringIndex(ATOM_TO_JSID(name)));
 
     if (monitor.recompiled()) {
         stubs::Name(f);
         return;
     }
 
     if (!shape ||
-        !shape->hasDefaultGetterOrIsMethod() ||
+        !shape->hasDefaultGetter() ||
         !shape->hasSlot())
     {
         if (shape)
             PatchGetFallback(f, ic);
         stubs::Name(f);
         return;
     }
     uint32_t slot = shape->slot();
@@ -160,18 +160,17 @@ SetGlobalNameIC::patchInlineShapeGuard(R
 
 static LookupStatus
 UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Shape *shape)
 {
     /* Give globals a chance to appear. */
     if (!shape)
         return Lookup_Uncacheable;
 
-    if (shape->isMethod() ||
-        !shape->hasDefaultSetter() ||
+    if (!shape->hasDefaultSetter() ||
         !shape->writable() ||
         !shape->hasSlot() ||
         obj->watched())
     {
         /* Disable the IC for weird shape attributes and watchpoints. */
         PatchSetFallback(f, ic);
         return Lookup_Uncacheable;
     }
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -345,33 +345,16 @@ class SetPropCompiler : public PICStubCo
                 Jump protoGuard = masm.guardShape(pic.shapeReg, proto);
                 if (!otherGuards.append(protoGuard))
                     return error();
 
                 proto = proto->getProto();
                 lastReg = pic.shapeReg;
             }
 
-            if (pic.kind == ic::PICInfo::SETMETHOD) {
-                /*
-                 * Guard that the value is equal to the shape's method.
-                 * We already know it is a function, so test the payload.
-                 */
-                JS_ASSERT(shape->isMethod());
-                JSObject *funobj = obj->nativeGetMethod(shape);
-                if (pic.u.vr.isConstant()) {
-                    JS_ASSERT(funobj == &pic.u.vr.value().toObject());
-                } else {
-                    Jump mismatchedFunction =
-                        masm.branchPtr(Assembler::NotEqual, pic.u.vr.dataReg(), ImmPtr(funobj));
-                    if (!slowExits.append(mismatchedFunction))
-                        return error();
-                }
-            }
-
             if (obj->isFixedSlot(shape->slot())) {
                 Address address(pic.objReg,
                                 JSObject::getFixedSlotOffset(shape->slot()));
                 masm.storeValue(pic.u.vr, address);
             } else {
                 /*
                  * Note: the guard on the initial shape determines the object's
                  * number of fixed slots and slot span, which in turn determine
@@ -384,17 +367,16 @@ class SetPropCompiler : public PICStubCo
             }
 
             JS_ASSERT(shape == obj->lastProperty());
             JS_ASSERT(shape != initialShape);
 
             /* Write the object's new shape. */
             masm.storePtr(ImmPtr(shape), Address(pic.objReg, JSObject::offsetOfShape()));
         } else if (shape->hasDefaultSetter()) {
-            JS_ASSERT(!shape->isMethod());
             Address address = masm.objPropAddress(obj, pic.objReg, shape->slot());
             masm.storeValue(pic.u.vr, address);
         } else {
             //   \ /        In general, two function objects with different JSFunctions
             //    #         can have the same shape, thus we must not rely on the identity
             // >--+--<      of 'fun' remaining the same. However, since:
             //   |||         1. the shape includes all arguments and locals and their setters
             //    \\     V     and getters, and
@@ -580,39 +562,26 @@ class SetPropCompiler : public PICStubCo
             }
 
             const Shape *initialShape = obj->lastProperty();
             uint32_t slots = obj->numDynamicSlots();
 
             unsigned flags = 0;
             PropertyOp getter = clasp->getProperty;
 
-            if (pic.kind == ic::PICInfo::SETMETHOD) {
-                if (!obj->canHaveMethodBarrier())
-                    return disable("can't have method barrier");
-
-                JSObject *funobj = &f.regs.sp[-1].toObject();
-                if (funobj->toFunction()->isClonedMethod())
-                    return disable("mismatched function");
-
-                flags |= Shape::METHOD;
-            }
-
             /*
              * Define the property but do not set it yet. For setmethod,
              * populate the slot to satisfy the method invariant (in case we
              * hit an early return below).
              */
             const Shape *shape =
                 obj->putProperty(cx, name, getter, clasp->setProperty,
                                  SHAPE_INVALID_SLOT, JSPROP_ENUMERATE, flags, 0);
             if (!shape)
                 return error();
-            if (flags & Shape::METHOD)
-                obj->nativeSetSlot(shape->slot(), f.regs.sp[-1]);
 
             if (monitor.recompiled())
                 return Lookup_Uncacheable;
 
             /*
              * Test after calling putProperty since it can switch obj into
              * dictionary mode, specifically if the shape tree ancestor line
              * exceeds PropertyTree::MAX_HEIGHT.
@@ -642,23 +611,18 @@ class SetPropCompiler : public PICStubCo
 
             if (pic.typeMonitored && !updateMonitoredTypes())
                 return Lookup_Uncacheable;
 
             return generateStub(initialShape, shape, true);
         }
 
         const Shape *shape = (const Shape *) prop;
-        if (pic.kind == ic::PICInfo::SETMETHOD && !shape->isMethod())
-            return disable("set method on non-method shape");
         if (!shape->writable())
             return disable("readonly");
-        if (shape->isMethod())
-            return disable("method");
-
         if (shape->hasDefaultSetter()) {
             if (!shape->hasSlot())
                 return disable("invalid slot");
             if (pic.typeMonitored && !updateMonitoredTypes())
                 return Lookup_Uncacheable;
         } else {
             if (shape->hasSetterValue())
                 return disable("scripted setter");
@@ -784,37 +748,32 @@ struct GetPropHelper {
         if (!IsCacheableProtoChain(obj, holder))
             return ic.disable(f, "non-native holder");
         shape = (const Shape *)prop;
         return Lookup_Cacheable;
     }
 
     LookupStatus testForGet() {
         if (!shape->hasDefaultGetter()) {
-            if (shape->isMethod()) {
-                if (JSOp(*f.pc()) != JSOP_CALLPROP)
-                    return ic.disable(f, "method valued shape");
-            } else {
-                if (shape->hasGetterValue())
-                    return ic.disable(f, "getter value shape");
-                if (shape->hasSlot() && holder != obj)
-                    return ic.disable(f, "slotful getter hook through prototype");
-                if (!ic.canCallHook)
-                    return ic.disable(f, "can't call getter hook");
-                if (f.regs.inlined()) {
-                    /*
-                     * As with native stubs, getter hook stubs can't be
-                     * generated for inline frames. Mark the inner function
-                     * as uninlineable and recompile.
-                     */
-                    f.script()->uninlineable = true;
-                    MarkTypeObjectFlags(cx, f.script()->function(),
-                                        types::OBJECT_FLAG_UNINLINEABLE);
-                    return Lookup_Uncacheable;
-                }
+            if (shape->hasGetterValue())
+                return ic.disable(f, "getter value shape");
+            if (shape->hasSlot() && holder != obj)
+                return ic.disable(f, "slotful getter hook through prototype");
+            if (!ic.canCallHook)
+                return ic.disable(f, "can't call getter hook");
+            if (f.regs.inlined()) {
+                /*
+                 * As with native stubs, getter hook stubs can't be
+                 * generated for inline frames. Mark the inner function
+                 * as uninlineable and recompile.
+                 */
+                f.script()->uninlineable = true;
+                MarkTypeObjectFlags(cx, f.script()->function(),
+                                    types::OBJECT_FLAG_UNINLINEABLE);
+                return Lookup_Uncacheable;
             }
         } else if (!shape->hasSlot()) {
             return ic.disable(f, "no slot");
         }
 
         return Lookup_Cacheable;
     }
 
@@ -957,17 +916,17 @@ class GetPropCompiler : public PICStubCo
             return Lookup_Uncacheable;
 
         GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
         LookupStatus status = getprop.lookupAndTest();
         if (status != Lookup_Cacheable)
             return status;
         if (getprop.obj != getprop.holder)
             return disable("proto walk on String.prototype");
-        if (!getprop.shape->hasDefaultGetterOrIsMethod())
+        if (!getprop.shape->hasDefaultGetter())
             return disable("getter hook on String.prototype");
         if (hadGC())
             return Lookup_Uncacheable;
 
         Assembler masm;
 
         /* Only strings are allowed. */
         Jump notString = masm.branchPtr(Assembler::NotEqual, pic.typeReg(),
@@ -1234,17 +1193,17 @@ class GetPropCompiler : public PICStubCo
             if (!shapeMismatches.append(j))
                 return error();
 
             pic.secondShapeGuard = masm.distanceOf(masm.label()) - masm.distanceOf(start);
         } else {
             pic.secondShapeGuard = 0;
         }
 
-        if (!shape->hasDefaultGetterOrIsMethod()) {
+        if (!shape->hasDefaultGetter()) {
             generateGetterStub(masm, shape, start, shapeMismatches);
             if (setStubShapeOffset)
                 pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
             return Lookup_Cacheable;
         }
 
         /* Load the value out of the object. */
         masm.loadObjProp(holder, holderReg, shape, pic.shapeReg, pic.objReg);
@@ -1322,17 +1281,17 @@ class GetPropCompiler : public PICStubCo
         GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
         LookupStatus status = getprop.lookupAndTest();
         if (status != Lookup_Cacheable)
             return status;
         if (hadGC())
             return Lookup_Uncacheable;
 
         if (obj == getprop.holder &&
-            getprop.shape->hasDefaultGetterOrIsMethod() &&
+            getprop.shape->hasDefaultGetter() &&
             !pic.inlinePathPatched) {
             return patchInline(getprop.holder, getprop.shape);
         }
 
         return generateStub(getprop.holder, getprop.shape);
     }
 };
 
@@ -1670,17 +1629,17 @@ class ScopeNameCompiler : public PICStub
                 return false;
             return true;
         }
 
         const Shape *shape = getprop.shape;
         JSObject *normalized = obj;
         if (obj->isWith() && !shape->hasDefaultGetter())
             normalized = &obj->asWith().object();
-        NATIVE_GET(cx, normalized, holder, shape, JSGET_METHOD_BARRIER, vp, return false);
+        NATIVE_GET(cx, normalized, holder, shape, 0, vp, return false);
         return true;
     }
 };
 
 class BindNameCompiler : public PICStubCompiler
 {
     JSObject *scopeChain;
     PropertyName *name;
--- a/js/src/methodjit/PolyIC.h
+++ b/js/src/methodjit/PolyIC.h
@@ -379,17 +379,16 @@ struct PICInfo : public BasePolyIC {
     // Operation this is a PIC for.
     enum Kind
 #ifdef _MSC_VER
     : uint8_t
 #endif
     {
         GET,        // JSOP_GETPROP
         SET,        // JSOP_SETPROP, JSOP_SETNAME
-        SETMETHOD,  // JSOP_SETMETHOD
         NAME,       // JSOP_NAME
         BIND,       // JSOP_BINDNAME
         XNAME       // JSOP_GETXPROP
     };
 
     union {
         struct {
             RegisterID typeReg  : 5;  // reg used for checking type
@@ -456,17 +455,17 @@ struct PICInfo : public BasePolyIC {
 
     // Offset from start of fast path to initial shape guard.
     uint32_t shapeGuard;
 
     // Possible types of the RHS, for monitored SETPROP PICs.
     types::TypeSet *rhsTypes;
     
     inline bool isSet() const {
-        return kind == SET || kind == SETMETHOD;
+        return kind == SET;
     }
     inline bool isGet() const {
         return kind == GET;
     }
     inline bool isBind() const {
         return kind == BIND;
     }
     inline bool isScopeName() const {
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -994,79 +994,16 @@ stubs::RegExp(VMFrame &f, JSObject *rege
     JS_ASSERT(proto);
     JSObject *obj = CloneRegExpObject(f.cx, regex, proto);
     if (!obj)
         THROW();
     f.regs.sp[0].setObject(*obj);
 }
 
 JSObject * JS_FASTCALL
-stubs::LambdaJoinableForInit(VMFrame &f, JSFunction *fun)
-{
-    JS_ASSERT(fun->joinable());
-    DebugOnly<jsbytecode*> nextpc = f.regs.pc + JSOP_LAMBDA_LENGTH;
-    JS_ASSERT(fun->methodAtom() == f.script()->getAtom(GET_UINT32_INDEX(nextpc)));
-    return fun;
-}
-
-JSObject * JS_FASTCALL
-stubs::LambdaJoinableForSet(VMFrame &f, JSFunction *fun)
-{
-    JS_ASSERT(fun->joinable());
-    const Value &lref = f.regs.sp[-1];
-    if (lref.isObject() && lref.toObject().canHaveMethodBarrier()) {
-        DebugOnly<jsbytecode*> nextpc = f.regs.pc + JSOP_LAMBDA_LENGTH;
-        JS_ASSERT(fun->methodAtom() == f.script()->getAtom(GET_UINT32_INDEX(nextpc)));
-        return fun;
-    }
-    return Lambda(f, fun);
-}
-
-JSObject * JS_FASTCALL
-stubs::LambdaJoinableForCall(VMFrame &f, JSFunction *fun)
-{
-    JS_ASSERT(fun->joinable());
-
-    /*
-     * Array.prototype.sort and String.prototype.replace are optimized as if
-     * they are special form. We know that they won't leak the joined function
-     * object fun, therefore we don't need to clone that compiler-created
-     * function object for identity/mutation reasons.
-     */
-    int iargc = GET_ARGC(f.regs.pc + JSOP_LAMBDA_LENGTH);
-
-    /*
-     * Note that we have not yet pushed fun as the final argument, so
-     * regs.sp[1 - (iargc + 2)], and not regs.sp[-(iargc + 2)], is the callee
-     * for this JSOP_CALL.
-     */
-    const Value &cref = f.regs.sp[1 - (iargc + 2)];
-    JSFunction *callee;
-
-    if (IsFunctionObject(cref, &callee)) {
-        Native native = callee->maybeNative();
-
-        if (native) {
-            if (iargc == 1 && native == array_sort)
-                return fun;
-            if (iargc == 2 && native == str_replace)
-                return fun;
-        }
-    }
-    return Lambda(f, fun);
-}
-
-JSObject * JS_FASTCALL
-stubs::LambdaJoinableForNull(VMFrame &f, JSFunction *fun)
-{
-    JS_ASSERT(fun->joinable());
-    return fun;
-}
-
-JSObject * JS_FASTCALL
 stubs::Lambda(VMFrame &f, JSFunction *fun)
 {
     JSObject *parent;
     if (fun->isNullClosure()) {
         parent = &f.fp()->scopeChain();
     } else {
         parent = GetScopeChain(f.cx, f.fp());
         if (!parent)
@@ -1136,38 +1073,31 @@ InitPropOrMethod(VMFrame &f, PropertyNam
 
     /* Load the object being initialized into lval/obj. */
     JSObject *obj = &regs.sp[-2].toObject();
     JS_ASSERT(obj->isNative());
 
     /* Get the immediate property name into id. */
     jsid id = ATOM_TO_JSID(name);
 
-    unsigned defineHow = (op == JSOP_INITMETHOD) ? DNP_SET_METHOD : 0;
     if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
-        ? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, false)
+        ? !js_SetPropertyHelper(cx, obj, id, 0, &rval, false)
         : !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
-                                JSPROP_ENUMERATE, 0, 0, defineHow)) {
+                                JSPROP_ENUMERATE, 0, 0, 0)) {
         THROW();
     }
 }
 
 void JS_FASTCALL
 stubs::InitProp(VMFrame &f, PropertyName *name)
 {
     InitPropOrMethod(f, name, JSOP_INITPROP);
 }
 
 void JS_FASTCALL
-stubs::InitMethod(VMFrame &f, PropertyName *name)
-{
-    InitPropOrMethod(f, name, JSOP_INITMETHOD);
-}
-
-void JS_FASTCALL
 stubs::IterNext(VMFrame &f, int32_t offset)
 {
     JS_ASSERT(f.regs.sp - offset >= f.fp()->base());
     JS_ASSERT(f.regs.sp[-offset].isObject());
 
     JSObject *iterobj = &f.regs.sp[-offset].toObject();
     f.regs.sp[0].setNull();
     f.regs.sp++;
--- a/js/src/methodjit/StubCalls.h
+++ b/js/src/methodjit/StubCalls.h
@@ -57,17 +57,16 @@ void JS_FASTCALL This(VMFrame &f);
 void JS_FASTCALL NewInitArray(VMFrame &f, uint32_t count);
 void JS_FASTCALL NewInitObject(VMFrame &f, JSObject *base);
 void JS_FASTCALL Trap(VMFrame &f, uint32_t trapTypes);
 void JS_FASTCALL DebuggerStatement(VMFrame &f, jsbytecode *pc);
 void JS_FASTCALL Interrupt(VMFrame &f, jsbytecode *pc);
 void JS_FASTCALL RecompileForInline(VMFrame &f);
 void JS_FASTCALL InitElem(VMFrame &f, uint32_t last);
 void JS_FASTCALL InitProp(VMFrame &f, PropertyName *name);
-void JS_FASTCALL InitMethod(VMFrame &f, PropertyName *name);
 
 void JS_FASTCALL HitStackQuota(VMFrame &f);
 void * JS_FASTCALL FixupArity(VMFrame &f, uint32_t argc);
 void * JS_FASTCALL CompileFunction(VMFrame &f, uint32_t argc);
 void JS_FASTCALL SlowNew(VMFrame &f, uint32_t argc);
 void JS_FASTCALL SlowCall(VMFrame &f, uint32_t argc);
 void * JS_FASTCALL UncachedNew(VMFrame &f, uint32_t argc);
 void * JS_FASTCALL UncachedCall(VMFrame &f, uint32_t argc);
@@ -132,20 +131,16 @@ template <JSBool strict> void JS_FASTCAL
 void JS_FASTCALL DelName(VMFrame &f, PropertyName *name);
 JSBool JS_FASTCALL In(VMFrame &f);
 
 void JS_FASTCALL DefVarOrConst(VMFrame &f, PropertyName *name);
 void JS_FASTCALL SetConst(VMFrame &f, PropertyName *name);
 template<JSBool strict> void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
 void JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
 JSObject * JS_FASTCALL Lambda(VMFrame &f, JSFunction *fun);
-JSObject * JS_FASTCALL LambdaJoinableForInit(VMFrame &f, JSFunction *fun);
-JSObject * JS_FASTCALL LambdaJoinableForSet(VMFrame &f, JSFunction *fun);
-JSObject * JS_FASTCALL LambdaJoinableForCall(VMFrame &f, JSFunction *fun);
-JSObject * JS_FASTCALL LambdaJoinableForNull(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL FlatLambda(VMFrame &f, JSFunction *fun);
 void JS_FASTCALL Arguments(VMFrame &f);
 void JS_FASTCALL EnterBlock(VMFrame &f, JSObject *obj);
 void JS_FASTCALL LeaveBlock(VMFrame &f);
 
 JSBool JS_FASTCALL LessThan(VMFrame &f);
 JSBool JS_FASTCALL LessEqual(VMFrame &f);
 JSBool JS_FASTCALL GreaterThan(VMFrame &f);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2165,18 +2165,17 @@ DumpStack(JSContext *cx, unsigned argc, 
     JS_ASSERT(iter.nativeArgs().callee().toFunction()->native() == DumpStack);
     ++iter;
 
     uint32_t index = 0;
     for (; !iter.done(); ++index, ++iter) {
         Value v;
         if (iter.isScript()) {
             if (iter.fp()->isNonEvalFunctionFrame()) {
-                if (!iter.fp()->getValidCalleeObject(cx, &v))
-                    return false;
+                v = ObjectValue(iter.fp()->callee());
             } else if (iter.fp()->isEvalFrame()) {
                 v = StringValue(evalStr);
             } else {
                 v = StringValue(globalStr);
             }
         } else {
             v = iter.nativeArgs().calleev();
         }
@@ -2777,21 +2776,17 @@ CopyProperty(JSContext *cx, JSObject *ob
     *objp = NULL;
     if (referent->isNative()) {
         if (!LookupPropertyWithFlags(cx, referent, id, lookupFlags, &obj2, &prop))
             return false;
         if (obj2 != referent)
             return true;
 
         const Shape *shape = (Shape *) prop;
-        if (shape->isMethod()) {
-            shape = referent->methodReadBarrier(cx, *shape, &desc.value);
-            if (!shape)
-                return false;
-        } else if (shape->hasSlot()) {
+        if (shape->hasSlot()) {
             desc.value = referent->nativeGetSlot(shape->slot());
         } else {
             desc.value.setUndefined();
         }
 
         desc.attrs = shape->attributes();
         desc.getter = shape->getter();
         if (!desc.getter && !(desc.attrs & JSPROP_GETTER))
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -920,17 +920,17 @@ Debugger::parseResumptionValue(AutoCompa
 bool
 CallMethodIfPresent(JSContext *cx, JSObject *obj, const char *name, int argc, Value *argv,
                     Value *rval)
 {
     rval->setUndefined();
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     Value fval;
     return atom &&
-           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, &fval) &&
+           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &fval) &&
            (!js_IsCallable(fval) ||
             Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
 }
 
 JSTrapStatus
 Debugger::fireDebuggerStatement(JSContext *cx, Value *vp)
 {
     JSObject *hook = getHook(OnDebuggerStatement);
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -184,23 +184,16 @@ StackFrame::initFixupFrame(StackFrame *p
                          UNDERFLOW_ARGS)) == 0);
 
     flags_ = FUNCTION | flags;
     prev_ = prev;
     ncode_ = ncode;
     u.nactual = nactual;
 }
 
-inline void
-StackFrame::overwriteCallee(JSObject &newCallee)
-{
-    JS_ASSERT(callee().toFunction()->script() == newCallee.toFunction()->script());
-    mutableCalleev().setObject(newCallee);
-}
-
 inline Value &
 StackFrame::canonicalActualArg(unsigned i) const
 {
     if (i < numFormalArgs())
         return formalArg(i);
     JS_ASSERT(i < numActualArgs());
     return actualArgs()[i];
 }
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -813,37 +813,23 @@ class StackFrame
         JS_ASSERT(isScriptFrame());
         Value &calleev = flags_ & (EVAL | GLOBAL)
                          ? ((Value *)this)[-2]
                          : formalArgs()[-2];
         JS_ASSERT(calleev.isObjectOrNull());
         return calleev;
     }
 
-    /*
-     * Beware! Ad hoc changes can corrupt the stack layout; the callee should
-     * only be changed to something that is equivalent to the current callee in
-     * terms of numFormalArgs etc. Prefer overwriteCallee since it checks.
-     */
-    inline void overwriteCallee(JSObject &newCallee);
-
     Value &mutableCalleev() const {
         JS_ASSERT(isFunctionFrame());
         if (isEvalFrame())
             return ((Value *)this)[-2];
         return formalArgs()[-2];
     }
 
-    /*
-     * Compute the callee function for this stack frame, cloning if needed to
-     * implement the method read barrier.  If this is not a function frame,
-     * set *vp to null.
-     */
-    bool getValidCalleeObject(JSContext *cx, Value *vp);
-
     CallReceiver callReceiver() const {
         return CallReceiverFromArgv(formalArgs());
     }
 
     /*
      * Scope chain
      *
      * Every frame has a scopeChain which, when traversed via the 'parent' link