Bug 440473 - Crash [@ Decompile][@ js_GetSrcNoteOffset] with firebug/jQuery, r=igor
authorbcrowder@mozilla.com
Wed, 25 Jun 2008 13:50:26 -0700
changeset 15530 4aeb5932fc5ac4deab932926fb50fa22f58681f3
parent 15529 ec02b60c2a0b19f021ab1e67facefcea436b3ba4
child 15531 1bbd2daaabb6c0204d2db369aaf87f2e77201583
push id290
push userbcrowder@mozilla.com
push dateWed, 25 Jun 2008 20:55:16 +0000
treeherdermozilla-central@1bbd2daaabb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersigor
bugs440473
milestone1.9.1a1pre
Bug 440473 - Crash [@ Decompile][@ js_GetSrcNoteOffset] with firebug/jQuery, r=igor
js/src/jscntxt.h
js/src/jsscript.cpp
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -56,35 +56,37 @@
 #include "jspubtd.h"
 #include "jsregexp.h"
 #include "jsutil.h"
 
 JS_BEGIN_EXTERN_C
 
 /*
  * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
- * given pc in a script.
+ * given pc in a script.  We use the script->code pointer to tag the cache,
+ * instead of the script address itself, so that source notes are always found
+ * by offset from the bytecode with which they were generated.
  */
 typedef struct JSGSNCache {
-    JSScript        *script;
+    jsbytecode      *code;
     JSDHashTable    table;
 #ifdef JS_GSNMETER
     uint32          hits;
     uint32          misses;
     uint32          fills;
     uint32          clears;
 # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt)
 #else
 # define GSN_CACHE_METER(cache,cnt) /* nothing */
 #endif
 } JSGSNCache;
 
 #define GSN_CACHE_CLEAR(cache)                                                \
     JS_BEGIN_MACRO                                                            \
-        (cache)->script = NULL;                                               \
+        (cache)->code = NULL;                                                 \
         if ((cache)->table.ops) {                                             \
             JS_DHashTableFinish(&(cache)->table);                             \
             (cache)->table.ops = NULL;                                        \
         }                                                                     \
         GSN_CACHE_METER(cache, clears);                                       \
     JS_END_MACRO
 
 /* These helper macros take a cx as parameter and operate on its GSN cache. */
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1527,17 +1527,17 @@ void
 js_DestroyScript(JSContext *cx, JSScript *script)
 {
     js_CallDestroyScriptHook(cx, script);
     JS_ClearScriptTraps(cx, script);
 
     if (script->principals)
         JSPRINCIPALS_DROP(cx, script->principals);
 
-    if (JS_GSN_CACHE(cx).script == script)
+    if (JS_GSN_CACHE(cx).code == script->code)
         JS_CLEAR_GSN_CACHE(cx);
 
     /*
      * The GC flushes all property caches, so no need to purge just the
      * entries for this script.
      *
      * JS_THREADSAFE note: js_FlushPropertyCacheForScript flushes only the
      * current thread's property cache, so a script not owned by a function
@@ -1633,17 +1633,17 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
     jssrcnote *sn, *result;
     uintN nsrcnotes;
 
 
     target = PTRDIFF(pc, script->code, jsbytecode);
     if ((uint32)target >= script->length)
         return NULL;
 
-    if (JS_GSN_CACHE(cx).script == script) {
+    if (JS_GSN_CACHE(cx).code == script->code) {
         JS_METER_GSN_CACHE(cx, hits);
         entry = (GSNCacheEntry *)
                 JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
                                      JS_DHASH_LOOKUP);
         return entry->sn;
     }
 
     JS_METER_GSN_CACHE(cx, misses);
@@ -1655,17 +1655,17 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
         }
         offset += SN_DELTA(sn);
         if (offset == target && SN_IS_GETTABLE(sn)) {
             result = sn;
             break;
         }
     }
 
-    if (JS_GSN_CACHE(cx).script != script &&
+    if (JS_GSN_CACHE(cx).code != script->code &&
         script->length >= GSN_CACHE_THRESHOLD) {
         JS_CLEAR_GSN_CACHE(cx);
         nsrcnotes = 0;
         for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
              sn = SN_NEXT(sn)) {
             if (SN_IS_GETTABLE(sn))
                 ++nsrcnotes;
         }
@@ -1681,17 +1681,17 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
                 if (SN_IS_GETTABLE(sn)) {
                     entry = (GSNCacheEntry *)
                             JS_DHashTableOperate(&JS_GSN_CACHE(cx).table, pc,
                                                  JS_DHASH_ADD);
                     entry->pc = pc;
                     entry->sn = sn;
                 }
             }
-            JS_GSN_CACHE(cx).script = script;
+            JS_GSN_CACHE(cx).code = script->code;
             JS_METER_GSN_CACHE(cx, fills);
         }
     }
 
     return result;
 }
 
 uintN