Bug 488967 - TM: Add global size check to global shape check, r=gal.
authorGraydon Hoare <graydon@mozilla.com>
Thu, 23 Apr 2009 20:46:40 -0700
changeset 27889 789dd9844f6f3d034744f2aecaa5225f9a3dce24
parent 27888 8466bcdbd346ed26d220d94d751ea0420770ffb4
child 27890 b404007efd79740662215f7ac3a27bc9bd6d19bc
push id6760
push userrsayre@mozilla.com
push dateWed, 29 Apr 2009 01:51:23 +0000
treeherdermozilla-central@f5a2dfe49558 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs488967
milestone1.9.2a1pre
Bug 488967 - TM: Add global size check to global shape check, r=gal.
js/src/jstracer.cpp
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -122,16 +122,19 @@ static const char tagChar[]  = "OIDISIBI
 #define MAX_CALLDEPTH 10
 
 /* Max native stack size. */
 #define MAX_NATIVE_STACK_SLOTS 1024
 
 /* Max call stack size. */
 #define MAX_CALL_STACK_ENTRIES 64
 
+/* Max global object size. */
+#define MAX_GLOBAL_SLOTS 4096
+
 /* Max memory you can allocate in a LIR buffer via a single skip() call. */
 #define MAX_SKIP_BYTES (NJ_PAGE_SIZE - LIR_FAR_SLOTS)
 
 /* Max memory needed to rebuild the interpreter stack when falling off trace. */
 #define MAX_INTERP_STACK_BYTES                                                \
     (MAX_NATIVE_STACK_SLOTS * sizeof(jsval) +                                 \
      MAX_CALL_STACK_ENTRIES * sizeof(JSInlineFrame))
 
@@ -1957,17 +1960,17 @@ JS_REQUIRES_STACK bool
 TraceRecorder::lazilyImportGlobalSlot(unsigned slot)
 {
     if (slot != uint16(slot)) /* we use a table of 16-bit ints, bail out if that's not enough */
         return false;
     /*
      * If the global object grows too large, alloca in js_ExecuteTree might fail, so
      * abort tracing on global objects with unreasonably many slots.
      */
-    if (globalObj->dslots[-1] > 4096)
+    if (STOBJ_NSLOTS(globalObj) > MAX_GLOBAL_SLOTS)
         return false;
     jsval* vp = &STOBJ_GET_SLOT(globalObj, slot);
     if (known(vp))
         return true; /* we already have it */
     unsigned index = treeInfo->globalSlots->length();
     /* Add the slot to the list of interned global slots. */
     JS_ASSERT(treeInfo->nGlobalTypes() == treeInfo->globalSlots->length());
     treeInfo->globalSlots->add(slot);
@@ -3225,16 +3228,19 @@ static JS_REQUIRES_STACK bool
 CheckGlobalObjectShape(JSContext* cx, JSTraceMonitor* tm, JSObject* globalObj,
                        uint32 *shape=NULL, SlotList** slots=NULL)
 {
     if (tm->needFlush) {
         FlushJITCache(cx);
         return false;
     }
 
+    if (STOBJ_NSLOTS(globalObj) > MAX_GLOBAL_SLOTS)
+        return false;
+
     uint32 globalShape = OBJ_SHAPE(globalObj);
 
     if (tm->recorder) {
         VMFragment* root = (VMFragment*)tm->recorder->getFragment()->root;
         TreeInfo* ti = tm->recorder->getTreeInfo();
         /* Check the global shape matches the recorder's treeinfo's shape. */
         if (globalObj != root->globalObj || globalShape != root->globalShape) {
             AUDIT(globalShapeMismatchAtEntry);
@@ -4146,16 +4152,17 @@ js_ExecuteTree(JSContext* cx, Fragment* 
     state->stackMark = JS_ARENA_MARK(&cx->stackPool);
     JS_ARENA_ALLOCATE(reserve, &cx->stackPool, MAX_INTERP_STACK_BYTES);
     if (!reserve)
         return NULL;
 
 #ifdef DEBUG
     memset(stack_buffer, 0xCD, sizeof(stack_buffer));
     memset(global, 0xCD, (globalFrameSize+1)*sizeof(double));
+    JS_ASSERT(globalFrameSize <= MAX_GLOBAL_SLOTS);
 #endif
 
     debug_only(*(uint64*)&global[globalFrameSize] = 0xdeadbeefdeadbeefLL;)
     debug_only_v(printf("entering trace at %s:%u@%u, native stack slots: %u code: %p\n",
                         cx->fp->script->filename,
                         js_FramePCToLineNumber(cx, cx->fp),
                         FramePCOffset(cx->fp),
                         ti->maxNativeStackSlots,