Remove support for anonymous storage from jsobjects
https://bugs.webkit.org/show_bug.cgi?id=67881

Reviewed by Sam Weinig.

Source/JavaScriptCore:

Remove all use of anonymous slots, essentially a mechanical change
in JavaScriptCore

* API/JSCallbackConstructor.h:
(JSC::JSCallbackConstructor::createStructure):
* API/JSCallbackFunction.h:
(JSC::JSCallbackFunction::createStructure):
* API/JSCallbackObject.h:
(JSC::JSCallbackObject::createStructure):
* JavaScriptCore.exp:
* debugger/DebuggerActivation.h:
(JSC::DebuggerActivation::createStructure):
* heap/MarkStack.cpp:
(JSC::MarkStack::validateValue):
* heap/MarkStack.h:
* runtime/Arguments.h:
(JSC::Arguments::createStructure):
* runtime/ArrayConstructor.h:
(JSC::ArrayConstructor::createStructure):
* runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::finishCreation):
* runtime/ArrayPrototype.h:
(JSC::ArrayPrototype::createStructure):
* runtime/BooleanObject.h:
(JSC::BooleanObject::createStructure):
* runtime/BooleanPrototype.cpp:
(JSC::BooleanPrototype::BooleanPrototype):
* runtime/BooleanPrototype.h:
(JSC::BooleanPrototype::createStructure):
* runtime/DateConstructor.h:
(JSC::DateConstructor::createStructure):
* runtime/DateInstance.h:
(JSC::DateInstance::createStructure):
* runtime/DatePrototype.cpp:
(JSC::DatePrototype::DatePrototype):
* runtime/DatePrototype.h:
(JSC::DatePrototype::createStructure):
* runtime/ErrorInstance.h:
(JSC::ErrorInstance::createStructure):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::finishCreation):
* runtime/ErrorPrototype.h:
(JSC::ErrorPrototype::createStructure):
* runtime/ExceptionHelpers.h:
(JSC::InterruptedExecutionError::createStructure):
(JSC::TerminatedExecutionError::createStructure):
* runtime/Executable.h:
(JSC::ExecutableBase::createStructure):
(JSC::NativeExecutable::createStructure):
(JSC::EvalExecutable::createStructure):
(JSC::ProgramExecutable::createStructure):
(JSC::FunctionExecutable::createStructure):
* runtime/FunctionPrototype.h:
(JSC::FunctionPrototype::createStructure):
* runtime/GetterSetter.h:
(JSC::GetterSetter::createStructure):
* runtime/InternalFunction.h:
(JSC::InternalFunction::createStructure):
* runtime/JSAPIValueWrapper.h:
(JSC::JSAPIValueWrapper::createStructure):
* runtime/JSActivation.h:
(JSC::JSActivation::createStructure):
* runtime/JSArray.h:
(JSC::JSArray::createStructure):
* runtime/JSByteArray.cpp:
(JSC::JSByteArray::createStructure):
* runtime/JSCell.h:
* runtime/JSFunction.h:
(JSC::JSFunction::createStructure):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::finishCreation):
(JSC::JSGlobalObject::createStructure):
* runtime/JSNotAnObject.h:
(JSC::JSNotAnObject::createStructure):
* runtime/JSONObject.h:
(JSC::JSONObject::createStructure):
* runtime/JSObject.h:
(JSC::JSObject::createStructure):
(JSC::JSNonFinalObject::createStructure):
(JSC::JSFinalObject::createStructure):
* runtime/JSPropertyNameIterator.cpp:
(JSC::JSPropertyNameIterator::create):
* runtime/JSPropertyNameIterator.h:
(JSC::JSPropertyNameIterator::createStructure):
* runtime/JSStaticScopeObject.h:
(JSC::JSStaticScopeObject::createStructure):
* runtime/JSString.h:
(JSC::RopeBuilder::createStructure):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::createStructure):
* runtime/JSWrapperObject.h:
(JSC::JSWrapperObject::createStructure):
* runtime/MathObject.h:
(JSC::MathObject::createStructure):
* runtime/NativeErrorConstructor.h:
(JSC::NativeErrorConstructor::createStructure):
* runtime/NumberConstructor.h:
(JSC::NumberConstructor::createStructure):
* runtime/NumberObject.h:
(JSC::NumberObject::createStructure):
* runtime/NumberPrototype.cpp:
(JSC::NumberPrototype::NumberPrototype):
* runtime/NumberPrototype.h:
(JSC::NumberPrototype::createStructure):
* runtime/ObjectConstructor.h:
(JSC::ObjectConstructor::createStructure):
* runtime/ObjectPrototype.cpp:
(JSC::ObjectPrototype::finishCreation):
* runtime/ObjectPrototype.h:
(JSC::ObjectPrototype::createStructure):
* runtime/RegExp.h:
(JSC::RegExp::createStructure):
* runtime/RegExpConstructor.h:
(JSC::RegExpConstructor::createStructure):
* runtime/RegExpObject.h:
(JSC::RegExpObject::createStructure):
* runtime/RegExpPrototype.h:
(JSC::RegExpPrototype::createStructure):
* runtime/ScopeChain.h:
(JSC::ScopeChainNode::createStructure):
* runtime/StrictEvalActivation.h:
(JSC::StrictEvalActivation::createStructure):
* runtime/StringConstructor.h:
(JSC::StringConstructor::createStructure):
* runtime/StringObject.h:
(JSC::StringObject::createStructure):
* runtime/StringObjectThatMasqueradesAsUndefined.h:
(JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::StringPrototype):
* runtime/StringPrototype.h:
(JSC::StringPrototype::createStructure):
* runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::materializePropertyMap):
(JSC::Structure::addPropertyTransitionToExistingStructure):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::removePropertyTransition):
(JSC::Structure::changePrototypeTransition):
(JSC::Structure::despecifyFunctionTransition):
(JSC::Structure::getterSetterTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::preventExtensionsTransition):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::addPropertyWithoutTransition):
(JSC::Structure::removePropertyWithoutTransition):
(JSC::Structure::get):
(JSC::Structure::putSpecificValue):
(JSC::Structure::remove):
(JSC::Structure::checkConsistency):
* runtime/Structure.h:
(JSC::Structure::create):
(JSC::Structure::propertyStorageSize):
(JSC::Structure::get):
* runtime/StructureChain.h:
(JSC::StructureChain::createStructure):

Source/JavaScriptGlue:

Don't need an anonymous slot count anymore

* UserObjectImp.h:
(UserObjectImp::createStructure):

Source/WebCore:

Remove all use of anonymous slots, this required modifying
bindings generation to add member variables for cached attributes,
and override visitChildren with the necessary logic to mark those
new members.

I added bindings generation tests for these values.

* bindings/js/JSAudioConstructor.h:
(WebCore::JSAudioConstructor::createStructure):
* bindings/js/JSDOMBinding.h:
(WebCore::DOMConstructorObject::createStructure):
* bindings/js/JSDOMGlobalObject.h:
(WebCore::JSDOMGlobalObject::createStructure):
* bindings/js/JSDOMWindowBase.h:
(WebCore::JSDOMWindowBase::createStructure):
* bindings/js/JSDOMWindowShell.h:
(WebCore::JSDOMWindowShell::createStructure):
* bindings/js/JSDOMWrapper.h:
(WebCore::JSDOMWrapper::createStructure):
* bindings/js/JSImageConstructor.h:
(WebCore::JSImageConstructor::createStructure):
* bindings/js/JSMessageEventCustom.cpp:
(WebCore::JSMessageEvent::data):
(WebCore::JSMessageEvent::initMessageEvent):
* bindings/js/JSOptionConstructor.h:
(WebCore::JSOptionConstructor::createStructure):
* bindings/js/JSWorkerContextBase.h:
(WebCore::JSWorkerContextBase::createStructure):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateImplementation):
(GenerateConstructorDeclaration):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfaceConstructor::createStructure):
* bindings/scripts/test/JS/JSTestInterface.h:
(WebCore::JSTestInterface::createStructure):
(WebCore::JSTestInterfacePrototype::createStructure):
* bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp:
(WebCore::JSTestMediaQueryListListenerConstructor::createStructure):
* bindings/scripts/test/JS/JSTestMediaQueryListListener.h:
(WebCore::JSTestMediaQueryListListener::createStructure):
(WebCore::JSTestMediaQueryListListenerPrototype::createStructure):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::JSTestObjConstructor::createStructure):
(WebCore::jsTestObjCachedAttribute1):
(WebCore::jsTestObjCachedAttribute2):
(WebCore::JSTestObj::visitChildren):
* bindings/scripts/test/JS/JSTestObj.h:
(WebCore::JSTestObj::createStructure):
(WebCore::JSTestObjPrototype::createStructure):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
(WebCore::JSTestSerializedScriptValueInterfaceConstructor::createStructure):
* bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h:
(WebCore::JSTestSerializedScriptValueInterface::createStructure):
(WebCore::JSTestSerializedScriptValueInterfacePrototype::createStructure):
* bindings/scripts/test/TestObj.idl:
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::TestObjInternal::cachedAttribute1AttrGetter):
(WebCore::TestObjInternal::cachedAttribute2AttrGetter):
* bridge/c/CRuntimeObject.h:
(JSC::Bindings::CRuntimeObject::createStructure):
* bridge/c/c_instance.cpp:
(JSC::Bindings::CRuntimeMethod::createStructure):
* bridge/jni/jsc/JavaInstanceJSC.cpp:
(JavaRuntimeMethod::createStructure):
* bridge/jni/jsc/JavaRuntimeObject.h:
(JSC::Bindings::JavaRuntimeObject::createStructure):
* bridge/objc/ObjCRuntimeObject.h:
(JSC::Bindings::ObjCRuntimeObject::createStructure):
* bridge/objc/objc_instance.mm:
(ObjCRuntimeMethod::createStructure):
* bridge/objc/objc_runtime.h:
(JSC::Bindings::ObjcFallbackObjectImp::createStructure):
* bridge/runtime_array.h:
(JSC::RuntimeArray::createStructure):
* bridge/runtime_method.h:
(JSC::RuntimeMethod::createStructure):
* bridge/runtime_object.h:
(JSC::Bindings::RuntimeObject::createStructure):

Source/WebKit/mac:

Remove the use of AnonymousSlotCount

* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyRuntimeMethod::createStructure):
* Plugins/Hosted/ProxyRuntimeObject.h:
(WebKit::ProxyRuntimeObject::createStructure):

Source/WebKit2:

Remove the use of AnonymousSlotCount.

* WebProcess/Plugins/Netscape/JSNPMethod.h:
(WebKit::JSNPMethod::createStructure):
* WebProcess/Plugins/Netscape/JSNPObject.h:
(WebKit::JSNPObject::createStructure):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94929 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 1f24b94..e89fb3f 100644
--- a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -803,15 +803,9 @@
     push(@headerContent,
         "    static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\n" .
         "    {\n" .
-        "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);\n" .
+        "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\n" .
         "    }\n\n");
 
-    # visit function
-    if ($needsMarkChildren) {
-        push(@headerContent, "    virtual void visitChildren(JSC::SlotVisitor&);\n\n");
-        $structureFlags{"JSC::OverridesVisitChildren"} = 1;
-    }
-
     # Custom pushEventHandlerScope function
     push(@headerContent, "    virtual JSC::ScopeChainNode* pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChainNode*) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"};
 
@@ -868,16 +862,19 @@
             $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"};
             $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCCustomSetter"};
             if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) {
-                push(@headerContent, "    static const unsigned " . $attribute->signature->name . "Slot = $numCachedAttributes + Base::AnonymousSlotCount;\n");
+                push(@headerContent, "    JSC::WriteBarrier<JSC::Unknown> m_" . $attribute->signature->name . ";\n");
                 $numCachedAttributes++;
+                $needsMarkChildren = 1;
             }
         }
     }
 
-    if ($numCachedAttributes > 0) {
-        push(@headerContent, "    using $parentClassName" . "::putAnonymousValue;\n");
-        push(@headerContent, "    using $parentClassName" . "::getAnonymousValue;\n");
+    # visit function
+    if ($needsMarkChildren) {
+        push(@headerContent, "    virtual void visitChildren(JSC::SlotVisitor&);\n\n");
+        $structureFlags{"JSC::OverridesVisitChildren"} = 1;
     }
+
     if ($numCustomAttributes > 0) {
         push(@headerContent, "\n    // Custom attributes\n");
 
@@ -921,12 +918,6 @@
         push(@headerContent, "        return static_cast<$implClassName*>(Base::impl());\n");
         push(@headerContent, "    }\n");
     }
-    
-    # anonymous slots
-    if ($numCachedAttributes) {
-        push(@headerContent, "public:\n");
-        push(@headerContent, "    static const unsigned AnonymousSlotCount = $numCachedAttributes + Base::AnonymousSlotCount;\n");
-    }
 
     push(@headerContent, "protected:\n");
     # Constructor
@@ -1046,7 +1037,7 @@
     push(@headerContent,
         "    static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\n" .
         "    {\n" .
-        "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);\n" .
+        "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\n" .
         "    }\n");
     if ($dataNode->extendedAttributes->{"DelegatingPrototypePutFunction"}) {
         push(@headerContent, "    virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n");
@@ -1533,23 +1524,8 @@
         }
     }
     push(@implContent, "    ASSERT(inherits(&s_info));\n");
-    if ($numCachedAttributes > 0) {
-        push(@implContent, "    for (unsigned i = Base::AnonymousSlotCount; i < AnonymousSlotCount; i++)\n");
-        push(@implContent, "        putAnonymousValue(globalObject->globalData(), i, JSValue());\n");
-    }
     push(@implContent, "}\n\n");
 
-    if ($needsMarkChildren && !$dataNode->extendedAttributes->{"CustomMarkFunction"}) {
-        push(@implContent, "void ${className}::visitChildren(SlotVisitor& visitor)\n");
-        push(@implContent, "{\n");
-        push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(this, &s_info);\n");
-        push(@implContent, "    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);\n");
-        push(@implContent, "    ASSERT(structure()->typeInfo().overridesVisitChildren());\n");
-        push(@implContent, "    Base::visitChildren(visitor);\n");
-        push(@implContent, "    impl()->visitJSEventListeners(visitor);\n");
-        push(@implContent, "}\n\n");
-    }
-
     if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) {
         push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec, JSGlobalObject* globalObject)\n");
         push(@implContent, "{\n");
@@ -1618,6 +1594,10 @@
                 push(@implContent, "{\n");
                 push(@implContent, "    ${className}* castedThis = static_cast<$className*>(asObject(slotBase));\n");
 
+                if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) {
+                    $needsMarkChildren = 1;
+                }
+
                 if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && 
                         !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"} &&
                         !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurityOnGet"}) {
@@ -1663,7 +1643,7 @@
                     if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) {
                         $cacheIndex = $currentCachedAttribute;
                         $currentCachedAttribute++;
-                        push(@implContent, "    if (JSValue cachedValue = castedThis->getAnonymousValue(" . $className . "::" . $attribute->signature->name . "Slot))\n");
+                        push(@implContent, "    if (JSValue cachedValue = m_" . $attribute->signature->name . ".get())\n");
                         push(@implContent, "        return cachedValue;\n");
                     }
 
@@ -1688,7 +1668,7 @@
                         }
                     }
                     
-                    push(@implContent, "    castedThis->putAnonymousValue(exec->globalData(), " . $className . "::" . $attribute->signature->name . "Slot, result);\n") if ($attribute->signature->extendedAttributes->{"CachedAttribute"});
+                    push(@implContent, "    m_" . $attribute->signature->name . ".set(exec->globalData(), this, result);\n") if ($attribute->signature->extendedAttributes->{"CachedAttribute"});
                     push(@implContent, "    return result;\n");
 
                 } else {
@@ -2192,6 +2172,7 @@
                     GenerateImplementationFunctionCall($function, $functionString, $paramIndex, "    ", $svgPropertyType, $implClassName);
                 }
             }
+
             push(@implContent, "}\n\n");
 
             if ($function->{overloads} && @{$function->{overloads}} > 1 && $function->{overloadIndex} == @{$function->{overloads}}) {
@@ -2203,6 +2184,29 @@
                 push(@implContent, "#endif\n\n");
             }
         }
+        
+        if ($needsMarkChildren && !$dataNode->extendedAttributes->{"CustomMarkFunction"}) {
+            push(@implContent, "void ${className}::visitChildren(SlotVisitor& visitor)\n");
+            push(@implContent, "{\n");
+            push(@implContent, "    ASSERT_GC_OBJECT_INHERITS(this, &s_info);\n");
+            push(@implContent, "    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);\n");
+            push(@implContent, "    ASSERT(structure()->typeInfo().overridesVisitChildren());\n");
+            push(@implContent, "    Base::visitChildren(visitor);\n");
+            if ($dataNode->extendedAttributes->{"EventTarget"}) {
+                push(@implContent, "    impl()->visitJSEventListeners(visitor);\n");
+            }
+            if ($numCachedAttributes > 0) {
+                foreach (@{$dataNode->attributes}) {
+                    my $attribute = $_;
+                    if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) {
+                        push(@implContent, "    if (m_" . $attribute->signature->name . ")\n");
+                        push(@implContent, "        visitor.append(&m_" . $attribute->signature->name . ");\n");
+                    }
+                }
+            }
+            push(@implContent, "}\n\n");
+        }
+        die "Can't generate binding for class with cached attribute and custom mark." if (($numCachedAttributes > 0) and ($dataNode->extendedAttributes->{"CustomMarkFunction"}));
     }
 
     if ($numConstants > 0) {
@@ -3117,7 +3121,7 @@
 
     push(@$outputArray, "    static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\n");
     push(@$outputArray, "    {\n");
-    push(@$outputArray, "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);\n");
+    push(@$outputArray, "        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\n");
     push(@$outputArray, "    }\n");
 
     push(@$outputArray, "protected:\n");
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
index 26de183..5047c61 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
@@ -78,7 +78,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 protected:
     static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | DOMConstructorObject::StructureFlags;
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.h b/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.h
index b74d691..432f73b 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.h
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.h
@@ -46,7 +46,7 @@
 
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
     static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);
@@ -74,7 +74,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
 private:
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp
index 4b5856e..326bb2b 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp
@@ -79,7 +79,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 protected:
     static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | DOMConstructorObject::StructureFlags;
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.h b/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.h
index e355ad8..d4d5f65 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.h
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.h
@@ -44,7 +44,7 @@
 
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
     static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);
@@ -74,7 +74,7 @@
     virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&);
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
 private:
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
index d2d637e..3bb307e 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
@@ -116,6 +116,8 @@
 #if ENABLE(Condition1) || ENABLE(Condition2)
     { "conditionalAttr6", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjConditionalAttr6Constructor), (intptr_t)setJSTestObjConditionalAttr6Constructor THUNK_GENERATOR(0) },
 #endif
+    { "cachedAttribute1", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCachedAttribute1), (intptr_t)0 THUNK_GENERATOR(0) },
+    { "cachedAttribute2", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCachedAttribute2), (intptr_t)0 THUNK_GENERATOR(0) },
     { "description", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjDescription), (intptr_t)0 THUNK_GENERATOR(0) },
     { "id", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjId), (intptr_t)setJSTestObjId THUNK_GENERATOR(0) },
     { "hash", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjHash), (intptr_t)0 THUNK_GENERATOR(0) },
@@ -124,7 +126,7 @@
 };
 
 #undef THUNK_GENERATOR
-static JSC_CONST_HASHTABLE HashTable JSTestObjTable = { 134, 127, JSTestObjTableValues, 0 };
+static JSC_CONST_HASHTABLE HashTable JSTestObjTable = { 135, 127, JSTestObjTableValues, 0 };
 /* Hash table for constructor */
 #if ENABLE(JIT)
 #define THUNK_GENERATOR(generator) , generator
@@ -179,7 +181,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 protected:
     static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | DOMConstructorObject::StructureFlags;
@@ -670,6 +672,32 @@
 
 #endif
 
+JSValue jsTestObjCachedAttribute1(ExecState* exec, JSValue slotBase, const Identifier&)
+{
+    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(slotBase));
+    UNUSED_PARAM(exec);
+    if (JSValue cachedValue = m_cachedAttribute1.get())
+        return cachedValue;
+    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+    JSValue result = imp->cachedAttribute1() ? imp->cachedAttribute1()->deserialize(exec, castedThis->globalObject()) : jsNull();
+    m_cachedAttribute1.set(exec->globalData(), this, result);
+    return result;
+}
+
+
+JSValue jsTestObjCachedAttribute2(ExecState* exec, JSValue slotBase, const Identifier&)
+{
+    JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(slotBase));
+    UNUSED_PARAM(exec);
+    if (JSValue cachedValue = m_cachedAttribute2.get())
+        return cachedValue;
+    TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+    JSValue result = imp->cachedAttribute2() ? imp->cachedAttribute2()->deserialize(exec, castedThis->globalObject()) : jsNull();
+    m_cachedAttribute2.set(exec->globalData(), this, result);
+    return result;
+}
+
+
 JSValue jsTestObjDescription(ExecState* exec, JSValue slotBase, const Identifier&)
 {
     JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(slotBase));
@@ -1815,6 +1843,18 @@
     return JSValue::encode(result);
 }
 
+void JSTestObj::visitChildren(SlotVisitor& visitor)
+{
+    ASSERT_GC_OBJECT_INHERITS(this, &s_info);
+    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
+    ASSERT(structure()->typeInfo().overridesVisitChildren());
+    Base::visitChildren(visitor);
+    if (m_cachedAttribute1)
+        visitor.append(&m_cachedAttribute1);
+    if (m_cachedAttribute2)
+        visitor.append(&m_cachedAttribute2);
+}
+
 // Constant getters
 
 JSValue jsTestObjCONST_VALUE_0(ExecState* exec, JSValue, const Identifier&)
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h
index 4d0f797..fb74b56 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h
@@ -45,10 +45,14 @@
 
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
     static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);
+    JSC::WriteBarrier<JSC::Unknown> m_cachedAttribute1;
+    JSC::WriteBarrier<JSC::Unknown> m_cachedAttribute2;
+    virtual void visitChildren(JSC::SlotVisitor&);
+
 
     // Custom attributes
     JSC::JSValue customAttr(JSC::ExecState*) const;
@@ -63,7 +67,7 @@
     RefPtr<TestObj> m_impl;
 protected:
     JSTestObj(JSC::Structure*, JSDOMGlobalObject*, PassRefPtr<TestObj>);
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
+    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesVisitChildren | Base::StructureFlags;
 };
 
 JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestObj*);
@@ -83,13 +87,13 @@
     virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&);
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
 private:
     JSTestObjPrototype(JSC::JSGlobalData& globalData, JSC::JSGlobalObject*, JSC::Structure* structure) : JSC::JSNonFinalObject(globalData, structure) { finishCreation(globalData); }
 protected:
-    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
+    static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesVisitChildren | Base::StructureFlags;
 };
 
 // Functions
@@ -201,6 +205,8 @@
 void setJSTestObjConditionalAttr5Constructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);
 JSC::JSValue jsTestObjConditionalAttr6Constructor(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
 void setJSTestObjConditionalAttr6Constructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);
+JSC::JSValue jsTestObjCachedAttribute1(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
+JSC::JSValue jsTestObjCachedAttribute2(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
 JSC::JSValue jsTestObjDescription(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
 JSC::JSValue jsTestObjId(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
 void setJSTestObjId(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
index b079339..732b272 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
@@ -80,7 +80,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 protected:
     static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::ImplementsHasInstance | DOMConstructorObject::StructureFlags;
diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h b/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h
index 6dfa781..c14dd90 100644
--- a/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h
+++ b/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h
@@ -46,7 +46,7 @@
 
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
     static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);
@@ -74,7 +74,7 @@
     static const JSC::ClassInfo s_info;
     static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
     {
-        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+        return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
     }
 
 private:
diff --git a/Source/WebCore/bindings/scripts/test/TestObj.idl b/Source/WebCore/bindings/scripts/test/TestObj.idl
index 4acae6a..75b49ab 100644
--- a/Source/WebCore/bindings/scripts/test/TestObj.idl
+++ b/Source/WebCore/bindings/scripts/test/TestObj.idl
@@ -146,6 +146,11 @@
         attribute [Conditional=Condition1|Condition2] TestObjectCConstructor conditionalAttr6;
 
 #if defined(TESTING_V8) || defined(TESTING_JS)
+        readonly attribute [CachedAttribute] any cachedAttribute1;
+        readonly attribute [CachedAttribute] any cachedAttribute2;
+#endif
+
+#if defined(TESTING_V8) || defined(TESTING_JS)
         // Overloads
         void    overloadedMethod(in TestObj objArg, in DOMString strArg);
         void    overloadedMethod(in TestObj objArg, in [Optional] long intArg);
diff --git a/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp b/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
index 56d6c7a..8dd6662 100644
--- a/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
+++ b/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
@@ -39,6 +39,7 @@
 #include "V8IsolatedContext.h"
 #include "V8Proxy.h"
 #include "V8TestCallback.h"
+#include "V8any.h"
 #include "V8int.h"
 #include "V8log.h"
 #include <wtf/GetPtr.h>
@@ -580,6 +581,34 @@
 
 #endif // ENABLE(Condition1) || ENABLE(Condition2)
 
+static v8::Handle<v8::Value> cachedAttribute1AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+    INC_STATS("DOM.TestObj.cachedAttribute1._get");
+    TestObj* imp = V8TestObj::toNative(info.Holder());
+    RefPtr<any> result = imp->cachedAttribute1();
+    v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
+    if (wrapper.IsEmpty()) {
+        wrapper = toV8(result.get());
+        if (!wrapper.IsEmpty())
+            V8DOMWrapper::setNamedHiddenReference(info.Holder(), "cachedAttribute1", wrapper);
+    }
+    return wrapper;
+}
+
+static v8::Handle<v8::Value> cachedAttribute2AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+    INC_STATS("DOM.TestObj.cachedAttribute2._get");
+    TestObj* imp = V8TestObj::toNative(info.Holder());
+    RefPtr<any> result = imp->cachedAttribute2();
+    v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
+    if (wrapper.IsEmpty()) {
+        wrapper = toV8(result.get());
+        if (!wrapper.IsEmpty())
+            V8DOMWrapper::setNamedHiddenReference(info.Holder(), "cachedAttribute2", wrapper);
+    }
+    return wrapper;
+}
+
 static v8::Handle<v8::Value> enabledAtRuntimeAttr1AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     INC_STATS("DOM.TestObj.enabledAtRuntimeAttr1._get");
@@ -1277,6 +1306,10 @@
     // Attribute 'conditionalAttr6' (Type: 'attribute' ExtAttr: 'Conditional')
     {"conditionalAttr6", TestObjInternal::TestObjConstructorGetter, 0, &V8TestObjectC::info, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::ReadOnly), 0 /* on instance */},
 #endif // ENABLE(Condition1) || ENABLE(Condition2)
+    // Attribute 'cachedAttribute1' (Type: 'readonly attribute' ExtAttr: 'CachedAttribute')
+    {"cachedAttribute1", TestObjInternal::cachedAttribute1AttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
+    // Attribute 'cachedAttribute2' (Type: 'readonly attribute' ExtAttr: 'CachedAttribute')
+    {"cachedAttribute2", TestObjInternal::cachedAttribute2AttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
     // Attribute 'description' (Type: 'readonly attribute' ExtAttr: '')
     {"description", TestObjInternal::descriptionAttrGetter, 0, 0 /* no data */, static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None), 0 /* on instance */},
     // Attribute 'id' (Type: 'attribute' ExtAttr: '')