]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSGlobalObject.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / runtime / JSGlobalObject.h
index bb0836256ea57065836ba114c8823b49c0a6ae01..9f05d49123aa43f9ed33bdd423bc01d32b4da7e9 100644 (file)
 #include "JSArray.h"
 #include "JSGlobalData.h"
 #include "JSVariableObject.h"
-#include "NativeFunctionWrapper.h"
+#include "JSWeakObjectMapRefInternal.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
+#include "StructureChain.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/RandomNumber.h>
 
 namespace JSC {
 
@@ -40,10 +42,8 @@ namespace JSC {
     class ErrorConstructor;
     class FunctionPrototype;
     class GlobalCodeBlock;
-    class GlobalEvalFunction;
     class NativeErrorConstructor;
     class ProgramCodeBlock;
-    class PrototypeFunction;
     class RegExpConstructor;
     class RegExpPrototype;
     class RegisterFile;
@@ -55,126 +55,106 @@ namespace JSC {
     
     class JSGlobalObject : public JSVariableObject {
     protected:
-        using JSVariableObject::JSVariableObjectData;
-
-        struct JSGlobalObjectData : public JSVariableObjectData {
-            // We use an explicit destructor function pointer instead of a
-            // virtual destructor because we want to avoid adding a vtable
-            // pointer to this struct. Adding a vtable pointer would force the
-            // compiler to emit costly pointer fixup code when casting from
-            // JSVariableObjectData* to JSGlobalObjectData*.
-            typedef void (*Destructor)(void*);
-
-            JSGlobalObjectData(Destructor destructor)
-                : JSVariableObjectData(&symbolTable, 0)
-                , destructor(destructor)
-                , registerArraySize(0)
-                , globalScopeChain(NoScopeChain())
-                , regExpConstructor(0)
-                , errorConstructor(0)
-                , evalErrorConstructor(0)
-                , rangeErrorConstructor(0)
-                , referenceErrorConstructor(0)
-                , syntaxErrorConstructor(0)
-                , typeErrorConstructor(0)
-                , URIErrorConstructor(0)
-                , evalFunction(0)
-                , callFunction(0)
-                , applyFunction(0)
-                , objectPrototype(0)
-                , functionPrototype(0)
-                , arrayPrototype(0)
-                , booleanPrototype(0)
-                , stringPrototype(0)
-                , numberPrototype(0)
-                , datePrototype(0)
-                , regExpPrototype(0)
-                , methodCallDummy(0)
-            {
-            }
-            
-            Destructor destructor;
-            
-            size_t registerArraySize;
-
-            JSGlobalObject* next;
-            JSGlobalObject* prev;
-
-            Debugger* debugger;
-            
-            ScopeChain globalScopeChain;
-            Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
-
-            int recursion;
-
-            RegExpConstructor* regExpConstructor;
-            ErrorConstructor* errorConstructor;
-            NativeErrorConstructor* evalErrorConstructor;
-            NativeErrorConstructor* rangeErrorConstructor;
-            NativeErrorConstructor* referenceErrorConstructor;
-            NativeErrorConstructor* syntaxErrorConstructor;
-            NativeErrorConstructor* typeErrorConstructor;
-            NativeErrorConstructor* URIErrorConstructor;
-
-            GlobalEvalFunction* evalFunction;
-            NativeFunctionWrapper* callFunction;
-            NativeFunctionWrapper* applyFunction;
-
-            ObjectPrototype* objectPrototype;
-            FunctionPrototype* functionPrototype;
-            ArrayPrototype* arrayPrototype;
-            BooleanPrototype* booleanPrototype;
-            StringPrototype* stringPrototype;
-            NumberPrototype* numberPrototype;
-            DatePrototype* datePrototype;
-            RegExpPrototype* regExpPrototype;
-
-            JSObject* methodCallDummy;
-
-            RefPtr<Structure> argumentsStructure;
-            RefPtr<Structure> arrayStructure;
-            RefPtr<Structure> booleanObjectStructure;
-            RefPtr<Structure> callbackConstructorStructure;
-            RefPtr<Structure> callbackFunctionStructure;
-            RefPtr<Structure> callbackObjectStructure;
-            RefPtr<Structure> dateStructure;
-            RefPtr<Structure> emptyObjectStructure;
-            RefPtr<Structure> errorStructure;
-            RefPtr<Structure> functionStructure;
-            RefPtr<Structure> numberObjectStructure;
-            RefPtr<Structure> prototypeFunctionStructure;
-            RefPtr<Structure> regExpMatchesArrayStructure;
-            RefPtr<Structure> regExpStructure;
-            RefPtr<Structure> stringObjectStructure;
-
-            SymbolTable symbolTable;
-            unsigned profileGroup;
-
-            RefPtr<JSGlobalData> globalData;
-
-            HashSet<GlobalCodeBlock*> codeBlocks;
+        typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
+
+        RefPtr<JSGlobalData> m_globalData;
+
+        size_t m_registerArraySize;
+        Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
+
+        WriteBarrier<ScopeChainNode> m_globalScopeChain;
+        WriteBarrier<JSObject> m_methodCallDummy;
+
+        WriteBarrier<RegExpConstructor> m_regExpConstructor;
+        WriteBarrier<ErrorConstructor> m_errorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
+        WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
+
+        WriteBarrier<JSFunction> m_evalFunction;
+        WriteBarrier<JSFunction> m_callFunction;
+        WriteBarrier<JSFunction> m_applyFunction;
+
+        WriteBarrier<ObjectPrototype> m_objectPrototype;
+        WriteBarrier<FunctionPrototype> m_functionPrototype;
+        WriteBarrier<ArrayPrototype> m_arrayPrototype;
+        WriteBarrier<BooleanPrototype> m_booleanPrototype;
+        WriteBarrier<StringPrototype> m_stringPrototype;
+        WriteBarrier<NumberPrototype> m_numberPrototype;
+        WriteBarrier<DatePrototype> m_datePrototype;
+        WriteBarrier<RegExpPrototype> m_regExpPrototype;
+
+        WriteBarrier<Structure> m_argumentsStructure;
+        WriteBarrier<Structure> m_arrayStructure;
+        WriteBarrier<Structure> m_booleanObjectStructure;
+        WriteBarrier<Structure> m_callbackConstructorStructure;
+        WriteBarrier<Structure> m_callbackFunctionStructure;
+        WriteBarrier<Structure> m_callbackObjectStructure;
+        WriteBarrier<Structure> m_dateStructure;
+        WriteBarrier<Structure> m_emptyObjectStructure;
+        WriteBarrier<Structure> m_nullPrototypeObjectStructure;
+        WriteBarrier<Structure> m_errorStructure;
+        WriteBarrier<Structure> m_functionStructure;
+        WriteBarrier<Structure> m_numberObjectStructure;
+        WriteBarrier<Structure> m_regExpMatchesArrayStructure;
+        WriteBarrier<Structure> m_regExpStructure;
+        WriteBarrier<Structure> m_stringObjectStructure;
+        WriteBarrier<Structure> m_internalFunctionStructure;
+
+        unsigned m_profileGroup;
+        Debugger* m_debugger;
+
+        WeakMapSet m_weakMaps;
+        Weak<JSGlobalObject> m_weakMapsFinalizer;
+        class WeakMapsFinalizer : public WeakHandleOwner {
+        public:
+            virtual void finalize(Handle<Unknown>, void* context);
         };
+        static WeakMapsFinalizer* weakMapsFinalizer();
+
+        WeakRandom m_weakRandom;
+
+        SymbolTable m_symbolTable;
+
+        bool m_isEvalEnabled;
 
     public:
         void* operator new(size_t, JSGlobalData*);
 
-        explicit JSGlobalObject()
-            : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
+        explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure)
+            : JSVariableObject(globalData, structure, &m_symbolTable, 0)
+            , m_registerArraySize(0)
+            , m_globalScopeChain()
+            , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
+            , m_isEvalEnabled(true)
         {
+            COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
+            putThisToAnonymousValue(0);
             init(this);
         }
 
+        static JS_EXPORTDATA const ClassInfo s_info;
+
     protected:
-        JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
-            : JSVariableObject(structure, data)
+        JSGlobalObject(JSGlobalData& globalData, Structure* structure, JSObject* thisValue)
+            : JSVariableObject(globalData, structure, &m_symbolTable, 0)
+            , m_registerArraySize(0)
+            , m_globalScopeChain()
+            , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
+            , m_isEvalEnabled(true)
         {
+            COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
+            putThisToAnonymousValue(0);
             init(thisValue);
         }
 
     public:
         virtual ~JSGlobalObject();
 
-        virtual void markChildren(MarkStack&);
+        virtual void visitChildren(SlotVisitor&);
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
@@ -185,65 +165,65 @@ namespace JSC {
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
 
-        // Linked list of all global objects that use the same JSGlobalData.
-        JSGlobalObject*& head() { return d()->globalData->head; }
-        JSGlobalObject* next() { return d()->next; }
+        // We use this in the code generator as we perform symbol table
+        // lookups prior to initializing the properties
+        bool symbolTableHasProperty(const Identifier& propertyName);
 
         // The following accessors return pristine values, even if a script 
         // replaces the global object's associated property.
 
-        RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
-
-        ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
-        NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
-        NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
-        NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
-        NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
-        NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
-        NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
-
-        GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
-
-        ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
-        FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
-        ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
-        BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
-        StringPrototype* stringPrototype() const { return d()->stringPrototype; }
-        NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
-        DatePrototype* datePrototype() const { return d()->datePrototype; }
-        RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
-
-        JSObject* methodCallDummy() const { return d()->methodCallDummy; }
-
-        Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
-        Structure* arrayStructure() const { return d()->arrayStructure.get(); }
-        Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
-        Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
-        Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
-        Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
-        Structure* dateStructure() const { return d()->dateStructure.get(); }
-        Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
-        Structure* errorStructure() const { return d()->errorStructure.get(); }
-        Structure* functionStructure() const { return d()->functionStructure.get(); }
-        Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
-        Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
-        Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
-        Structure* regExpStructure() const { return d()->regExpStructure.get(); }
-        Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
-
-        void setProfileGroup(unsigned value) { d()->profileGroup = value; }
-        unsigned profileGroup() const { return d()->profileGroup; }
-
-        Debugger* debugger() const { return d()->debugger; }
-        void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
-        
+        RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
+
+        ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
+        NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
+        NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
+        NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
+        NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
+        NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
+        NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
+
+        JSFunction* evalFunction() const { return m_evalFunction.get(); }
+        JSFunction* callFunction() const { return m_callFunction.get(); }
+        JSFunction* applyFunction() const { return m_applyFunction.get(); }
+
+        ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
+        FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
+        ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
+        BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
+        StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
+        NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
+        DatePrototype* datePrototype() const { return m_datePrototype.get(); }
+        RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
+
+        JSObject* methodCallDummy() const { return m_methodCallDummy.get(); }
+
+        Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+        Structure* arrayStructure() const { return m_arrayStructure.get(); }
+        Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
+        Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
+        Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
+        Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
+        Structure* dateStructure() const { return m_dateStructure.get(); }
+        Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); }
+        Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
+        Structure* errorStructure() const { return m_errorStructure.get(); }
+        Structure* functionStructure() const { return m_functionStructure.get(); }
+        Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
+        Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
+        Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
+        Structure* regExpStructure() const { return m_regExpStructure.get(); }
+        Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+
+        void setProfileGroup(unsigned value) { m_profileGroup = value; }
+        unsigned profileGroup() const { return m_profileGroup; }
+
+        Debugger* debugger() const { return m_debugger; }
+        void setDebugger(Debugger* debugger) { m_debugger = debugger; }
+
         virtual bool supportsProfiling() const { return false; }
-        
-        int recursion() { return d()->recursion; }
-        void incRecursion() { ++d()->recursion; }
-        void decRecursion() { --d()->recursion; }
-        
-        ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
+        virtual bool supportsRichSourceInfo() const { return true; }
+
+        ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
 
         virtual bool isGlobalObject() const { return true; }
 
@@ -254,26 +234,41 @@ namespace JSC {
 
         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
-        virtual bool isDynamicScope() const;
+        virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
 
-        HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+        void disableEval();
+        bool isEvalEnabled() { return m_isEvalEnabled; }
 
         void copyGlobalsFrom(RegisterFile&);
         void copyGlobalsTo(RegisterFile&);
-        
-        void resetPrototype(JSValue prototype);
+        void resizeRegisters(int oldSize, int newSize);
 
-        JSGlobalData* globalData() { return d()->globalData.get(); }
-        JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
+        void resetPrototype(JSGlobalData&, JSValue prototype);
+
+        JSGlobalData& globalData() const { return *m_globalData.get(); }
+
+        static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+        {
+            return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        }
+
+        void registerWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            if (!m_weakMapsFinalizer)
+                m_weakMapsFinalizer.set(globalData(), this, weakMapsFinalizer());
+            m_weakMaps.add(map);
+        }
 
-        static PassRefPtr<Structure> createStructure(JSValue prototype)
+        void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
         {
-            return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
+            m_weakMaps.remove(map);
         }
 
+        double weakRandomNumber() { return m_weakRandom.get(); }
     protected:
 
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
+        static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1;
+        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
 
         struct GlobalPropertyInfo {
             GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
@@ -290,13 +285,11 @@ namespace JSC {
         void addStaticGlobals(GlobalPropertyInfo*, int count);
 
     private:
-        static void destroyJSGlobalObjectData(void*);
-
         // FIXME: Fold reset into init.
         void init(JSObject* thisValue);
         void reset(JSValue prototype);
 
-        void setRegisters(Register* registers, Register* registerArray, size_t count);
+        void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count);
 
         void* operator new(size_t); // can only be allocated with JSGlobalData
     };
@@ -309,42 +302,10 @@ namespace JSC {
         return static_cast<JSGlobalObject*>(asObject(value));
     }
 
-    inline void JSGlobalObject::setRegisters(Register* registers, Register* registerArray, size_t count)
+    inline void JSGlobalObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count)
     {
         JSVariableObject::setRegisters(registers, registerArray);
-        d()->registerArraySize = count;
-    }
-
-    inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
-    {
-        size_t oldSize = d()->registerArraySize;
-        size_t newSize = oldSize + count;
-        Register* registerArray = new Register[newSize];
-        if (d()->registerArray)
-            memcpy(registerArray + count, d()->registerArray.get(), oldSize * sizeof(Register));
-        setRegisters(registerArray + newSize, registerArray, newSize);
-
-        for (int i = 0, index = -static_cast<int>(oldSize) - 1; i < count; ++i, --index) {
-            GlobalPropertyInfo& global = globals[i];
-            ASSERT(global.attributes & DontDelete);
-            SymbolTableEntry newEntry(index, global.attributes);
-            symbolTable().add(global.identifier.ustring().rep(), newEntry);
-            registerAt(index) = global.value;
-        }
-    }
-
-    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-    {
-        if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
-            return true;
-        return symbolTableGet(propertyName, slot);
-    }
-
-    inline bool JSGlobalObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
-    {
-        if (symbolTableGet(propertyName, descriptor))
-            return true;
-        return JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+        m_registerArraySize = count;
     }
 
     inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName)
@@ -356,21 +317,19 @@ namespace JSC {
         return symbolTableGet(propertyName, slot, slotIsWriteable);
     }
 
+    inline bool JSGlobalObject::symbolTableHasProperty(const Identifier& propertyName)
+    {
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        return !entry.isNull();
+    }
+
     inline JSValue Structure::prototypeForLookup(ExecState* exec) const
     {
         if (typeInfo().type() == ObjectType)
-            return m_prototype;
-
-#if USE(JSVALUE32)
-        if (typeInfo().type() == StringType)
-            return exec->lexicalGlobalObject()->stringPrototype();
+            return m_prototype.get();
 
-        ASSERT(typeInfo().type() == NumberType);
-        return exec->lexicalGlobalObject()->numberPrototype();
-#else
         ASSERT(typeInfo().type() == StringType);
         return exec->lexicalGlobalObject()->stringPrototype();
-#endif
     }
 
     inline StructureChain* Structure::prototypeChain(ExecState* exec) const
@@ -378,7 +337,7 @@ namespace JSC {
         // We cache our prototype chain so our clients can share it.
         if (!isValid(exec, m_cachedPrototypeChain.get())) {
             JSValue prototype = prototypeForLookup(exec);
-            m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure());
+            m_cachedPrototypeChain.set(exec->globalData(), this, StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure()));
         }
         return m_cachedPrototypeChain.get();
     }
@@ -389,9 +348,9 @@ namespace JSC {
             return false;
 
         JSValue prototype = prototypeForLookup(exec);
-        RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head();
+        WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
         while(*cachedStructure && !prototype.isNull()) {
-            if (asObject(prototype)->structure() != *cachedStructure)
+            if (asObject(prototype)->structure() != cachedStructure->get())
                 return false;
             ++cachedStructure;
             prototype = asObject(prototype)->prototype();
@@ -410,57 +369,62 @@ namespace JSC {
         return globalData().dynamicGlobalObject;
     }
 
-    inline JSObject* constructEmptyObject(ExecState* exec)
+    inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
     {
-        return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+        return constructEmptyObject(exec, globalObject->emptyObjectStructure());
     }
-    
-    inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
+
+    inline JSObject* constructEmptyObject(ExecState* exec)
     {
-        return new (exec) JSObject(globalObject->emptyObjectStructure());
+        return constructEmptyObject(exec, exec->lexicalGlobalObject());
     }
 
-    inline JSArray* constructEmptyArray(ExecState* exec)
+    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+        return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure());
     }
     
-    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
+    inline JSArray* constructEmptyArray(ExecState* exec)
     {
-        return new (exec) JSArray(globalObject->arrayStructure());
+        return constructEmptyArray(exec, exec->lexicalGlobalObject());
+    }
+
+    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength)
+    {
+        return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), initialLength, CreateInitialized);
     }
 
     inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+        return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength);
     }
 
-    inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
+    inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, JSValue singleItemValue)
     {
         MarkedArgumentBuffer values;
         values.append(singleItemValue);
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+        return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), values);
+    }
+
+    inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
+    {
+        return constructArray(exec, exec->lexicalGlobalObject(), singleItemValue);
+    }
+
+    inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values)
+    {
+        return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), values);
     }
 
     inline JSArray* constructArray(ExecState* exec, const ArgList& values)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+        return constructArray(exec, exec->lexicalGlobalObject(), values);
     }
 
-    class DynamicGlobalObjectScope : public Noncopyable {
+    class DynamicGlobalObjectScope {
+        WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
     public:
-        DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) 
-            : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
-            , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
-        {
-            if (!m_dynamicGlobalObjectSlot) {
-                m_dynamicGlobalObjectSlot = dynamicGlobalObject;
-
-                // Reset the date cache between JS invocations to force the VM
-                // to observe time zone changes.
-                callFrame->globalData().resetDateCache();
-            }
-        }
+        DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
 
         ~DynamicGlobalObjectScope()
         {