Back out patch for bug 469625, it mysterious busts stuff.
authorBrendan Eich <brendan@mozilla.org>
Fri, 19 Dec 2008 01:32:48 -0800
changeset 23100 5af9839712f7f6d2be011763ce4a0370c1f7b5f5
parent 23099 b8d8494faf18f57473b1b28d9c46964c63827343
child 23101 229681f85e7aef406b41c6529a59addd969ff310
push id4346
push userrsayre@mozilla.com
push dateFri, 26 Dec 2008 01:26:36 +0000
treeherdermozilla-central@8eb5a5b83a93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs469625
milestone1.9.2a1pre
Back out patch for bug 469625, it mysterious busts stuff.
js/src/jsarray.cpp
js/src/jsemit.cpp
js/src/jsobj.cpp
js/src/jsopcode.tbl
js/src/jstracer.cpp
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -826,16 +826,18 @@ array_defineProperty(JSContext *cx, JSOb
 
     if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
         return JS_TRUE;
 
     isIndex = js_IdIsIndex(ID_TO_VALUE(id), &i);
     if (!isIndex || attrs != JSPROP_ENUMERATE) {
         if (!ENSURE_SLOW_ARRAY(cx, obj))
             return JS_FALSE;
+        if (isIndex && STOBJ_IS_DELEGATE(obj))
+            cx->runtime->anyArrayProtoHasElement = JS_TRUE;
         return js_DefineProperty(cx, obj, id, value, getter, setter, attrs, propp);
     }
 
     return array_setProperty(cx, obj, id, &value);
 }
 
 static JSBool
 array_getAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -1700,16 +1700,17 @@ EmitIndexOp(JSContext *cx, JSOp op, uint
  * caller's lexical environment, and embedding a false return on error.
  */
 #define EMIT_INDEX_OP(op, index)                                              \
     JS_BEGIN_MACRO                                                            \
         if (!EmitIndexOp(cx, op, index, cg))                                  \
             return JS_FALSE;                                                  \
     JS_END_MACRO
 
+
 static JSBool
 EmitAtomOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
 {
     JSAtomListElement *ale;
 
     JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
     if (op == JSOP_GETPROP &&
         pn->pn_atom == cx->runtime->atomState.lengthAtom) {
@@ -2327,34 +2328,22 @@ EmitXMLName(JSContext *cx, JSParseNode *
         return JS_FALSE;
     }
 
     return js_Emit1(cx, cg, op) >= 0;
 }
 #endif
 
 static JSBool
-EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg);
-
-static JSBool
 EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg,
            JSBool callContext)
 {
     JSParseNode *pn2, *pndot, *pnup, *pndown;
     ptrdiff_t top;
 
-    /*
-     * Special case obj.__proto__ to deoptimize away from fast paths in the
-     * interpreter and trace recorder, which skip dense array instances by
-     * skipping over the directly referenced object to Array.prototype before
-     * looking up the property name. See bug 450274.
-     */
-    if (pn->pn_atom == cx->runtime->atomState.protoAtom)
-        return EmitElemOp(cx, pn, callContext ? JSOP_CALLELEM : JSOP_GETELEM, cg);
-
     pn2 = pn->pn_expr;
     if (callContext) {
         JS_ASSERT(pn->pn_type == TOK_DOT);
         JS_ASSERT(op == JSOP_GETPROP);
         op = JSOP_CALLPROP;
     } else if (op == JSOP_GETPROP && pn->pn_type == TOK_DOT) {
         if (pn2->pn_op == JSOP_THIS) {
             if (pn->pn_atom != cx->runtime->atomState.lengthAtom) {
@@ -5335,21 +5324,16 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
                 EMIT_INDEX_OP(JSOP_GETXPROP, atomIndex);
                 break;
               case TOK_DOT:
                 if (js_Emit1(cx, cg, JSOP_DUP) < 0)
                     return JS_FALSE;
                 if (pn2->pn_atom == cx->runtime->atomState.lengthAtom) {
                     if (js_Emit1(cx, cg, JSOP_LENGTH) < 0)
                         return JS_FALSE;
-                } else if (pn2->pn_atom == cx->runtime->atomState.protoAtom) {
-                    if (!EmitIndexOp(cx, JSOP_QNAMEPART, atomIndex, cg))
-                        return JS_FALSE;
-                    if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
-                        return JS_FALSE;
                 } else {
                     EMIT_INDEX_OP(JSOP_GETPROP, atomIndex);
                 }
                 break;
               case TOK_LB:
 #if JS_HAS_LVALUE_RETURN
               case TOK_LP:
 #endif
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -321,30 +321,20 @@ js_SetProtoOrParent(JSContext *cx, JSObj
                                  (slot == JSSLOT_PROTO) ? js_proto_str
                                                         : js_parent_str
 #endif
                                  );
         }
         return JS_FALSE;
     }
 
-    /*
-     * Maintain the "any Array prototype has indexed properties hazard" flag by
-     * conservatively setting it. We simply don't know what pobj has in the way
-     * of indexed properties, either directly or along its prototype chain, and
-     * we won't expend effort here to find out. We do know that if obj is not
-     * an array or a prototype (delegate), then we're ok. And, of course, pobj
-     * must be non-null.
-     *
-     * This pessimistic approach could be improved, but setting __proto__ is
-     * quite rare and arguably deserving of deoptimization.
-     */
+    // Maintain the "any Array prototype has indexed properties hazard" flag.
     if (slot == JSSLOT_PROTO &&
-        pobj &&
-        (OBJ_IS_ARRAY(cx, obj) || OBJ_IS_DELEGATE(cx, obj))) {
+        OBJ_IS_ARRAY(cx, pobj) &&
+        pobj->fslots[JSSLOT_ARRAY_LENGTH] != 0) {
         rt->anyArrayProtoHasElement = JS_TRUE;
     }
     return JS_TRUE;
 }
 
 static JSHashNumber
 js_hash_object(const void *key)
 {
@@ -3190,34 +3180,29 @@ js_DefineProperty(JSContext *cx, JSObjec
                                    0, 0, propp);
 }
 
 /*
  * Backward compatibility requires allowing addProperty hooks to mutate the
  * nominal initial value of a slot-full property, while GC safety wants that
  * value to be stored before the call-out through the hook.  Optimize to do
  * both while saving cycles for classes that stub their addProperty hook.
- *
- * As in js_SetProtoOrParent (see above), we maintain the "any Array prototype
- * has indexed properties hazard" flag by conservatively setting it.
  */
 #define ADD_PROPERTY_HELPER(cx,clasp,obj,scope,sprop,vp,cleanup)              \
     JS_BEGIN_MACRO                                                            \
         if ((clasp)->addProperty != JS_PropertyStub) {                        \
             jsval nominal_ = *(vp);                                           \
             if (!(clasp)->addProperty(cx, obj, SPROP_USERID(sprop), vp)) {    \
                 cleanup;                                                      \
             }                                                                 \
             if (*(vp) != nominal_) {                                          \
                 if (SPROP_HAS_VALID_SLOT(sprop, scope))                       \
                     LOCKED_OBJ_WRITE_BARRIER(cx, obj, (sprop)->slot, *(vp));  \
             }                                                                 \
         }                                                                     \
-        if (STOBJ_IS_DELEGATE(obj) && JSID_IS_INT(sprop->id))                 \
-            cx->runtime->anyArrayProtoHasElement = JS_TRUE;                   \
     JS_END_MACRO
 
 JSBool
 js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
                         JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
                         uintN flags, intN shortid, JSProperty **propp)
 {
     JSClass *clasp;
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -536,17 +536,16 @@ OPDEF(JSOP_UNUSED219,     219,"unused219
  */
 OPDEF(JSOP_INDEXBASE1,    220,"atombase1",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
 OPDEF(JSOP_INDEXBASE2,    221,"atombase2",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
 OPDEF(JSOP_INDEXBASE3,    222,"atombase3",     NULL,  1,  0,  0,  0,  JOF_BYTE |JOF_INDEXBASE)
 
 OPDEF(JSOP_CALLGVAR,      223, "callgvar",     NULL,  3,  0,  2, 19,  JOF_ATOM|JOF_NAME|JOF_CALLOP)
 OPDEF(JSOP_CALLLOCAL,     224, "calllocal",    NULL,  3,  0,  2, 19,  JOF_LOCAL|JOF_NAME|JOF_CALLOP)
 OPDEF(JSOP_CALLARG,       225, "callarg",      NULL,  3,  0,  2, 19,  JOF_QARG |JOF_NAME|JOF_CALLOP)
-
 OPDEF(JSOP_UNUSED226,     226, "unused226",    NULL,  1,  0,  1,  1,  JOF_BYTE)
 
 /*
  * Opcodes to hold 8-bit and 32-bit immediate integer operands.
  */
 OPDEF(JSOP_INT8,          227, "int8",         NULL,  2,  0,  1, 16,  JOF_INT8)
 OPDEF(JSOP_INT32,         228, "int32",        NULL,  5,  0,  1, 16,  JOF_INT32)
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -7758,16 +7758,17 @@ JS_REQUIRES_STACK bool
 TraceRecorder::record_JSOP_GOTOX()
 {
     return true;
 }
 
 JS_REQUIRES_STACK bool
 TraceRecorder::record_JSOP_IFEQX()
 {
+    trackCfgMerges(cx->fp->regs->pc);
     return record_JSOP_IFEQ();
 }
 
 JS_REQUIRES_STACK bool
 TraceRecorder::record_JSOP_IFNEX()
 {
     return record_JSOP_IFNE();
 }
@@ -8451,17 +8452,17 @@ TraceRecorder::record_JSOP_INT32()
 }
 
 JS_REQUIRES_STACK bool
 TraceRecorder::record_JSOP_LENGTH()
 {
     jsval& l = stackval(-1);
     if (JSVAL_IS_PRIMITIVE(l)) {
         if (!JSVAL_IS_STRING(l))
-            ABORT_TRACE("non-string primitive JSOP_LENGTH unsupported");
+            ABORT_TRACE("non-string primitives unsupported");
         LIns* str_ins = get(&l);
         LIns* len_ins = lir->insLoad(LIR_ldp, str_ins, (int)offsetof(JSString, length));
 
         LIns* masked_len_ins = lir->ins2(LIR_piand,
                                          len_ins,
                                          INS_CONSTPTR(JSSTRING_LENGTH_MASK));
 
         LIns *choose_len_ins =