Bug 595975 diagnostic 2: shape markers and object data, r=billm, a=blocker
☠☠ backed out by 11a134784bd1 ☠ ☠
authorDavid Mandelin <dmandelin@mozilla.com>
Tue, 28 Dec 2010 14:50:01 -0800
changeset 59712 c35a4e6ea3ca5c86f98ceb89a6363240ebed3fdc
parent 59711 2a25c4d1ed991b232623523b4e08ce46bddaff7e
child 59713 aa25ead3690382f79c2ac86f250434b2ddf6a13a
child 59729 11a134784bd1c4a211601e3a43f87a5b57693b30
push id17751
push userdmandelin@mozilla.com
push dateTue, 28 Dec 2010 23:16:15 +0000
treeherdermozilla-central@c35a4e6ea3ca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, blocker
bugs595975
milestone2.0b9pre
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 595975 diagnostic 2: shape markers and object data, r=billm, a=blocker
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsscope.h
js/src/jsscopeinlines.h
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -101,17 +101,17 @@
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jsautooplen.h"
 
 using namespace js;
 using namespace js::gc;
 
-JS_FRIEND_DATA(const JSObjectMap) JSObjectMap::sharedNonNative(JSObjectMap::SHAPELESS);
+JS_FRIEND_DATA(const JSObjectMap) JSObjectMap::sharedNonNative(JSObjectMap::NON_NATIVE_START_MARKER, JSObjectMap::SHAPELESS, 0);
 
 Class js_ObjectClass = {
     js_Object_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
     PropertyStub,   /* addProperty */
     PropertyStub,   /* delProperty */
     PropertyStub,   /* getProperty */
     PropertyStub,   /* setProperty */
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -171,25 +171,31 @@ struct PropDesc {
 
 namespace js {
 
 typedef Vector<PropDesc, 1> PropDescArray;
 
 } /* namespace js */
 
 struct JSObjectMap {
+    uint32 startMarker; /* start marker for diagnostics */
     uint32 shape;       /* shape identifier */
     uint32 slotSpan;    /* one more than maximum live slot number */
 
     static JS_FRIEND_DATA(const JSObjectMap) sharedNonNative;
 
-    explicit JSObjectMap(uint32 shape) : shape(shape), slotSpan(0) {}
-    JSObjectMap(uint32 shape, uint32 slotSpan) : shape(shape), slotSpan(slotSpan) {}
+    JSObjectMap(uint32 startMarker, uint32 shape, uint32 slotSpan)
+        : startMarker(startMarker), shape(shape), slotSpan(slotSpan) {}
 
     enum { INVALID_SHAPE = 0x8fffffff, SHAPELESS = 0xffffffff };
+    enum { NON_NATIVE_START_MARKER = 0xeaeaeaea,
+           SHAPE_START_MARKER      = 0xebebebeb,
+           SHAPE_MARKER_1          = 0xecececec,
+           SHAPE_MARKER_2          = 0xedededed,
+           SHAPE_END_MARKER        = 0xefefefef };
 
     bool isNative() const { return this != &sharedNonNative; }
 
   private:
     /* No copy or assignment semantics. */
     JSObjectMap(JSObjectMap &);
     void operator=(JSObjectMap &);
 };
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -287,16 +287,17 @@ CastAsPropertyOp(js::Class *clasp)
 
 struct Shape : public JSObjectMap
 {
     friend struct ::JSObject;
     friend struct ::JSFunction;
     friend class js::PropertyTree;
     friend bool HasUnreachableGCThings(TreeFragment *f);
 
+    uint32                    marker1;
   protected:
     mutable js::PropertyTable *table;
 
   public:
     inline void freeTable(JSContext *cx);
 
     static bool initRuntimeState(JSContext *cx);
     static void finishRuntimeState(JSContext *cx);
@@ -325,16 +326,17 @@ struct Shape : public JSObjectMap
 
     union {
         js::PropertyOp  rawSetter;      /* getter is JSObject* and setter is 0
                                            if shape->isMethod() */
         JSObject        *setterObj;     /* user-defined callable "set" object or
                                            null if shape->hasSetterValue() */
     };
 
+    uint32              marker2;
   public:
     uint32              slot;           /* abstract index in object slots */
   private:
     uint8               attrs;          /* attributes, see jsapi.h JSPROP_* */
     mutable uint8       flags;          /* flags, see below for defines */
   public:
     int16               shortid;        /* tinyid, or local arg/var index */
 
@@ -343,16 +345,17 @@ struct Shape : public JSObjectMap
     union {
         mutable js::KidsPointer kids;   /* null, single child, or a tagged ptr
                                            to many-kids data structure */
         mutable js::Shape **listp;      /* dictionary list starting at lastProp
                                            has a double-indirect back pointer,
                                            either to shape->parent if not last,
                                            else to obj->lastProp */
     };
+    uint32               endMarker;     /* end marker for diagnostics */
 
     static inline js::Shape **search(js::Shape **startp, jsid id, bool adding = false);
     static js::Shape *newDictionaryShape(JSContext *cx, const js::Shape &child, js::Shape **listp);
     static js::Shape *newDictionaryList(JSContext *cx, js::Shape **listp);
 
     inline void removeFromDictionary(JSObject *obj) const;
     inline void insertIntoDictionary(js::Shape **dictp);
 
@@ -642,19 +645,34 @@ struct EmptyShape : public js::Shape
 #define SHAPE_FETCH(spp)                SHAPE_CLEAR_COLLISION(*(spp))
 
 #define SHAPE_CLEAR_COLLISION(shape)                                          \
     ((js::Shape *) (jsuword(shape) & ~SHAPE_COLLISION))
 
 #define SHAPE_STORE_PRESERVING_COLLISION(spp, shape)                          \
     (*(spp) = (js::Shape *) (jsuword(shape) | SHAPE_HAD_COLLISION(*(spp))))
 
+inline static volatile int *vcopy(volatile int *dst, int *src, size_t bytes)
+{
+    int *end = src + bytes / sizeof(int);
+    for (; src < end; ++src, ++dst)
+        *dst = *src;
+    return dst;
+}
+
 inline js::Shape **
 JSObject::nativeSearch(jsid id, bool adding)
 {
+    {
+        char blackbox[sizeof(JSObject) + 8];
+        volatile int *p = (int *) blackbox;
+        *p++ = 0xacacacac;
+        p = vcopy(p, (int *) this, sizeof(JSObject));
+        *p = 0xadadadad;
+    }
     return js::Shape::search(&lastProp, id, adding);
 }
 
 inline const js::Shape *
 JSObject::nativeLookup(jsid id)
 {
     JS_ASSERT(isNative());
     return SHAPE_FETCH(nativeSearch(id));
@@ -824,24 +842,16 @@ extern JS_FRIEND_DATA(JSScopeStats) js_s
 
 # define METER(x)       JS_ATOMIC_INCREMENT(&js_scope_stats.x)
 #else
 # define METER(x)       /* nothing */
 #endif
 
 namespace js {
 
-inline static volatile int *vcopy(volatile int *dst, int *src, size_t bytes)
-{
-    int *end = src + bytes / sizeof(int);
-    for (; src < end; ++src, ++dst)
-        *dst = *src;
-    return dst;
-}
-
 JS_ALWAYS_INLINE js::Shape **
 Shape::search(js::Shape **startp, jsid id, bool adding)
 {
     METER(searches);
     if (!(*startp)->table) {
         /*
          * Not enough properties to justify hashing: search from *startp.
          *
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -164,31 +164,35 @@ JSObject::trace(JSTracer *trc)
     } while ((shape = shape->parent) != NULL);
 }
 
 namespace js {
 
 inline
 Shape::Shape(jsid id, js::PropertyOp getter, js::PropertyOp setter, uint32 slot, uintN attrs,
              uintN flags, intN shortid, uint32 shape, uint32 slotSpan)
-  : JSObjectMap(shape, slotSpan),
+  : JSObjectMap(JSObjectMap::SHAPE_START_MARKER, shape, slotSpan),
     table(NULL), id(id), rawGetter(getter), rawSetter(setter), slot(slot), attrs(uint8(attrs)),
-    flags(uint8(flags)), shortid(int16(shortid)), parent(NULL)
+    flags(uint8(flags)), shortid(int16(shortid)), parent(NULL),
+    marker1(JSObjectMap::SHAPE_MARKER_1), marker2(JSObjectMap::SHAPE_MARKER_2),
+    endMarker(JSObjectMap::SHAPE_END_MARKER)
 {
     JS_ASSERT_IF(slotSpan != SHAPE_INVALID_SLOT, slotSpan < JSObject::NSLOTS_LIMIT);
     JS_ASSERT_IF(getter && (attrs & JSPROP_GETTER), getterObj->isCallable());
     JS_ASSERT_IF(setter && (attrs & JSPROP_SETTER), setterObj->isCallable());
     kids.setNull();
 }
 
 inline
 Shape::Shape(JSContext *cx, Class *aclasp)
-  : JSObjectMap(js_GenerateShape(cx, false), JSSLOT_FREE(aclasp)), table(NULL),
+  : JSObjectMap(JSObjectMap::SHAPE_START_MARKER, js_GenerateShape(cx, false), JSSLOT_FREE(aclasp)), table(NULL),
     id(JSID_EMPTY), clasp(aclasp), rawSetter(NULL), slot(SHAPE_INVALID_SLOT), attrs(0),
-    flags(SHARED_EMPTY), shortid(0), parent(NULL)
+    flags(SHARED_EMPTY), shortid(0), parent(NULL),
+    marker1(JSObjectMap::SHAPE_MARKER_1), marker2(JSObjectMap::SHAPE_MARKER_2),
+    endMarker(JSObjectMap::SHAPE_END_MARKER)
 {
     kids.setNull();
 }
 
 inline JSDHashNumber
 Shape::hash() const
 {
     JSDHashNumber hash = 0;