Rollout r82500
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 23:53:25 +0000 (23:53 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 23:53:25 +0000 (23:53 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@82519 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/Instruction.h
Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
Source/JavaScriptCore/bytecode/StructureStubInfo.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/JavaScriptCore/runtime/JSGlobalData.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
Source/JavaScriptCore/runtime/MarkStack.h
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureChain.cpp
Source/JavaScriptCore/runtime/StructureChain.h

index f0b9c58..8a8c3d1 100644 (file)
@@ -1,3 +1,62 @@
+2011-03-30  Oliver Hunt  <oliver@apple.com>
+
+        Rollout r82500
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dump):
+        (JSC::CodeBlock::derefStructures):
+        (JSC::CodeBlock::refStructures):
+        (JSC::CodeBlock::markAggregate):
+        * bytecode/Instruction.h:
+        (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+        (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+        (JSC::PolymorphicAccessStructureList::derefStructures):
+        (JSC::Instruction::Instruction):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        * bytecode/StructureStubInfo.h:
+        (JSC::StructureStubInfo::initGetByIdChain):
+        (JSC::StructureStubInfo::initPutByIdTransition):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
+        (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_jneq_ptr):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_jneq_ptr):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::privateCompileGetByIdChainList):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::privateCompileGetByIdChainList):
+        * jit/JITStubs.cpp:
+        (JSC::getPolymorphicAccessStructureListSlot):
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/JSCell.h:
+        * runtime/JSGlobalData.cpp:
+        (JSC::JSGlobalData::JSGlobalData):
+        * runtime/JSGlobalData.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::markIfNeeded):
+        * runtime/JSGlobalObject.h:
+        (JSC::Structure::prototypeChain):
+        * runtime/JSObject.h:
+        (JSC::JSObject::markChildrenDirect):
+        * runtime/JSPropertyNameIterator.cpp:
+        (JSC::JSPropertyNameIterator::create):
+        (JSC::JSPropertyNameIterator::get):
+        (JSC::JSPropertyNameIterator::markChildren):
+        * runtime/JSPropertyNameIterator.h:
+        (JSC::JSPropertyNameIterator::setCachedPrototypeChain):
+        * runtime/MarkStack.h:
+        (JSC::MarkStack::append):
+        * runtime/Structure.h:
+        * runtime/StructureChain.cpp:
+        (JSC::StructureChain::StructureChain):
+        * runtime/StructureChain.h:
+        (JSC::StructureChain::create):
+
 2011-03-29  Matthew Delaney  <mdelaney@apple.com>
 
         Reviewed by Simon Fraser.
index 98bbb3c..0a0cf84 100644 (file)
@@ -731,7 +731,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         case op_resolve_global_dynamic: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            JSValue scope = JSValue((++it)->u.jsCell.get());
+            JSValue scope = JSValue((++it)->u.jsCell);
             ++it;
             int depth = (++it)->u.operand;
             printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
@@ -1437,11 +1437,13 @@ void CodeBlock::derefStructures(Instruction* vPC) const
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
         vPC[4].u.structure->deref();
+        vPC[5].u.structureChain->deref();
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
         vPC[4].u.structure->deref();
         vPC[5].u.structure->deref();
+        vPC[6].u.structureChain->deref();
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
@@ -1484,11 +1486,13 @@ void CodeBlock::refStructures(Instruction* vPC) const
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
         vPC[4].u.structure->ref();
+        vPC[5].u.structureChain->ref();
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
         vPC[4].u.structure->ref();
         vPC[5].u.structure->ref();
+        vPC[6].u.structureChain->ref();
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
@@ -1523,20 +1527,6 @@ void CodeBlock::markAggregate(MarkStack& markStack)
         if (callLinkInfo(i).isLinked())
             markStack.append(&callLinkInfo(i).callee);
 #endif
-#if ENABLE(INTERPRETER)
-    Interpreter* interpreter = m_globalData->interpreter;
-    for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
-        Instruction* vPC = &m_instructions[m_propertyAccessInstructions[i]];
-        if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain))
-            markStack.append(&vPC[5].u.structureChain);
-        else if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition))
-            markStack.append(&vPC[6].u.structureChain);
-    }
-#endif
-#if ENABLE(JIT)
-    for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
-        m_structureStubInfos[i].markAggregate(markStack);
-#endif
 }
 
 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
index da0821d..f077cbf 100644 (file)
@@ -63,7 +63,7 @@ namespace JSC {
             Structure* base;
             union {
                 Structure* proto;
-                WriteBarrierBase<StructureChain> chain;
+                StructureChain* chain;
             } u;
 
             void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
@@ -82,11 +82,11 @@ namespace JSC {
                 isChain = false;
             }
             
-            void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
+            void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
             {
                 stubRoutine = _stubRoutine;
                 base = _base;
-                u.chain.set(globalData, owner, _chain);
+                u.chain = _chain;
                 isChain = true;
             }
         } list[POLYMORPHIC_LIST_CACHE_SIZE];
@@ -101,9 +101,9 @@ namespace JSC {
             list[0].set(stubRoutine, firstBase, firstProto);
         }
 
-        PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
+        PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
         {
-            list[0].set(globalData, owner, stubRoutine, firstBase, firstChain);
+            list[0].set(stubRoutine, firstBase, firstChain);
         }
 
         void derefStructures(int count)
@@ -115,22 +115,13 @@ namespace JSC {
                 info.base->deref();
 
                 if (info.u.proto) {
-                    if (!info.isChain)
+                    if (info.isChain)
+                        info.u.chain->deref();
+                    else
                         info.u.proto->deref();
                 }
             }
         }
-
-        void markAggregate(MarkStack& markStack, int count)
-        {
-            for (int i = 0; i < count; ++i) {
-                PolymorphicStubInfo& info = list[i];
-                ASSERT(info.base);
-                
-                if (info.u.proto && info.isChain)
-                    markStack.append(&info.u.chain);
-            }
-        }
     };
 
     struct Instruction {
@@ -139,7 +130,7 @@ namespace JSC {
 #if !ENABLE(COMPUTED_GOTO_INTERPRETER)
             // We have to initialize one of the pointer members to ensure that
             // the entire struct is initialized, when opcode is not a pointer.
-            u.jsCell.clear();
+            u.jsCell = 0;
 #endif
             u.opcode = opcode;
         }
@@ -148,21 +139,13 @@ namespace JSC {
         {
             // We have to initialize one of the pointer members to ensure that
             // the entire struct is initialized in 64-bit.
-            u.jsCell.clear();
+            u.jsCell = 0;
             u.operand = operand;
         }
 
         Instruction(Structure* structure) { u.structure = structure; }
-        Instruction(JSGlobalData& globalData, JSCell* owner, StructureChain* structureChain)
-        {
-            u.structureChain.clear();
-            u.structureChain.set(globalData, owner, structureChain);
-        }
-        Instruction(JSGlobalData& globalData, JSCell* owner, JSCell* jsCell)
-        {
-            u.jsCell.clear();
-            u.jsCell.set(globalData, owner, jsCell);
-        }
+        Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
+        Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
         Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
         Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
 
@@ -170,8 +153,8 @@ namespace JSC {
             Opcode opcode;
             int operand;
             Structure* structure;
-            WriteBarrierBase<StructureChain> structureChain;
-            WriteBarrierBase<JSCell> jsCell;
+            StructureChain* structureChain;
+            JSCell* jsCell;
             PolymorphicAccessStructureList* polymorphicStructures;
             PropertySlot::GetValueFunc getterFunc;
         } u;
index 4d59ac1..5df4841 100644 (file)
@@ -44,6 +44,7 @@ void StructureStubInfo::deref()
         return;
     case access_get_by_id_chain:
         u.getByIdChain.baseObjectStructure->deref();
+        u.getByIdChain.chain->deref();
         return;
     case access_get_by_id_self_list: {
         PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
@@ -60,6 +61,7 @@ void StructureStubInfo::deref()
     case access_put_by_id_transition:
         u.putByIdTransition.previousStructure->deref();
         u.putByIdTransition.structure->deref();
+        u.putByIdTransition.chain->deref();
         return;
     case access_put_by_id_replace:
         u.putByIdReplace.baseObjectStructure->deref();
@@ -76,42 +78,6 @@ void StructureStubInfo::deref()
         ASSERT_NOT_REACHED();
     }
 }
-
-void StructureStubInfo::markAggregate(MarkStack& markStack)
-{
-    switch (accessType) {
-    case access_get_by_id_self:
-        return;
-    case access_get_by_id_proto:
-        return;
-    case access_get_by_id_chain:
-        return;
-    case access_get_by_id_self_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
-        polymorphicStructures->markAggregate(markStack, u.getByIdSelfList.listSize);
-        return;
-    }
-    case access_get_by_id_proto_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
-        polymorphicStructures->markAggregate(markStack, u.getByIdProtoList.listSize);
-        return;
-    }
-    case access_put_by_id_transition:
-        return;
-    case access_put_by_id_replace:
-        return;
-    case access_get_by_id:
-    case access_put_by_id:
-    case access_get_by_id_generic:
-    case access_put_by_id_generic:
-    case access_get_array_length:
-    case access_get_string_length:
-        // These instructions don't ref their Structures.
-        return;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-}
 #endif
 
 } // namespace JSC
index 28202f9..8e2c489 100644 (file)
@@ -85,6 +85,7 @@ namespace JSC {
             baseObjectStructure->ref();
 
             u.getByIdChain.chain = chain;
+            chain->ref();
         }
 
         void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
@@ -116,6 +117,7 @@ namespace JSC {
             structure->ref();
 
             u.putByIdTransition.chain = chain;
+            chain->ref();
         }
 
         void initPutByIdReplace(Structure* baseObjectStructure)
@@ -127,7 +129,6 @@ namespace JSC {
         }
 
         void deref();
-        void markAggregate(MarkStack&);
 
         bool seenOnce()
         {
index 5af3420..b5df53f 100644 (file)
@@ -925,7 +925,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond,
 
     emitOpcode(op_jneq_ptr);
     instructions().append(cond->index());
-    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction()));
+    instructions().append(m_scopeChain->globalObject->callFunction());
     instructions().append(target->bind(begin, instructions().size()));
     return target;
 }
@@ -936,7 +936,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond
 
     emitOpcode(op_jneq_ptr);
     instructions().append(cond->index());
-    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction()));
+    instructions().append(m_scopeChain->globalObject->applyFunction());
     instructions().append(target->bind(begin, instructions().size()));
     return target;
 }
index 6021279..0826f5d 100644 (file)
@@ -3537,9 +3537,10 @@ skip_id_custom_self:
            to ptr, using pointer equality.
          */
         int src = vPC[1].u.operand;
+        JSValue ptr = JSValue(vPC[2].u.jsCell);
         int target = vPC[3].u.operand;
         JSValue srcValue = callFrame->r(src).jsValue();
-        if (srcValue != vPC[2].u.jsCell.get()) {
+        if (srcValue != ptr) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
index daceea6..965d6d9 100644 (file)
@@ -762,7 +762,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
 void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
 {
     unsigned src = currentInstruction[1].u.operand;
-    JSCell* ptr = currentInstruction[2].u.jsCell.get();
+    JSCell* ptr = currentInstruction[2].u.jsCell;
     unsigned target = currentInstruction[3].u.operand;
     
     emitGetVirtualRegister(src, regT0);
index bc0b2cb..9c3a923 100644 (file)
@@ -979,7 +979,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
 void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
 {
     unsigned src = currentInstruction[1].u.operand;
-    JSCell* ptr = currentInstruction[2].u.jsCell.get();
+    JSCell* ptr = currentInstruction[2].u.jsCell;
     unsigned target = currentInstruction[3].u.operand;
 
     emitLoad(src, regT1, regT0);
index 68f8dda..0f4e178 100644 (file)
@@ -979,7 +979,8 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
 
     // Track the stub we have created so that it will be deleted later.
     structure->ref();
-    prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
+    chain->ref();
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
     CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
index 2a47e5c..1eefe3d 100644 (file)
@@ -1007,7 +1007,8 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
     
     // Track the stub we have created so that it will be deleted later.
     structure->ref();
-    prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
+    chain->ref();
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
     
     // Finally patch the jump to slow case back in the hot path to jump here instead.
     CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
index e52c7c8..a38f01e 100644 (file)
@@ -1553,7 +1553,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
     return JSValue::encode(result);
 }
 
-static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSGlobalData& globalData, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
 {
     PolymorphicAccessStructureList* prototypeStructureList = 0;
     listIndex = 1;
@@ -1565,7 +1565,7 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSG
         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
         break;
     case access_get_by_id_chain:
-        prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
         stubInfo->stubRoutine = CodeLocationLabel();
         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
         break;
@@ -1653,7 +1653,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
         }
 
         int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
             JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
 
@@ -1663,7 +1663,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
     } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
         ASSERT(!baseValue.asCell()->structure()->isDictionary());
         int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
         
         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
             StructureChain* protoChain = structure->prototypeChain(callFrame);
index ab0e237..62cee37 100644 (file)
@@ -68,7 +68,6 @@ namespace JSC {
         friend class MarkedSpace;
         friend class MarkedBlock;
         friend class ScopeChainNode;
-        friend class StructureChain;
 
     private:
         explicit JSCell(Structure*);
index ee1829b..1d5fcf3 100644 (file)
@@ -184,7 +184,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
     programExecutableStructure = ProgramExecutable::createStructure(*this, jsNull());
     functionExecutableStructure = FunctionExecutable::createStructure(*this, jsNull());
     dummyMarkableCellStructure = JSCell::createDummyStructure(*this);
-    structureChainStructure = StructureChain::createStructure(*this, jsNull());
 
     interpreter = new Interpreter(*this);
     if (globalDataType == Default)
index 34ea75d..28bdade 100644 (file)
@@ -161,7 +161,6 @@ namespace JSC {
         RefPtr<Structure> programExecutableStructure;
         RefPtr<Structure> functionExecutableStructure;
         RefPtr<Structure> dummyMarkableCellStructure;
-        RefPtr<Structure> structureChainStructure;
 
         static void storeVPtrs();
         static JS_EXPORTDATA void* jsArrayVPtr;
index a2bbfbd..c9b0985 100644 (file)
@@ -88,8 +88,6 @@ static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s
 {
     if (s && s->storedPrototype())
         markStack.append(s->storedPrototypeSlot());
-    if (s && *s->cachedPrototypeChainSlot())
-        markStack.append(s->cachedPrototypeChainSlot());
 }
 
 JSGlobalObject::~JSGlobalObject()
index 04f63eb..5e01ebb 100644 (file)
@@ -28,7 +28,6 @@
 #include "JSWeakObjectMapRefInternal.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
-#include "StructureChain.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/RandomNumber.h>
@@ -363,7 +362,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(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure());
+            m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure());
         }
         return m_cachedPrototypeChain.get();
     }
index 578b3cf..fe01cb9 100644 (file)
@@ -814,10 +814,8 @@ inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
 ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
 {
     JSCell::markChildren(markStack);
-    
+
     markStack.append(m_structure->storedPrototypeSlot());
-    if (*m_structure->cachedPrototypeChainSlot())
-        markStack.append(m_structure->cachedPrototypeChainSlot());
     PropertyStorage storage = propertyStorage();
     size_t storageSize = m_structure->propertyStorageSize();
     markStack.appendValues(storage, storageSize);
index 6f31f99..0d759cf 100644 (file)
@@ -77,7 +77,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
             return jsPropertyNameIterator;
     }
 
-    jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain);
+    jsPropertyNameIterator->setCachedPrototypeChain(structureChain);
     jsPropertyNameIterator->setCachedStructure(o->structure());
     o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator);
     return jsPropertyNameIterator;
@@ -86,7 +86,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
 JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
 {
     JSValue identifier = m_jsStrings[i].get();
-    if (m_cachedStructure == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
+    if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
         return identifier;
 
     if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
@@ -97,8 +97,6 @@ JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
 void JSPropertyNameIterator::markChildren(MarkStack& markStack)
 {
     markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
-    if (m_cachedPrototypeChain)
-        markStack.append(&m_cachedPrototypeChain);
 }
 
 #if !ASSERT_DISABLED
index 499396c..8b007dd 100644 (file)
@@ -73,7 +73,7 @@ namespace JSC {
         }
         Structure* cachedStructure() { return m_cachedStructure.get(); }
 
-        void setCachedPrototypeChain(JSGlobalData& globalData, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(globalData, this, cachedPrototypeChain); }
+        void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
         StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
 
     private:
@@ -84,7 +84,7 @@ namespace JSC {
 #endif
 
         RefPtr<Structure> m_cachedStructure;
-        WriteBarrier<StructureChain> m_cachedPrototypeChain;
+        RefPtr<StructureChain> m_cachedPrototypeChain;
         uint32_t m_numCacheableSlots;
         uint32_t m_jsStringsSize;
         OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
index 7131917..dee4f34 100644 (file)
@@ -215,12 +215,12 @@ namespace JSC {
 
     template <typename T> inline void MarkStack::append(DeprecatedPtr<T>* slot)
     {
-        internalAppend(*slot->slot());
+        internalAppend(slot->get());
     }
     
     template <typename T> inline void MarkStack::append(WriteBarrierBase<T>* slot)
     {
-        internalAppend(*slot->slot());
+        internalAppend(slot->get());
     }
 
     ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
index c9f900a..6f7060b 100644 (file)
@@ -32,6 +32,7 @@
 #include "PropertyMapHashTable.h"
 #include "PropertyNameArray.h"
 #include "Protect.h"
+#include "StructureChain.h"
 #include "StructureTransitionTable.h"
 #include "JSTypeInfo.h"
 #include "UString.h"
@@ -45,7 +46,6 @@ namespace JSC {
     class MarkStack;
     class PropertyNameArray;
     class PropertyNameArrayData;
-    class StructureChain;
 
     struct ClassInfo;
 
@@ -107,7 +107,6 @@ namespace JSC {
         DeprecatedPtr<Unknown>* storedPrototypeSlot() { return &m_prototype; }
         JSValue prototypeForLookup(ExecState*) const;
         StructureChain* prototypeChain(ExecState*) const;
-        DeprecatedPtr<StructureChain>* cachedPrototypeChainSlot() { return &m_cachedPrototypeChain; }
 
         Structure* previousID() const { return m_previous.get(); }
 
@@ -211,7 +210,7 @@ namespace JSC {
         TypeInfo m_typeInfo;
 
         DeprecatedPtr<Unknown> m_prototype;
-        mutable DeprecatedPtr<StructureChain> m_cachedPrototypeChain;
+        mutable RefPtr<StructureChain> m_cachedPrototypeChain;
 
         RefPtr<Structure> m_previous;
         RefPtr<StringImpl> m_nameInPrevious;
index 4fa4a4b..e4523c3 100644 (file)
@@ -32,8 +32,7 @@
 
 namespace JSC {
 
-StructureChain::StructureChain(NonNullPassRefPtr<Structure> structure, Structure* head)
-    : JSCell(structure.releaseRef())
+StructureChain::StructureChain(Structure* head)
 {
     size_t size = 0;
     for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
index 88592dc..816b66d 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef StructureChain_h
 #define StructureChain_h
 
-#include "JSCell.h"
-
 #include <wtf/OwnArrayPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -37,16 +35,15 @@ namespace JSC {
 
     class Structure;
 
-    class StructureChain : public JSCell {
+    class StructureChain : public RefCounted<StructureChain> {
         friend class JIT;
 
     public:
-        static StructureChain* create(JSGlobalData& globalData, Structure* head) { return new (&globalData) StructureChain(globalData.structureChainStructure, head); }
+        static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
         RefPtr<Structure>* head() { return m_vector.get(); }
 
-        static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), 0, 0); }
     private:
-        StructureChain(NonNullPassRefPtr<Structure>, Structure* head);
+        StructureChain(Structure* head);
 
         OwnArrayPtr<RefPtr<Structure> > m_vector;
     };