From 49fe1b383b13debe8834918ee73bfe5606a2102a Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Mon, 8 Apr 2002 08:15:23 +0000 Subject: [PATCH] In NativeObject.toSource and NativeArray.toStringHelper methods set cx.iterating to null when done to prevent Hashtable with potentially ever growing internal buffers to lay around. Use ObjToIntMap instead of Hashtable for cx.iterating, it servers the same purpose as using JDK 1.2 HashSet, but without breaking 1.1 compatibility. git-svn-id: svn://10.0.0.236/trunk@118466 18797224-902f-48f8-a5cc-f745e15eee43 --- .../src/org/mozilla/javascript/Context.java | 3 +- .../org/mozilla/javascript/NativeArray.java | 69 +++++++++-------- .../org/mozilla/javascript/NativeObject.java | 75 ++++++++++--------- 3 files changed, 78 insertions(+), 69 deletions(-) diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java index 4808b553280..da8a9181c04 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java @@ -2187,7 +2187,8 @@ public class Context { // for Objects, Arrays to tag themselves as being printed out, // so they don't print themselves out recursively. - Hashtable iterating; + // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility + ObjToIntMap iterating; Object interpreterSecurityDomain; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java index 2c15ece845f..d7a18b9f55d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java @@ -461,11 +461,7 @@ public class NativeArray extends IdScriptable { long length = (long)getLengthProperty(thisObj); - StringBuffer result = new StringBuffer(); - - if (cx.iterating == null) - cx.iterating = new Hashtable(31); - boolean iterating = cx.iterating.get(thisObj) == Boolean.TRUE; + StringBuffer result = new StringBuffer(256); // whether to return '4,unquoted,5' or '[4, "quoted", 5]' String separator; @@ -480,33 +476,40 @@ public class NativeArray extends IdScriptable { boolean haslast = false; long i = 0; - if (!iterating) { - for (i = 0; i < length; i++) { - if (i > 0) result.append(separator); - Object elem = getElem(thisObj, i); - if (elem == null || elem == Undefined.instance) { - haslast = false; - continue; - } - haslast = true; + boolean toplevel, iterating; + if (cx.iterating == null) { + toplevel = true; + iterating = false; + cx.iterating = new ObjToIntMap(31); + }else { + toplevel = false; + iterating = cx.iterating.has(thisObj); + } - if (elem instanceof String) { - String s = (String)elem; - if (toSource) { - result.append('\"'); - result.append(ScriptRuntime.escapeString(s)); - result.append('\"'); - } else { - result.append(s); + // Make sure cx.iterating is set to null when done + // so we don't leak memory + try { + if (!iterating) { + cx.iterating.put(thisObj, 0); // stop recursion. + for (i = 0; i < length; i++) { + if (i > 0) result.append(separator); + Object elem = getElem(thisObj, i); + if (elem == null || elem == Undefined.instance) { + haslast = false; + continue; } - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. */ - try { - // stop recursion. - cx.iterating.put(thisObj, Boolean.TRUE); + haslast = true; + + if (elem instanceof String) { + String s = (String)elem; + if (toSource) { + result.append('\"'); + result.append(ScriptRuntime.escapeString(s)); + result.append('\"'); + } else { + result.append(s); + } + } else { if (toLocale && elem != Undefined.instance && elem != null) { @@ -518,11 +521,13 @@ public class NativeArray extends IdScriptable { ScriptRuntime.emptyArgs); } result.append(ScriptRuntime.toString(elem)); - } finally { - cx.iterating.remove(thisObj); } } } + }finally { + if (toplevel) { + cx.iterating = null; + } } if (toSource) { diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java index 42c8f394b09..0d1b769b85d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java @@ -142,48 +142,51 @@ public class NativeObject extends IdScriptable { private static String toSource(Context cx, Scriptable thisObj) { - Scriptable m = thisObj; + StringBuffer result = new StringBuffer(256); + result.append('{'); - if (cx.iterating == null) - cx.iterating = new Hashtable(31); + boolean toplevel, iterating; + if (cx.iterating == null) { + toplevel = true; + iterating = false; + cx.iterating = new ObjToIntMap(31); + }else { + toplevel = false; + iterating = cx.iterating.has(thisObj); + } - if (cx.iterating.get(m) == Boolean.TRUE) { - return "{}"; // stop recursion - } else { - StringBuffer result = new StringBuffer("{"); - Object[] ids = m.getIds(); - - for(int i=0; i < ids.length; i++) { - if (i > 0) - result.append(", "); - - Object id = ids[i]; - String idString = ScriptRuntime.toString(id); - Object p = (id instanceof String) - ? m.get((String) id, m) - : m.get(((Number) id).intValue(), m); - if (p instanceof String) { - result.append(idString + ":\"" - + ScriptRuntime - .escapeString(ScriptRuntime.toString(p)) - + "\""); - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. - */ - try { - cx.iterating.put(m, Boolean.TRUE); // stop recursion. - result.append(idString + ":" + ScriptRuntime.toString(p)); - } finally { - cx.iterating.remove(m); + // Make sure cx.iterating is set to null when done + // so we don't leak memory + try { + if (!iterating) { + cx.iterating.put(thisObj, 0); // stop recursion. + Object[] ids = thisObj.getIds(); + for(int i=0; i < ids.length; i++) { + if (i > 0) + result.append(", "); + Object id = ids[i]; + result.append(id); + result.append(':'); + Object p = (id instanceof String) + ? thisObj.get((String) id, thisObj) + : thisObj.get(((Integer) id).intValue(), thisObj); + if (p instanceof String) { + result.append('\"'); + result.append(ScriptRuntime.escapeString((String)p)); + result.append('\"'); + }else { + result.append(ScriptRuntime.toString(p)); } } } - result.append('}'); - return result.toString(); + }finally { + if (toplevel) { + cx.iterating = null; + } } + + result.append('}'); + return result.toString(); } private static Object jsFunction_valueOf(Scriptable thisObj) {