Backed out changeset 7246c4dcf997 (bug 469625) due to trace-test.js failures.
authorshaver@mozilla.org
Wed, 28 Jan 2009 22:26:46 -0500
changeset 24488 6a6d6d76ebc8fad447f77cf8d537dea380361855
parent 24487 7246c4dcf99709f0fe1e0aefbf812e701f1961ad
child 24489 76a7344912ae6279e994f6b22fa69c7b67d998cd
push id5074
push userrsayre@mozilla.com
push dateSat, 31 Jan 2009 19:45:42 +0000
treeherdermozilla-central@f1cade532f6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs469625
milestone1.9.2a1pre
backs out7246c4dcf99709f0fe1e0aefbf812e701f1961ad
Backed out changeset 7246c4dcf997 (bug 469625) due to trace-test.js failures.
js/src/jsarray.cpp
js/src/jsemit.cpp
js/src/jsobj.cpp
js/src/jstracer.cpp
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -828,16 +828,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) {
@@ -2334,33 +2335,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 for obj.__proto__ to deoptimize away from fast paths in the
-     * interpreter and trace recorder, which skip dense array instances by going
-     * up to Array.prototype before looking up the property name.
-     */
-    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) {
@@ -5343,21 +5333,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)
 {
@@ -3393,34 +3383,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/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -8096,16 +8096,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();
 }
@@ -8882,17 +8883,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 =