Commit 5fca29f7 authored by oliver@apple.com's avatar oliver@apple.com

Stack overflow crash in JavaScript garbage collector mark pass

https://bugs.webkit.org/show_bug.cgi?id=12216

Reviewed by Gavin Barraclough and Sam Weinig

Make the GC mark phase iterative by using an explicit mark stack.
To do this marking any single object is performed in multiple stages
  * The object is appended to the MarkStack, this sets the marked
    bit for the object using the new markDirect() function, and then
    returns
  * When the MarkStack is drain()ed the object is popped off the stack
    and markChildren(MarkStack&) is called on the object to collect
    all of its children.  drain() then repeats until the stack is empty.

Additionally I renamed a number of methods from 'mark' to 'markAggregate'
in order to make it more clear that marking of those object was not
going to result in an actual recursive mark.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@47022 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6061b045
2009-08-07 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
Stack overflow crash in JavaScript garbage collector mark pass
https://bugs.webkit.org/show_bug.cgi?id=12216
Make the GC mark phase iterative by using an explicit mark stack.
To do this marking any single object is performed in multiple stages
* The object is appended to the MarkStack, this sets the marked
bit for the object using the new markDirect() function, and then
returns
* When the MarkStack is drain()ed the object is popped off the stack
and markChildren(MarkStack&) is called on the object to collect
all of its children. drain() then repeats until the stack is empty.
Additionally I renamed a number of methods from 'mark' to 'markAggregate'
in order to make it more clear that marking of those object was not
going to result in an actual recursive mark.
* GNUmakefile.am
* JavaScriptCore.exp:
* JavaScriptCore.gypi:
* JavaScriptCore.pri:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::markAggregate):
* bytecode/CodeBlock.h:
* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::markAggregate):
* debugger/DebuggerActivation.cpp:
(JSC::DebuggerActivation::markChildren):
* debugger/DebuggerActivation.h:
* interpreter/Register.h:
* interpreter/RegisterFile.h:
(JSC::RegisterFile::markGlobals):
(JSC::RegisterFile::markCallFrames):
* parser/Nodes.cpp:
(JSC::ScopeNodeData::markAggregate):
(JSC::EvalNode::markAggregate):
(JSC::FunctionBodyNode::markAggregate):
* parser/Nodes.h:
(JSC::ScopeNode::markAggregate):
* runtime/ArgList.cpp:
(JSC::MarkedArgumentBuffer::markLists):
* runtime/ArgList.h:
* runtime/Arguments.cpp:
(JSC::Arguments::markChildren):
* runtime/Arguments.h:
* runtime/Collector.cpp:
(JSC::Heap::markConservatively):
(JSC::Heap::markCurrentThreadConservativelyInternal):
(JSC::Heap::markCurrentThreadConservatively):
(JSC::Heap::markOtherThreadConservatively):
(JSC::Heap::markStackObjectsConservatively):
(JSC::Heap::markProtectedObjects):
(JSC::Heap::collect):
* runtime/Collector.h:
* runtime/GetterSetter.cpp:
(JSC::GetterSetter::markChildren):
* runtime/GetterSetter.h:
(JSC::GetterSetter::GetterSetter):
(JSC::GetterSetter::createStructure):
* runtime/GlobalEvalFunction.cpp:
(JSC::GlobalEvalFunction::markChildren):
* runtime/GlobalEvalFunction.h:
* runtime/JSActivation.cpp:
(JSC::JSActivation::markChildren):
* runtime/JSActivation.h:
* runtime/JSArray.cpp:
(JSC::JSArray::markChildren):
* runtime/JSArray.h:
* runtime/JSCell.h:
(JSC::JSCell::markCellDirect):
(JSC::JSCell::markChildren):
(JSC::JSValue::markDirect):
(JSC::JSValue::markChildren):
(JSC::JSValue::hasChildren):
(JSC::MarkStack::append):
(JSC::MarkStack::drain):
* runtime/JSFunction.cpp:
(JSC::JSFunction::markChildren):
* runtime/JSFunction.h:
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
* runtime/JSGlobalObject.cpp:
(JSC::markIfNeeded):
(JSC::JSGlobalObject::markChildren):
* runtime/JSGlobalObject.h:
* runtime/JSNotAnObject.cpp:
(JSC::JSNotAnObject::markChildren):
* runtime/JSNotAnObject.h:
* runtime/JSONObject.cpp:
(JSC::Stringifier::markAggregate):
(JSC::JSONObject::markStringifiers):
* runtime/JSONObject.h:
* runtime/JSObject.cpp:
(JSC::JSObject::markChildren):
(JSC::JSObject::defineGetter):
(JSC::JSObject::defineSetter):
* runtime/JSObject.h:
* runtime/JSPropertyNameIterator.cpp:
(JSC::JSPropertyNameIterator::markChildren):
* runtime/JSPropertyNameIterator.h:
(JSC::JSPropertyNameIterator::createStructure):
(JSC::JSPropertyNameIterator::JSPropertyNameIterator):
(JSC::JSPropertyNameIterator::create):
* runtime/JSStaticScopeObject.cpp:
(JSC::JSStaticScopeObject::markChildren):
* runtime/JSStaticScopeObject.h:
* runtime/JSType.h:
(JSC::):
* runtime/JSValue.h:
* runtime/JSWrapperObject.cpp:
(JSC::JSWrapperObject::markChildren):
* runtime/JSWrapperObject.h:
* runtime/MarkStack.cpp: Added.
(JSC::MarkStack::compact):
* runtime/MarkStack.h: Added.
(JSC::):
(JSC::MarkStack::MarkStack):
(JSC::MarkStack::append):
(JSC::MarkStack::appendValues):
(JSC::MarkStack::~MarkStack):
(JSC::MarkStack::MarkSet::MarkSet):
(JSC::MarkStack::pageSize):
MarkStackArray is a non-shrinking, mmap-based vector type
used for storing objects to be marked.
(JSC::MarkStack::MarkStackArray::MarkStackArray):
(JSC::MarkStack::MarkStackArray::~MarkStackArray):
(JSC::MarkStack::MarkStackArray::expand):
(JSC::MarkStack::MarkStackArray::append):
(JSC::MarkStack::MarkStackArray::removeLast):
(JSC::MarkStack::MarkStackArray::isEmpty):
(JSC::MarkStack::MarkStackArray::size):
(JSC::MarkStack::MarkStackArray::shrinkAllocation):
* runtime/MarkStackPosix.cpp: Added.
(JSC::MarkStack::allocateStack):
(JSC::MarkStack::releaseStack):
* runtime/MarkStackWin.cpp: Added.
(JSC::MarkStack::allocateStack):
(JSC::MarkStack::releaseStack):
* runtime/ScopeChain.h:
* runtime/ScopeChainMark.h:
(JSC::ScopeChain::markAggregate):
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::mark):
* runtime/Structure.h:
(JSC::Structure::markAggregate):
2009-08-10 Mark Rowe <mrowe@apple.com>
Reviewed by Darin Adler.
......
......@@ -191,6 +191,9 @@ javascriptcore_sources += \
JavaScriptCore/runtime/JSPropertyNameIterator.h \
JavaScriptCore/runtime/LiteralParser.cpp \
JavaScriptCore/runtime/LiteralParser.h \
JavaScriptCore/runtime/MarkStack.cpp \
JavaScriptCore/runtime/MarkStack.h \
JavaScriptCore/runtime/MarkStackPosix.cpp \
JavaScriptCore/runtime/SmallStrings.cpp \
JavaScriptCore/runtime/SmallStrings.h \
JavaScriptCore/runtime/Structure.cpp \
......@@ -436,6 +439,9 @@ javascriptcore_sources += \
JavaScriptCore/runtime/JSWrapperObject.h \
JavaScriptCore/runtime/Lookup.cpp \
JavaScriptCore/runtime/Lookup.h \
JavaScriptCore/runtime/MarkStack.cpp \
JavaScriptCore/runtime/MarkStack.h \
JavaScriptCore/runtime/MarkStackWin.cpp \
JavaScriptCore/runtime/MathObject.cpp \
JavaScriptCore/runtime/MathObject.h \
JavaScriptCore/runtime/NativeErrorConstructor.cpp \
......
......@@ -131,17 +131,17 @@ __ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
__ZN3JSC14JSGlobalObject10globalExecEv
__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject12markChildrenERNS_9MarkStackE
__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject4markEv
__ZN3JSC14JSGlobalObjectD2Ev
__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
__ZN3JSC14SamplingThread4stopEv
__ZN3JSC14SamplingThread5startEj
__ZN3JSC14TimeoutChecker5resetEv
__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
__ZN3JSC15JSWrapperObject4markEv
__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
__ZN3JSC15toInt32SlowCaseEdRb
__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
__ZN3JSC16FunctionBodyNode14copyParametersEv
......@@ -236,6 +236,7 @@ __ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject12markChildrenERNS_9MarkStackE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
__ZN3JSC8JSObject15unwrappedObjectEv
......@@ -251,7 +252,6 @@ __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE
__ZN3JSC8JSObject23allocatePropertyStorageEmm
__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
__ZN3JSC8JSObject4markEv
__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC8Profiler8profilerEv
......@@ -259,6 +259,9 @@ __ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
__ZN3JSC9CodeBlockD1Ev
__ZN3JSC9CodeBlockD2Ev
__ZN3JSC9MarkStack10s_pageSizeE
__ZN3JSC9MarkStack12releaseStackEPvm
__ZN3JSC9MarkStack13allocateStackEm
__ZN3JSC9Structure17stopIgnoringLeaksEv
__ZN3JSC9Structure18startIgnoringLeaksEv
__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
......@@ -326,6 +329,7 @@ __ZNK3JSC12DateInstance7getTimeERdRi
__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
__ZNK3JSC16FunctionBodyNode14isHostFunctionEv
__ZNK3JSC16InternalFunction9classInfoEv
__ZNK3JSC16JSVariableObject16isVariableObjectEv
......
......@@ -265,6 +265,9 @@
'runtime/LiteralParser.h',
'runtime/Lookup.cpp',
'runtime/Lookup.h',
'runtime/MarkStack.cpp',
'runtime/MarkStack.h',
'runtime/MarkStackWin.cpp',
'runtime/MathObject.cpp',
'runtime/MathObject.h',
'runtime/NativeErrorConstructor.cpp',
......
......@@ -98,6 +98,8 @@ SOURCES += \
runtime/JSNotAnObject.cpp \
runtime/JSONObject.cpp \
runtime/LiteralParser.cpp \
runtime/MarkStack.cpp \
runtime/MarkStackPosix.cpp \
runtime/TimeoutChecker.cpp \
bytecode/CodeBlock.cpp \
bytecode/StructureStubInfo.cpp \
......
......@@ -883,6 +883,18 @@
RelativePath="..\..\runtime\Lookup.h"
>
</File>
<File
RelativePath="..\..\runtime\MarkStack.h"
>
</File>
<File
RelativePath="..\..\runtime\MarkStack.cpp"
>
</File>
<File
RelativePath="..\..\runtime\MarkStackWin.cpp"
>
</File>
<File
RelativePath="..\..\runtime\MathObject.cpp"
>
......
......@@ -196,14 +196,17 @@
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74B3498102A5F8E0032AB98 /* MarkStack.cpp */; };
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76EE6590FAE59D5003F069A /* NativeFunctionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7795590101A74D500114E55 /* MarkStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A779558F101A74D500114E55 /* MarkStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */; };
A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A791EF260F11E07900AE1F68 /* JSByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A791EF270F11E07900AE1F68 /* JSByteArray.cpp */; };
A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */; };
A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */; };
A7C530E4102A3813005BC741 /* MarkStackPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */; };
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E2EA690FB460CF00601F06 /* LiteralParser.h */; };
A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */; };
A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
......@@ -738,7 +741,9 @@
A72701B30DADE94900E548D7 /* ExceptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHelpers.h; sourceTree = "<group>"; };
A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; };
A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; };
A74B3498102A5F8E0032AB98 /* MarkStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkStack.cpp; sourceTree = "<group>"; };
A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeFunctionWrapper.h; sourceTree = "<group>"; };
A779558F101A74D500114E55 /* MarkStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStack.h; sourceTree = "<group>"; };
A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorPosix.cpp; sourceTree = "<group>"; };
A791EF260F11E07900AE1F68 /* JSByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSByteArray.h; sourceTree = "<group>"; };
A791EF270F11E07900AE1F68 /* JSByteArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSByteArray.cpp; sourceTree = "<group>"; };
......@@ -746,6 +751,7 @@
A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteArray.h; sourceTree = "<group>"; };
A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkStackPosix.cpp; sourceTree = "<group>"; };
A7E2EA690FB460CF00601F06 /* LiteralParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralParser.h; sourceTree = "<group>"; };
A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralParser.cpp; sourceTree = "<group>"; };
A7E42C180E3938830065A544 /* JSStaticScopeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStaticScopeObject.h; sourceTree = "<group>"; };
......@@ -1490,6 +1496,9 @@
6507D2970E871E4A00D7D896 /* TypeInfo.h */,
F692A8850255597D01FF60F7 /* UString.cpp */,
F692A8860255597D01FF60F7 /* UString.h */,
A779558F101A74D500114E55 /* MarkStack.h */,
A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */,
A74B3498102A5F8E0032AB98 /* MarkStack.cpp */,
);
path = runtime;
sourceTree = "<group>";
......@@ -1892,6 +1901,7 @@
1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */,
1429DABF0ED263E700B89619 /* WRECParser.h in Headers */,
9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
A7795590101A74D500114E55 /* MarkStack.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -2258,6 +2268,8 @@
1429DA820ED2482900B89619 /* WRECFunctors.cpp in Sources */,
1429DAE10ED2645B00B89619 /* WRECGenerator.cpp in Sources */,
1429DAC00ED263E700B89619 /* WRECParser.cpp in Sources */,
A7C530E4102A3813005BC741 /* MarkStackPosix.cpp in Sources */,
A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -1428,20 +1428,21 @@ void CodeBlock::refStructures(Instruction* vPC) const
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic));
}
void CodeBlock::mark()
void CodeBlock::markAggregate(MarkStack& markStack)
{
for (size_t i = 0; i < m_constantRegisters.size(); ++i)
for (size_t i = 0; i < m_constantRegisters.size(); ++i) {
if (!m_constantRegisters[i].marked())
m_constantRegisters[i].mark();
markStack.append(m_constantRegisters[i].jsValue());
}
for (size_t i = 0; i < m_functionExpressions.size(); ++i)
m_functionExpressions[i]->body()->mark();
m_functionExpressions[i]->body()->markAggregate(markStack);
if (m_rareData) {
for (size_t i = 0; i < m_rareData->m_functions.size(); ++i)
m_rareData->m_functions[i]->body()->mark();
m_rareData->m_functions[i]->body()->markAggregate(markStack);
m_rareData->m_evalCodeCache.mark();
m_rareData->m_evalCodeCache.markAggregate(markStack);
}
}
......
......@@ -255,7 +255,7 @@ namespace JSC {
CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
~CodeBlock();
void mark();
void markAggregate(MarkStack&);
void refStructures(Instruction* vPC) const;
void derefStructures(Instruction* vPC) const;
#if ENABLE(JIT_OPTIMIZE_CALL)
......
......@@ -68,11 +68,11 @@ namespace JSC {
bool isEmpty() const { return m_cacheMap.isEmpty(); }
void mark()
void markAggregate(MarkStack& markStack)
{
EvalCacheMap::iterator end = m_cacheMap.end();
for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
ptr->second->mark();
ptr->second->markAggregate(markStack);
}
private:
static const int maxCacheableSourceLength = 256;
......
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -38,11 +38,12 @@ DebuggerActivation::DebuggerActivation(JSObject* activation)
m_activation = static_cast<JSActivation*>(activation);
}
void DebuggerActivation::mark()
void DebuggerActivation::markChildren(MarkStack& markStack)
{
JSObject::mark();
if (m_activation && !m_activation->marked())
m_activation->mark();
JSObject::markChildren(markStack);
if (m_activation)
markStack.append(m_activation);
}
UString DebuggerActivation::className() const
......
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -36,7 +36,7 @@ namespace JSC {
public:
DebuggerActivation(JSObject*);
virtual void mark();
virtual void markChildren(MarkStack&);
virtual UString className() const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
......
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -56,7 +56,7 @@ namespace JSC {
JSValue jsValue() const;
bool marked() const;
void mark();
void markChildren(MarkStack&);
Register(JSActivation*);
Register(CallFrame*);
......@@ -120,11 +120,6 @@ namespace JSC {
return jsValue().marked();
}
ALWAYS_INLINE void Register::mark()
{
jsValue().mark();
}
// Interpreter functions
ALWAYS_INLINE Register::Register(JSActivation* activation)
......
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -136,8 +136,8 @@ namespace JSC {
Register* lastGlobal() const { return m_start - m_numGlobals; }
void markGlobals(Heap* heap) { heap->markConservatively(lastGlobal(), m_start); }
void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); }
void markGlobals(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, lastGlobal(), m_start); }
void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, m_start, m_end); }
private:
void releaseExcessCapacity();
......
......@@ -1818,14 +1818,14 @@ ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarSt
children->releaseContentsIntoVector(m_children);
}
void ScopeNodeData::mark()
void ScopeNodeData::markAggregate(MarkStack& markStack)
{
FunctionStack::iterator end = m_functionStack.end();
for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
FunctionBodyNode* body = (*ptr)->body();
if (!body->isGenerated())
continue;
body->generatedBytecode().mark();
body->generatedBytecode().markAggregate(markStack);
}
}
......@@ -1972,10 +1972,10 @@ EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeCh
return *m_code;
}
void EvalNode::mark()
void EvalNode::markAggregate(MarkStack& markStack)
{
// We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
data()->mark();
data()->markAggregate(markStack);
}
#if ENABLE(JIT)
......@@ -2030,10 +2030,10 @@ void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCou
m_parameterCount = parameterCount;
}
void FunctionBodyNode::mark()
void FunctionBodyNode::markAggregate(MarkStack& markStack)
{
if (m_code)
m_code->mark();
m_code->markAggregate(markStack);
}
#if ENABLE(JIT)
......
......@@ -1390,7 +1390,7 @@ namespace JSC {
int m_numConstants;
StatementVector m_children;
void mark();
void markAggregate(MarkStack&);
};
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
......@@ -1436,7 +1436,7 @@ namespace JSC {
return m_data->m_numConstants + 2;
}
virtual void mark() { }
virtual void markAggregate(MarkStack&) { }
#if ENABLE(JIT)
JITCode& generatedJITCode()
......@@ -1515,7 +1515,7 @@ namespace JSC {
EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
virtual void mark();
virtual void markAggregate(MarkStack&);
#if ENABLE(JIT)
JITCode& jitCode(ScopeChainNode* scopeChain)
......@@ -1563,7 +1563,7 @@ namespace JSC {
bool isHostFunction() const;
virtual void mark();
virtual void markAggregate(MarkStack&);
void finishParsing(const SourceCode&, ParameterNode*);
void finishParsing(Identifier* parameters, size_t parameterCount);
......
/*
* Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -37,16 +37,12 @@ void ArgList::getSlice(int startIndex, ArgList& result) const
result = ArgList(m_args + startIndex, m_argCount - startIndex);
}
void MarkedArgumentBuffer::markLists(ListSet& markSet)
void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
MarkedArgumentBuffer* list = *it;
iterator end2 = list->end();
for (iterator it2 = list->begin(); it2 != end2; ++it2)
if (!(*it2).marked())
(*it2).mark();
markStack.appendValues(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size);
}
}
......
......@@ -135,7 +135,7 @@ namespace JSC {
const_iterator begin() const { return m_buffer; }
const_iterator end() const { return m_buffer + m_size; }
static void markLists(ListSet&);
static void markLists(MarkStack&, ListSet&);
private:
void slowAppend(JSValue);
......
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
*
......@@ -43,30 +43,22 @@ Arguments::~Arguments()
delete [] d->extraArguments;
}
void Arguments::mark()
void Arguments::markChildren(MarkStack& markStack)
{
JSObject::mark();
JSObject::markChildren(markStack);
if (d->registerArray) {
for (unsigned i = 0; i < d->numParameters; ++i) {
if (!d->registerArray[i].marked())
d->registerArray[i].mark();
}
}
if (d->registerArray)
markStack.appendValues(reinterpret_cast<JSValue*>(d->registerArray.get()), d->numParameters);
if (d->extraArguments) {
unsigned numExtraArguments = d->numArguments - d->numParameters;
for (unsigned i = 0; i < numExtraArguments; ++i) {
if (!d->extraArguments[i].marked())
d->extraArguments[i].mark();
}
markStack.appendValues(reinterpret_cast<JSValue*>(d->extraArguments), numExtraArguments);
}
if (!d->callee->marked())