2008-09-30  Darin Adler  <darin@apple.com>

        Reviewed by Eric Seidel.

        - https://bugs.webkit.org/show_bug.cgi?id=21214
          work on getting rid of ExecState

        Eliminate some unneeded uses of dynamicGlobalObject.

        * API/JSClassRef.cpp:
        (OpaqueJSClass::contextData): Changed to use a map in the global data instead
        of on the global object. Also fixed to use only a single hash table lookup.

        * API/JSObjectRef.cpp:
        (JSObjectMakeConstructor): Use lexicalGlobalObject rather than dynamicGlobalObject
        to get the object prototype.

        * kjs/ArrayPrototype.cpp:
        (JSC::arrayProtoFuncToString): Use arrayVisitedElements set in global data rather
        than in the global object.
        (JSC::arrayProtoFuncToLocaleString): Ditto.
        (JSC::arrayProtoFuncJoin): Ditto.

        * kjs/JSGlobalData.cpp:
        (JSC::JSGlobalData::JSGlobalData): Don't initialize opaqueJSClassData, since
        it's no longer a pointer.
        (JSC::JSGlobalData::~JSGlobalData): We still need to delete all the values, but
        we don't need to delete the map since it's no longer a pointer.

        * kjs/JSGlobalData.h: Made opaqueJSClassData a map instead of a pointer to a map.
        Also added arrayVisitedElements.

        * kjs/JSGlobalObject.h: Removed arrayVisitedElements.

        * kjs/Shell.cpp:
        (functionRun): Use lexicalGlobalObject instead of dynamicGlobalObject.
        (functionLoad): Ditto.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37175 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp
index c99666a..0bab2e2 100644
--- a/JavaScriptCore/API/JSClassRef.cpp
+++ b/JavaScriptCore/API/JSClassRef.cpp
@@ -185,11 +185,10 @@
 
 OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec)
 {
-    HashMap<OpaqueJSClass*, OpaqueJSClassContextData*>* contextDataMap = exec->globalData().opaqueJSClassData;
-    HashMap<OpaqueJSClass*, OpaqueJSClassContextData*>::iterator iter = contextDataMap->find(this);
-    if (iter != contextDataMap->end())
-        return *iter->second;
-    return *contextDataMap->add(this, new OpaqueJSClassContextData(this)).first->second;
+    OpaqueJSClassContextData*& contextData = exec->globalData().opaqueJSClassData.add(this, 0).first->second;
+    if (!contextData)
+        contextData = new OpaqueJSClassContextData(this);
+    return *contextData;
 }
 
 UString OpaqueJSClass::className()
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index 7ab329a..5c4c207 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -105,7 +105,7 @@
 
     JSValue* jsPrototype = jsClass 
         ? jsClass->prototype(exec)
-        : exec->dynamicGlobalObject()->objectPrototype();
+        : exec->lexicalGlobalObject()->objectPrototype();
     
     JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor);
     constructor->putDirect(exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 2f279ea..2d04464 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,41 @@
+2008-09-30  Darin Adler  <darin@apple.com>
+
+        Reviewed by Eric Seidel.
+
+        - https://bugs.webkit.org/show_bug.cgi?id=21214
+          work on getting rid of ExecState
+
+        Eliminate some unneeded uses of dynamicGlobalObject.
+
+        * API/JSClassRef.cpp:
+        (OpaqueJSClass::contextData): Changed to use a map in the global data instead
+        of on the global object. Also fixed to use only a single hash table lookup.
+
+        * API/JSObjectRef.cpp:
+        (JSObjectMakeConstructor): Use lexicalGlobalObject rather than dynamicGlobalObject
+        to get the object prototype.
+
+        * kjs/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncToString): Use arrayVisitedElements set in global data rather
+        than in the global object.
+        (JSC::arrayProtoFuncToLocaleString): Ditto.
+        (JSC::arrayProtoFuncJoin): Ditto.
+
+        * kjs/JSGlobalData.cpp:
+        (JSC::JSGlobalData::JSGlobalData): Don't initialize opaqueJSClassData, since
+        it's no longer a pointer.
+        (JSC::JSGlobalData::~JSGlobalData): We still need to delete all the values, but
+        we don't need to delete the map since it's no longer a pointer.
+
+        * kjs/JSGlobalData.h: Made opaqueJSClassData a map instead of a pointer to a map.
+        Also added arrayVisitedElements.
+
+        * kjs/JSGlobalObject.h: Removed arrayVisitedElements.
+
+        * kjs/Shell.cpp:
+        (functionRun): Use lexicalGlobalObject instead of dynamicGlobalObject.
+        (functionLoad): Ditto.
+
 2008-10-01  Cameron Zwarich  <zwarich@apple.com>
 
         Not reviewed.
@@ -70,7 +108,7 @@
 
 2008-10-01  Kevin McCullough  <kmccullough@apple.com>
 
-        Rubberstamped by Geoff .
+        Rubberstamped by Geoff Garen.
 
         Remove BreakpointCheckStatement because it's not used anymore.
         No effect on sunspider or the jsc tests.
diff --git a/JavaScriptCore/kjs/ArrayPrototype.cpp b/JavaScriptCore/kjs/ArrayPrototype.cpp
index 294e7b0..8dcfba2 100644
--- a/JavaScriptCore/kjs/ArrayPrototype.cpp
+++ b/JavaScriptCore/kjs/ArrayPrototype.cpp
@@ -125,15 +125,15 @@
         return throwError(exec, TypeError);
     JSObject* thisObj = static_cast<JSArray*>(thisValue);
 
-    HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     if (arrayVisitedElements.size() > MaxReentryDepth)
         return throwError(exec, RangeError, "Maximum call stack size exceeded.");
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
-    Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoiding infinite recursion.
 
+    Vector<UChar, 256> strBuffer;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
         if (k >= 1)
@@ -159,7 +159,7 @@
         if (exec->hadException())
             break;
     }
-    exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
+    arrayVisitedElements.remove(thisObj);
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
@@ -169,15 +169,15 @@
         return throwError(exec, TypeError);
     JSObject* thisObj = static_cast<JSArray*>(thisValue);
 
-    HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     if (arrayVisitedElements.size() > MaxReentryDepth)
         return throwError(exec, RangeError, "Maximum call stack size exceeded.");
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
-    Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
+    Vector<UChar, 256> strBuffer;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
         if (k >= 1)
@@ -211,7 +211,7 @@
         if (exec->hadException())
             break;
     }
-    exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
+    arrayVisitedElements.remove(thisObj);
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
@@ -219,15 +219,16 @@
 {
     JSObject* thisObj = thisValue->toThisObject(exec);
 
-    HashSet<JSObject*>& arrayVisitedElements = exec->dynamicGlobalObject()->arrayVisitedElements();
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     if (arrayVisitedElements.size() > MaxReentryDepth)
         return throwError(exec, RangeError, "Maximum call stack size exceeded.");
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
-    Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
+    Vector<UChar, 256> strBuffer;
+
     UChar comma = ',';
     UString separator = args.at(exec, 0)->isUndefined() ? UString(&comma, 1) : args.at(exec, 0)->toString(exec);
 
@@ -256,7 +257,7 @@
         if (exec->hadException())
             break;
     }
-    exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
+    arrayVisitedElements.remove(thisObj);
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
diff --git a/JavaScriptCore/kjs/JSGlobalData.cpp b/JavaScriptCore/kjs/JSGlobalData.cpp
index e75f394..a4d586c 100644
--- a/JavaScriptCore/kjs/JSGlobalData.cpp
+++ b/JavaScriptCore/kjs/JSGlobalData.cpp
@@ -82,7 +82,6 @@
     , identifierTable(createIdentifierTable())
     , propertyNames(new CommonIdentifiers(this))
     , emptyList(new ArgList)
-    , opaqueJSClassData(new HashMap<OpaqueJSClass*, OpaqueJSClassContextData*>)
     , newParserObjects(0)
     , parserObjectExtraRefCounts(0)
     , lexer(new Lexer(this))
@@ -122,8 +121,7 @@
     delete parser;
     delete lexer;
 
-    deleteAllValues(*opaqueJSClassData);
-    delete opaqueJSClassData;
+    deleteAllValues(opaqueJSClassData);
 
     delete emptyList;
 
diff --git a/JavaScriptCore/kjs/JSGlobalData.h b/JavaScriptCore/kjs/JSGlobalData.h
index 4e818b8..ce8539d 100644
--- a/JavaScriptCore/kjs/JSGlobalData.h
+++ b/JavaScriptCore/kjs/JSGlobalData.h
@@ -46,6 +46,7 @@
     class Heap;
     class IdentifierTable;
     class JSGlobalObject;
+    class JSObject;
     class Lexer;
     class Machine;
     class Parser;
@@ -83,7 +84,7 @@
 
         SmallStrings smallStrings;
         
-        HashMap<OpaqueJSClass*, OpaqueJSClassContextData*>* opaqueJSClassData;
+        HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
 
         HashSet<ParserRefCounted*>* newParserObjects;
         HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
@@ -95,6 +96,8 @@
 
         bool isSharedInstance;
 
+        HashSet<JSObject*> arrayVisitedElements;
+
     private:
         JSGlobalData(bool isShared = false);
 
diff --git a/JavaScriptCore/kjs/JSGlobalObject.h b/JavaScriptCore/kjs/JSGlobalObject.h
index b25ab4f..8c18cce 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.h
+++ b/JavaScriptCore/kjs/JSGlobalObject.h
@@ -138,8 +138,6 @@
             RefPtr<JSGlobalData> globalData;
 
             HashSet<ProgramCodeBlock*> codeBlocks;
-
-            OwnPtr<HashSet<JSObject*> > arrayVisitedElements; // Global data shared by array prototype functions.
         };
 
     public:
@@ -242,8 +240,6 @@
 
         virtual bool isDynamicScope() const;
 
-        HashSet<JSObject*>& arrayVisitedElements() { if (!d()->arrayVisitedElements) d()->arrayVisitedElements.set(new HashSet<JSObject*>); return *d()->arrayVisitedElements; }
-
         HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
 
         void copyGlobalsFrom(RegisterFile&);
diff --git a/JavaScriptCore/kjs/Shell.cpp b/JavaScriptCore/kjs/Shell.cpp
index 3015d98..c986990 100644
--- a/JavaScriptCore/kjs/Shell.cpp
+++ b/JavaScriptCore/kjs/Shell.cpp
@@ -231,7 +231,7 @@
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
-    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
 
     stopWatch.start();
     Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
@@ -247,7 +247,7 @@
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
-    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
 
     return jsUndefined();