]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSGlobalObject.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / runtime / JSGlobalObject.h
index bb0836256ea57065836ba114c8823b49c0a6ae01..435c2be2c024a4930d90491153f14b64e8e54a09 100644 (file)
 
 #include "JSArray.h"
 #include "JSGlobalData.h"
+#include "JSGlobalThis.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 {
 
@@ -39,11 +42,11 @@ namespace JSC {
     class Debugger;
     class ErrorConstructor;
     class FunctionPrototype;
+    class GetterSetter;
     class GlobalCodeBlock;
-    class GlobalEvalFunction;
+    class LLIntOffsetsExtractor;
     class NativeErrorConstructor;
     class ProgramCodeBlock;
-    class PrototypeFunction;
     class RegExpConstructor;
     class RegExpPrototype;
     class RegisterFile;
@@ -53,227 +56,277 @@ namespace JSC {
 
     typedef Vector<ExecState*, 16> ExecStateStack;
     
+    struct GlobalObjectMethodTable {
+        typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*);
+        AllowsAccessFromFunctionPtr allowsAccessFrom;
+
+        typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); 
+        SupportsProfilingFunctionPtr supportsProfiling;
+
+        typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*);
+        SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo;
+
+        typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
+        ShouldInterruptScriptFunctionPtr shouldInterruptScript;
+
+        typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*);
+        ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout;
+    };
+
     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)
+    private:
+        typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
+
+        struct JSGlobalObjectRareData {
+            JSGlobalObjectRareData()
+                : profileGroup(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;
+            WeakMapSet weakMaps;
+            unsigned profileGroup;
         };
 
+    protected:
+
+        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<GetterSetter> m_throwTypeErrorGetterSetter;
+
+        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_boundFunctionStructure;
+        WriteBarrier<Structure> m_namedFunctionStructure;
+        size_t m_functionNameOffset;
+        WriteBarrier<Structure> m_numberObjectStructure;
+        WriteBarrier<Structure> m_regExpMatchesArrayStructure;
+        WriteBarrier<Structure> m_regExpStructure;
+        WriteBarrier<Structure> m_stringObjectStructure;
+        WriteBarrier<Structure> m_internalFunctionStructure;
+
+        Debugger* m_debugger;
+
+        OwnPtr<JSGlobalObjectRareData> m_rareData;
+
+        WeakRandom m_weakRandom;
+
+        SymbolTable m_symbolTable;
+
+        bool m_evalEnabled;
+
+        static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
+        const GlobalObjectMethodTable* m_globalObjectMethodTable;
+
+        void createRareDataIfNeeded()
+        {
+            if (m_rareData)
+                return;
+            m_rareData = adoptPtr(new JSGlobalObjectRareData);
+            Heap::heap(this)->addFinalizer(this, clearRareData);
+        }
+        
     public:
-        void* operator new(size_t, JSGlobalData*);
+        typedef JSVariableObject Base;
 
-        explicit JSGlobalObject()
-            : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
+        static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure)
         {
-            init(this);
+            JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure);
+            globalObject->finishCreation(globalData);
+            return globalObject;
         }
 
+        static JS_EXPORTDATA const ClassInfo s_info;
+
     protected:
-        JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
-            : JSVariableObject(structure, data)
+        explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = 0)
+            : 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_evalEnabled(true)
+            , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
         {
+        }
+
+        void finishCreation(JSGlobalData& globalData)
+        {
+            Base::finishCreation(globalData);
+            structure()->setGlobalObject(globalData, this);
+            init(this);
+        }
+
+        void finishCreation(JSGlobalData& globalData, JSGlobalThis* thisValue)
+        {
+            Base::finishCreation(globalData);
+            structure()->setGlobalObject(globalData, this);
             init(thisValue);
         }
 
     public:
-        virtual ~JSGlobalObject();
+        JS_EXPORT_PRIVATE ~JSGlobalObject();
+        JS_EXPORT_PRIVATE static void destroy(JSCell*);
 
-        virtual void markChildren(MarkStack&);
+        JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
-        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
-        virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
-        virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
-        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
+        JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
+        JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
+        bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
+        JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
 
-        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
-        virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
+        JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
 
-        // Linked list of all global objects that use the same JSGlobalData.
-        JSGlobalObject*& head() { return d()->globalData->head; }
-        JSGlobalObject* next() { return d()->next; }
+        JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
+        JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
+        JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
+
+        // 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; }
-        
-        virtual bool supportsProfiling() const { return false; }
-        
-        int recursion() { return d()->recursion; }
-        void incRecursion() { ++d()->recursion; }
-        void decRecursion() { --d()->recursion; }
-        
-        ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
+        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(); }
 
-        virtual bool isGlobalObject() const { return true; }
+        JSFunction* evalFunction() const { return m_evalFunction.get(); }
+        JSFunction* callFunction() const { return m_callFunction.get(); }
+        JSFunction* applyFunction() const { return m_applyFunction.get(); }
+        GetterSetter* throwTypeErrorGetterSetter(ExecState* exec)
+        {
+            if (!m_throwTypeErrorGetterSetter)
+                createThrowTypeError(exec);
+            return m_throwTypeErrorGetterSetter.get();
+        }
 
-        virtual ExecState* globalExec();
+        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* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
+        Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
+        size_t functionNameOffset() const { return m_functionNameOffset; }
+        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) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
+        unsigned profileGroup() const
+        { 
+            if (!m_rareData)
+                return 0;
+            return m_rareData->profileGroup;
+        }
 
-        virtual bool shouldInterruptScriptBeforeTimeout() const { return false; }
-        virtual bool shouldInterruptScript() const { return true; }
+        Debugger* debugger() const { return m_debugger; }
+        void setDebugger(Debugger* debugger) { m_debugger = debugger; }
 
-        virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
+        const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
 
-        virtual bool isDynamicScope() const;
+        static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; }
+        static bool supportsProfiling(const JSGlobalObject*) { return false; }
+        static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }
 
-        HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+        ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
 
-        void copyGlobalsFrom(RegisterFile&);
-        void copyGlobalsTo(RegisterFile&);
-        
-        void resetPrototype(JSValue prototype);
+        JS_EXPORT_PRIVATE ExecState* globalExec();
+
+        static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; }
+        static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
+
+        bool isDynamicScope(bool& requiresDynamicChecks) const;
+
+        void setEvalEnabled(bool enabled) { m_evalEnabled = enabled; }
+        bool evalEnabled() { return m_evalEnabled; }
+
+        void resizeRegisters(size_t newSize);
+
+        void resetPrototype(JSGlobalData&, JSValue prototype);
+
+        JSGlobalData& globalData() const { return *Heap::heap(this)->globalData(); }
 
-        JSGlobalData* globalData() { return d()->globalData.get(); }
-        JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
+        static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+        {
+            return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
+        }
+
+        void registerWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            createRareDataIfNeeded();
+            m_rareData->weakMaps.add(map);
+        }
 
-        static PassRefPtr<Structure> createStructure(JSValue prototype)
+        void unregisterWeakMap(OpaqueJSWeakObjectMap* map)
         {
-            return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
+            if (m_rareData)
+                m_rareData->weakMaps.remove(map);
         }
 
+        double weakRandomNumber() { return m_weakRandom.get(); }
     protected:
 
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
+        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
 
         struct GlobalPropertyInfo {
             GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
@@ -287,18 +340,19 @@ namespace JSC {
             JSValue value;
             unsigned attributes;
         };
-        void addStaticGlobals(GlobalPropertyInfo*, int count);
+        JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
 
     private:
-        static void destroyJSGlobalObjectData(void*);
-
+        friend class LLIntOffsetsExtractor;
+        
         // FIXME: Fold reset into init.
-        void init(JSObject* thisValue);
+        JS_EXPORT_PRIVATE void init(JSObject* thisValue);
         void reset(JSValue prototype);
 
-        void setRegisters(Register* registers, Register* registerArray, size_t count);
+        void createThrowTypeError(ExecState*);
 
-        void* operator new(size_t); // can only be allocated with JSGlobalData
+        void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count);
+        JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
     };
 
     JSGlobalObject* asGlobalObject(JSValue);
@@ -306,71 +360,37 @@ namespace JSC {
     inline JSGlobalObject* asGlobalObject(JSValue value)
     {
         ASSERT(asObject(value)->isGlobalObject());
-        return static_cast<JSGlobalObject*>(asObject(value));
+        return jsCast<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)
     {
         PropertySlot slot;
-        if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
+        if (JSVariableObject::getOwnPropertySlot(this, exec, propertyName, slot))
             return true;
         bool slotIsWriteable;
         return symbolTableGet(propertyName, slot, slotIsWriteable);
     }
 
-    inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+    inline bool JSGlobalObject::symbolTableHasProperty(const Identifier& propertyName)
     {
-        if (typeInfo().type() == ObjectType)
-            return m_prototype;
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        return !entry.isNull();
+    }
 
-#if USE(JSVALUE32)
-        if (typeInfo().type() == StringType)
-            return exec->lexicalGlobalObject()->stringPrototype();
+    inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+    {
+        if (isObject())
+            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 +398,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 +409,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 +430,75 @@ namespace JSC {
         return globalData().dynamicGlobalObject;
     }
 
+    inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
+    {
+        return constructEmptyObject(exec, globalObject->emptyObjectStructure());
+    }
+
     inline JSObject* constructEmptyObject(ExecState* exec)
     {
-        return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+        return constructEmptyObject(exec, exec->lexicalGlobalObject());
     }
-    
-    inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
+
+    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength = 0)
     {
-        return new (exec) JSObject(globalObject->emptyObjectStructure());
+        return JSArray::create(exec->globalData(), globalObject->arrayStructure(), initialLength);
     }
 
-    inline JSArray* constructEmptyArray(ExecState* exec)
+    inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength = 0)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+        return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength);
     }
-    
-    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
+
+    inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values)
     {
-        return new (exec) JSArray(globalObject->arrayStructure());
+        JSGlobalData& globalData = exec->globalData();
+        unsigned length = values.size();
+        JSArray* array = JSArray::tryCreateUninitialized(globalData, globalObject->arrayStructure(), length);
+
+        // FIXME: we should probably throw an out of memory error here, but
+        // when making this change we should check that all clients of this
+        // function will correctly handle an exception being thrown from here.
+        if (!array)
+            CRASH();
+
+        for (unsigned i = 0; i < length; ++i)
+            array->initializeIndex(globalData, i, values.at(i));
+        array->completeInitialization(length);
+        return array;
     }
 
-    inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
+    inline JSArray* constructArray(ExecState* exec, const ArgList& values)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+        return constructArray(exec, exec->lexicalGlobalObject(), values);
     }
 
-    inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
+    inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const JSValue* values, unsigned length)
     {
-        MarkedArgumentBuffer values;
-        values.append(singleItemValue);
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+        JSGlobalData& globalData = exec->globalData();
+        JSArray* array = JSArray::tryCreateUninitialized(globalData, globalObject->arrayStructure(), length);
+
+        // FIXME: we should probably throw an out of memory error here, but
+        // when making this change we should check that all clients of this
+        // function will correctly handle an exception being thrown from here.
+        if (!array)
+            CRASH();
+
+        for (unsigned i = 0; i < length; ++i)
+            array->initializeIndex(globalData, i, values[i]);
+        array->completeInitialization(length);
+        return array;
     }
 
-    inline JSArray* constructArray(ExecState* exec, const ArgList& values)
+    inline JSArray* constructArray(ExecState* exec, const JSValue* values, unsigned length)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+        return constructArray(exec, exec->lexicalGlobalObject(), values, length);
     }
 
-    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();
-            }
-        }
+        JS_EXPORT_PRIVATE DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
 
         ~DynamicGlobalObjectScope()
         {
@@ -472,6 +510,11 @@ namespace JSC {
         JSGlobalObject* m_savedDynamicGlobalObject;
     };
 
+    inline bool JSGlobalObject::isDynamicScope(bool&) const
+    {
+        return true;
+    }
+
 } // namespace JSC
 
 #endif // JSGlobalObject_h