summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-18 13:36:51 +0100
committerSteve Block <steveblock@google.com>2011-05-24 15:38:28 +0100
commit2fc2651226baac27029e38c9d6ef883fa32084db (patch)
treee396d4bf89dcce6ed02071be66212495b1df1dec /Source/JavaScriptCore/runtime
parentb3725cedeb43722b3b175aaeff70552e562d2c94 (diff)
downloadexternal_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz
external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h29
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h8
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/CollectorHeapIterator.h140
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.cpp65
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.h80
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallback.h10
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h14
-rw-r--r--Source/JavaScriptCore/runtime/GlobalEvalFunction.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/GlobalEvalFunction.h4
-rw-r--r--Source/JavaScriptCore/runtime/Heap.cpp187
-rw-r--r--Source/JavaScriptCore/runtime/Heap.h115
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSAPIValueWrapper.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp126
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h24
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h56
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp53
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h9
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp240
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h125
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp32
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp34
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h130
-rw-r--r--Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h18
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h18
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.h4
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.h36
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.cpp84
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.h177
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.cpp337
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.h206
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.h1
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h6
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.h50
-rw-r--r--Source/JavaScriptCore/runtime/PrototypeFunction.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/PutPropertySlot.h8
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.h10
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChainMark.h2
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.h11
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h7
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h60
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h165
93 files changed, 1632 insertions, 1436 deletions
diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp
index ab2b5d7..a862ea0 100644
--- a/Source/JavaScriptCore/runtime/ArgList.cpp
+++ b/Source/JavaScriptCore/runtime/ArgList.cpp
@@ -42,7 +42,7 @@ void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet)
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
MarkedArgumentBuffer* list = *it;
- markStack.appendValues(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size);
+ markStack.deprecatedAppendValues(list->m_buffer, list->m_size);
}
}
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index 39886a8..305b247 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -48,17 +48,17 @@ void Arguments::markChildren(MarkStack& markStack)
JSObject::markChildren(markStack);
if (d->registerArray)
- markStack.appendValues(reinterpret_cast<JSValue*>(d->registerArray.get()), d->numParameters);
+ markStack.deprecatedAppendValues(d->registerArray.get(), d->numParameters);
if (d->extraArguments) {
unsigned numExtraArguments = d->numArguments - d->numParameters;
- markStack.appendValues(reinterpret_cast<JSValue*>(d->extraArguments), numExtraArguments);
+ markStack.deprecatedAppendValues(d->extraArguments, numExtraArguments);
}
- markStack.append(d->callee);
+ markStack.append(&d->callee);
if (d->activation)
- markStack.append(d->activation);
+ markStack.append(&d->activation);
}
void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
@@ -197,7 +197,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
if (!d->isStrictMode) {
- slot.setValue(d->callee);
+ slot.setValue(d->callee.get());
return true;
}
createStrictModeCalleeIfNecessary(exec);
@@ -228,7 +228,7 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
if (!d->isStrictMode) {
- descriptor.setDescriptor(d->callee, DontEnum);
+ descriptor.setDescriptor(d->callee.get(), DontEnum);
return true;
}
createStrictModeCalleeIfNecessary(exec);
@@ -253,7 +253,7 @@ void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& property
JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
-void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot)
+void Arguments::put(ExecState* exec, unsigned i, JSValue value)
{
if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
if (i < d->numParameters)
@@ -263,6 +263,7 @@ void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot&
return;
}
+ PutPropertySlot slot;
JSObject::put(exec, Identifier(exec, UString::number(i)), value, slot);
}
@@ -280,14 +281,14 @@ void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue val
if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
d->overrodeLength = true;
- putDirect(propertyName, value, DontEnum);
+ putDirect(exec->globalData(), propertyName, value, DontEnum);
return;
}
if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
if (!d->isStrictMode) {
d->overrodeCallee = true;
- putDirect(propertyName, value, DontEnum);
+ putDirect(exec->globalData(), propertyName, value, DontEnum);
return;
}
createStrictModeCalleeIfNecessary(exec);
@@ -303,7 +304,7 @@ bool Arguments::deleteProperty(ExecState* exec, unsigned i)
{
if (i < d->numArguments) {
if (!d->deletedArguments) {
- d->deletedArguments.set(new bool[d->numArguments]);
+ d->deletedArguments = adoptArrayPtr(new bool[d->numArguments]);
memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
}
if (!d->deletedArguments[i]) {
@@ -321,7 +322,7 @@ bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
unsigned i = propertyName.toArrayIndex(isArrayIndex);
if (isArrayIndex && i < d->numArguments) {
if (!d->deletedArguments) {
- d->deletedArguments.set(new bool[d->numArguments]);
+ d->deletedArguments = adoptArrayPtr(new bool[d->numArguments]);
memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
}
if (!d->deletedArguments[i]) {
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index fe900a2..658538b 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -37,7 +37,7 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(ArgumentsData); WTF_MAKE_FAST_ALLOCATED;
public:
ArgumentsData() { }
- JSActivation* activation;
+ WriteBarrier<JSActivation> activation;
unsigned numParameters;
ptrdiff_t firstParameterIndex;
@@ -50,7 +50,7 @@ namespace JSC {
OwnArrayPtr<bool> deletedArguments;
Register extraArgumentsFixedBuffer[4];
- JSFunction* callee;
+ WriteBarrier<JSFunction> callee;
bool overrodeLength : 1;
bool overrodeCallee : 1;
bool overrodeCaller : 1;
@@ -86,9 +86,9 @@ namespace JSC {
void copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize);
void copyRegisters();
bool isTornOff() const { return d->registerArray; }
- void setActivation(JSActivation* activation)
+ void setActivation(JSGlobalData& globalData, JSActivation* activation)
{
- d->activation = activation;
+ d->activation.set(globalData, this, activation);
d->registers = &activation->registerAt(0);
}
@@ -107,7 +107,7 @@ namespace JSC {
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValue);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
void createStrictModeCallerIfNecessary(ExecState*);
@@ -158,7 +158,6 @@ namespace JSC {
d->firstParameterIndex = firstParameterIndex;
d->numArguments = numArguments;
- d->activation = 0;
d->registers = callFrame->registers();
Register* extraArguments;
@@ -176,7 +175,7 @@ namespace JSC {
d->extraArguments = extraArguments;
- d->callee = callee;
+ d->callee.set(callFrame->globalData(), this, callee);
d->overrodeLength = false;
d->overrodeCallee = false;
d->overrodeCaller = false;
@@ -195,7 +194,6 @@ namespace JSC {
d->numParameters = 0;
d->numArguments = numArguments;
- d->activation = 0;
Register* extraArguments;
if (numArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register))
@@ -209,7 +207,7 @@ namespace JSC {
d->extraArguments = extraArguments;
- d->callee = asFunction(callFrame->callee());
+ d->callee.set(callFrame->globalData(), this, asFunction(callFrame->callee()));
d->overrodeLength = false;
d->overrodeCallee = false;
d->overrodeCaller = false;
@@ -228,10 +226,10 @@ namespace JSC {
int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = d->numParameters;
- Register* registerArray = new Register[registerArraySize];
- memcpy(registerArray, d->registers - registerOffset, registerArraySize * sizeof(Register));
- d->registerArray.set(registerArray);
- d->registers = registerArray + registerOffset;
+ OwnArrayPtr<Register> registerArray = adoptArrayPtr(new Register[registerArraySize]);
+ memcpy(registerArray.get(), d->registers - registerOffset, registerArraySize * sizeof(Register));
+ d->registers = registerArray.get() + registerOffset;
+ d->registerArray = registerArray.release();
}
// This JSActivation function is defined here so it can get at Arguments::setRegisters.
@@ -249,8 +247,9 @@ namespace JSC {
int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
- Register* registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize);
- setRegisters(registerArray + registerOffset, registerArray);
+ OwnArrayPtr<Register> registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize);
+ Register* registers = registerArray.get() + registerOffset;
+ setRegisters(registers, registerArray.release());
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index 632d466..5d0adbd 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -42,10 +42,10 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
- putDirectWithoutTransition(exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
// ES5
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum);
@@ -62,7 +62,7 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi
}
// otherwise the array is constructed with the arguments in it
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), args);
+ return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), args);
}
static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 7615ffc..70c0d06 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -117,7 +117,7 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
: JSArray(structure)
{
- putAnonymousValue(0, globalObject);
+ putAnonymousValue(globalObject->globalData(), 0, globalObject);
}
bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -545,9 +545,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
JSArray* resObj = new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact);
JSValue result = resObj;
-
+ JSGlobalData& globalData = exec->globalData();
for (unsigned k = 0; k < deleteCount; k++)
- resObj->uncheckedSetIndex(k, getProperty(exec, thisObj, k + begin));
+ resObj->uncheckedSetIndex(globalData, k, getProperty(exec, thisObj, k + begin));
resObj->setLength(deleteCount);
diff --git a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index db2d1d7..0f6a646 100644
--- a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -34,8 +34,9 @@ namespace JSC {
class BatchedTransitionOptimizer {
WTF_MAKE_NONCOPYABLE(BatchedTransitionOptimizer);
public:
- BatchedTransitionOptimizer(JSObject* object)
- : m_object(object)
+ BatchedTransitionOptimizer(JSGlobalData& globalData, JSObject* object)
+ : m_globalData(&globalData)
+ , m_object(object)
{
if (!m_object->structure()->isDictionary())
m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure()));
@@ -43,10 +44,11 @@ namespace JSC {
~BatchedTransitionOptimizer()
{
- m_object->flattenDictionaryObject();
+ m_object->flattenDictionaryObject(*m_globalData);
}
private:
+ JSGlobalData* m_globalData;
JSObject* m_object;
};
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 0167e03..21ef5bb 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -31,17 +31,17 @@ ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, booleanPrototype->classInfo()->className))
{
- putDirectWithoutTransition(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
}
// ECMA 15.6.2
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
- obj->setInternalValue(jsBoolean(args.at(0).toBoolean(exec)));
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -71,8 +71,8 @@ CallType BooleanConstructor::getCallData(CallData& callData)
JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
- obj->setInternalValue(immediateBooleanValue);
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ obj->setInternalValue(exec->globalData(), immediateBooleanValue);
return obj;
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index c9b3846..71ff2d2 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp
@@ -27,8 +27,8 @@ ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 };
-BooleanObject::BooleanObject(NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+BooleanObject::BooleanObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(globalData, structure)
{
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index 4b02acb..ff10ef6 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -27,7 +27,7 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
public:
- explicit BooleanObject(NonNullPassRefPtr<Structure>);
+ explicit BooleanObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure>);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
index 7ffd095..54d621c 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -39,9 +39,9 @@ static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*);
// ECMA 15.6.4
BooleanPrototype::BooleanPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
- : BooleanObject(structure)
+ : BooleanObject(exec->globalData(), structure)
{
- setInternalValue(jsBoolean(false));
+ setInternalValue(exec->globalData(), jsBoolean(false));
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
diff --git a/Source/JavaScriptCore/runtime/CollectorHeapIterator.h b/Source/JavaScriptCore/runtime/CollectorHeapIterator.h
deleted file mode 100644
index 7229d77..0000000
--- a/Source/JavaScriptCore/runtime/CollectorHeapIterator.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Heap.h"
-
-#ifndef CollectorHeapIterator_h
-#define CollectorHeapIterator_h
-
-namespace JSC {
-
- class CollectorHeapIterator {
- public:
- bool operator!=(const CollectorHeapIterator& other);
- JSCell* operator*() const;
-
- protected:
- CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell);
- void advance(size_t max);
-
- CollectorHeap& m_heap;
- size_t m_block;
- size_t m_cell;
- };
-
- class LiveObjectIterator : public CollectorHeapIterator {
- public:
- LiveObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
- LiveObjectIterator& operator++();
- };
-
- class DeadObjectIterator : public CollectorHeapIterator {
- public:
- DeadObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
- DeadObjectIterator& operator++();
- };
-
- class ObjectIterator : public CollectorHeapIterator {
- public:
- ObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
- ObjectIterator& operator++();
- };
-
- inline CollectorHeapIterator::CollectorHeapIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
- : m_heap(heap)
- , m_block(startBlock)
- , m_cell(startCell)
- {
- }
-
- inline bool CollectorHeapIterator::operator!=(const CollectorHeapIterator& other)
- {
- return m_block != other.m_block || m_cell != other.m_cell;
- }
-
- inline JSCell* CollectorHeapIterator::operator*() const
- {
- return reinterpret_cast<JSCell*>(&m_heap.collectorBlock(m_block)->cells[m_cell]);
- }
-
- // Iterators advance up to the next-to-last -- and not the last -- cell in a
- // block, since the last cell is a dummy sentinel.
- inline void CollectorHeapIterator::advance(size_t max)
- {
- ++m_cell;
- if (m_cell == max) {
- m_cell = 0;
- ++m_block;
- }
- }
-
- inline LiveObjectIterator::LiveObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
- : CollectorHeapIterator(heap, startBlock, startCell - 1)
- {
- ++(*this);
- }
-
- inline LiveObjectIterator& LiveObjectIterator::operator++()
- {
- advance(HeapConstants::cellsPerBlock - 1);
- if (m_block < m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell < m_heap.nextCell))
- return *this;
-
- while (m_block < m_heap.usedBlocks && !m_heap.collectorBlock(m_block)->marked.get(m_cell))
- advance(HeapConstants::cellsPerBlock - 1);
- return *this;
- }
-
- inline DeadObjectIterator::DeadObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
- : CollectorHeapIterator(heap, startBlock, startCell - 1)
- {
- ++(*this);
- }
-
- inline DeadObjectIterator& DeadObjectIterator::operator++()
- {
- do {
- advance(HeapConstants::cellsPerBlock - 1);
- ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell));
- } while (m_block < m_heap.usedBlocks && m_heap.collectorBlock(m_block)->marked.get(m_cell));
- return *this;
- }
-
- inline ObjectIterator::ObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
- : CollectorHeapIterator(heap, startBlock, startCell - 1)
- {
- ++(*this);
- }
-
- inline ObjectIterator& ObjectIterator::operator++()
- {
- advance(HeapConstants::cellsPerBlock - 1);
- return *this;
- }
-
-} // namespace JSC
-
-#endif // CollectorHeapIterator_h
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.cpp b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
new file mode 100644
index 0000000..bc8bd6d
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ConservativeSet.h"
+
+namespace JSC {
+
+inline bool isPointerAligned(void* p)
+{
+ return !((intptr_t)(p) & (sizeof(char*) - 1));
+}
+
+void ConservativeSet::grow()
+{
+ size_t newCapacity = m_capacity == inlineCapacity ? nonInlineCapacity : m_capacity * 2;
+ DeprecatedPtr<JSCell>* newSet = static_cast<DeprecatedPtr<JSCell>*>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));
+ memcpy(newSet, m_set, m_size * sizeof(JSCell*));
+ if (m_set != m_inlineSet)
+ OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(JSCell*));
+ m_capacity = newCapacity;
+ m_set = newSet;
+}
+
+void ConservativeSet::add(void* begin, void* end)
+{
+ ASSERT(begin <= end);
+ ASSERT((static_cast<char*>(end) - static_cast<char*>(begin)) < 0x1000000);
+ ASSERT(isPointerAligned(begin));
+ ASSERT(isPointerAligned(end));
+
+ for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it) {
+ if (!m_heap->contains(*it))
+ continue;
+
+ if (m_size == m_capacity)
+ grow();
+
+ m_set[m_size++] = reinterpret_cast<JSCell*>(*it);
+ }
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.h b/Source/JavaScriptCore/runtime/ConservativeSet.h
new file mode 100644
index 0000000..e7c2c4a
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ConservativeSet_h
+#define ConservativeSet_h
+
+#include "Heap.h"
+#include "MarkStack.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class JSCell;
+
+class ConservativeSet {
+public:
+ ConservativeSet(Heap*);
+ ~ConservativeSet();
+
+ void add(void* begin, void* end);
+ void mark(MarkStack&);
+
+private:
+ static const size_t inlineCapacity = 128;
+ static const size_t nonInlineCapacity = 8192 / sizeof(JSCell*);
+
+ void grow();
+
+ Heap* m_heap;
+ DeprecatedPtr<JSCell>* m_set;
+ size_t m_size;
+ size_t m_capacity;
+ DeprecatedPtr<JSCell> m_inlineSet[inlineCapacity];
+};
+
+inline ConservativeSet::ConservativeSet(Heap* heap)
+ : m_heap(heap)
+ , m_set(m_inlineSet)
+ , m_size(0)
+ , m_capacity(inlineCapacity)
+{
+}
+
+inline ConservativeSet::~ConservativeSet()
+{
+ if (m_set != m_inlineSet)
+ OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(DeprecatedPtr<JSCell>*));
+}
+
+inline void ConservativeSet::mark(MarkStack& markStack)
+{
+ for (size_t i = 0; i < m_size; ++i)
+ markStack.append(&m_set[i]);
+}
+
+} // namespace JSC
+
+#endif // ConservativeSet_h
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index dcbe12d..f1f3956 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -61,13 +61,13 @@ static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*);
DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, datePrototype->classInfo()->className))
{
- putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, datePrototype, DontEnum | DontDelete | ReadOnly);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum);
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete);
}
// ECMA 15.9.3
diff --git a/Source/JavaScriptCore/runtime/DateInstance.cpp b/Source/JavaScriptCore/runtime/DateInstance.cpp
index 8562e2d..44e8b7d 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.cpp
+++ b/Source/JavaScriptCore/runtime/DateInstance.cpp
@@ -34,22 +34,22 @@ namespace JSC {
const ClassInfo DateInstance::info = {"Date", 0, 0, 0};
-DateInstance::DateInstance(ExecState*, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(exec->globalData(), structure)
{
- setInternalValue(jsNaN());
+ setInternalValue(exec->globalData(), jsNaN());
}
-DateInstance::DateInstance(ExecState*, NonNullPassRefPtr<Structure> structure, double time)
- : JSWrapperObject(structure)
+DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure, double time)
+ : JSWrapperObject(exec->globalData(), structure)
{
- setInternalValue(jsNumber(timeClip(time)));
+ setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
}
DateInstance::DateInstance(ExecState* exec, double time)
- : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure())
+ : JSWrapperObject(exec->globalData(), exec->lexicalGlobalObject()->dateStructure())
{
- setInternalValue(jsNumber(timeClip(time)));
+ setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
}
const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exec) const
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 085cb33..5838b60 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -433,7 +433,7 @@ DatePrototype::DatePrototype(ExecState* exec, JSGlobalObject* globalObject, NonN
: DateInstance(exec, structure)
{
// The constructor will be added later, after DateConstructor has been built.
- putAnonymousValue(0, globalObject);
+ putAnonymousValue(exec->globalData(), 0, globalObject);
}
bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -845,7 +845,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec)
double milli = timeClip(exec->argument(0).toNumber(exec));
JSValue result = jsNumber(milli);
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -860,7 +860,7 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
if (!exec->argumentCount() || isnan(milli)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -877,12 +877,12 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
gregorianDateTime.copyFrom(*other);
if (!fillStructuresUsingTimeArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -895,7 +895,7 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
DateInstance* thisDateObj = asDateInstance(thisValue);
if (!exec->argumentCount()) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -917,12 +917,12 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
if (!fillStructuresUsingDateArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -1019,7 +1019,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
DateInstance* thisDateObj = asDateInstance(thisValue);
if (!exec->argumentCount()) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
@@ -1041,13 +1041,13 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
double year = exec->argument(0).toIntegerPreserveNaN(exec);
if (!isfinite(year)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
gregorianDateTime.year = toInt32((year > 99 || year < 0) ? year - 1900 : year);
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
- thisDateObj->setInternalValue(result);
+ thisDateObj->setInternalValue(exec->globalData(), result);
return JSValue::encode(result);
}
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index 227e9ec..b84f5ea 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -201,7 +201,7 @@ private:
UString m_message;
};
-COMPILE_ASSERT(sizeof(StrictModeTypeErrorFunction) <= sizeof(CollectorCell), sizeof_StrictModeTypeErrorFunction_must_be_less_than_CollectorCell);
+ASSERT_CLASS_FITS_IN_CELL(StrictModeTypeErrorFunction);
JSValue createTypeErrorFunction(ExecState* exec, const UString& message)
{
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index 4326a4d..2e53b95 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -33,8 +33,8 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, errorPrototype->classInfo()->className))
{
// ECMA 15.11.3.1 Error.prototype
- putDirectWithoutTransition(exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
}
// ECMA 15.9.3
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
index 0f3153c..a6208d5 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -29,14 +29,14 @@ ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structu
: JSObject(structure)
, m_appendSourceToMessage(false)
{
- putDirect(globalData->propertyNames->message, jsString(globalData, ""));
+ putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, ""));
}
ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message)
: JSObject(structure)
, m_appendSourceToMessage(false)
{
- putDirect(globalData->propertyNames->message, jsString(globalData, message));
+ putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
}
ErrorInstance* ErrorInstance::create(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message)
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index d8fc829..b4e0a7c 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -41,7 +41,7 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, No
{
// The constructor will be added later in ErrorConstructor's constructor
- putDirectWithoutTransition(exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index 45b4802..933b11f 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -40,10 +40,10 @@ ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, functionPrototype->classInfo()->className))
{
- putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
// Number of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
}
static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index cd7739d..e651538 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -41,7 +41,7 @@ static EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*);
FunctionPrototype::FunctionPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
: InternalFunction(&exec->globalData(), globalObject, structure, exec->propertyNames().nullIdentifier)
{
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
}
void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction)
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.h b/Source/JavaScriptCore/runtime/GCActivityCallback.h
index 862b4df..9b6ef04 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallback.h
+++ b/Source/JavaScriptCore/runtime/GCActivityCallback.h
@@ -32,6 +32,10 @@
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
+#if PLATFORM(CF)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
namespace JSC {
class Heap;
@@ -58,6 +62,12 @@ public:
void operator()();
void synchronize();
+#if PLATFORM(CF)
+protected:
+ DefaultGCActivityCallback(Heap*, CFRunLoopRef);
+ void commonConstructor(Heap*, CFRunLoopRef);
+#endif
+
private:
OwnPtr<DefaultGCActivityCallbackPlatformData*> d;
};
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
index 414a0ad..211c423 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
@@ -35,7 +35,6 @@
#include "JSLock.h"
#include <wtf/RetainPtr.h>
#include <wtf/WTFThreadData.h>
-#include <CoreFoundation/CoreFoundation.h>
#if !PLATFORM(CF)
#error "This file should only be used on CF platforms."
@@ -54,22 +53,22 @@ struct DefaultGCActivityCallbackPlatformData {
const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10;
const CFTimeInterval triggerInterval = 2; // seconds
-void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef, void *info)
+void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef timer, void *info)
{
Heap* heap = static_cast<Heap*>(info);
APIEntryShim shim(heap->globalData());
heap->collectAllGarbage();
+ CFRunLoopTimerSetNextFireDate(timer, CFAbsoluteTimeGetCurrent() + decade);
}
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
{
- d = adoptPtr(new DefaultGCActivityCallbackPlatformData);
+ commonConstructor(heap, CFRunLoopGetCurrent());
+}
- memset(&d->context, '\0', sizeof(CFRunLoopTimerContext));
- d->context.info = heap;
- d->runLoop = CFRunLoopGetCurrent();
- d->timer.adoptCF(CFRunLoopTimerCreate(0, decade, decade, 0, 0, DefaultGCActivityCallbackPlatformData::trigger, &d->context));
- CFRunLoopAddTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes);
+DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap, CFRunLoopRef runLoop)
+{
+ commonConstructor(heap, runLoop);
}
DefaultGCActivityCallback::~DefaultGCActivityCallback()
@@ -81,6 +80,17 @@ DefaultGCActivityCallback::~DefaultGCActivityCallback()
d->timer = 0;
}
+void DefaultGCActivityCallback::commonConstructor(Heap* heap, CFRunLoopRef runLoop)
+{
+ d = adoptPtr(new DefaultGCActivityCallbackPlatformData);
+
+ memset(&d->context, 0, sizeof(CFRunLoopTimerContext));
+ d->context.info = heap;
+ d->runLoop = runLoop;
+ d->timer.adoptCF(CFRunLoopTimerCreate(0, decade, decade, 0, 0, DefaultGCActivityCallbackPlatformData::trigger, &d->context));
+ CFRunLoopAddTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes);
+}
+
void DefaultGCActivityCallback::operator()()
{
CFRunLoopTimerSetNextFireDate(d->timer.get(), CFAbsoluteTimeGetCurrent() + triggerInterval);
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.cpp b/Source/JavaScriptCore/runtime/GetterSetter.cpp
index 7e54053..2b9f444 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.cpp
+++ b/Source/JavaScriptCore/runtime/GetterSetter.cpp
@@ -33,9 +33,9 @@ void GetterSetter::markChildren(MarkStack& markStack)
JSCell::markChildren(markStack);
if (m_getter)
- markStack.append(m_getter);
+ markStack.append(&m_getter);
if (m_setter)
- markStack.append(m_setter);
+ markStack.append(&m_setter);
}
bool GetterSetter::isGetterSetter() const
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index e7b1938..ffab94d 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -38,17 +38,15 @@ namespace JSC {
public:
GetterSetter(ExecState* exec)
: JSCell(exec->globalData().getterSetterStructure.get())
- , m_getter(0)
- , m_setter(0)
{
}
virtual void markChildren(MarkStack&);
- JSObject* getter() const { return m_getter; }
- void setGetter(JSObject* getter) { m_getter = getter; }
- JSObject* setter() const { return m_setter; }
- void setSetter(JSObject* setter) { m_setter = setter; }
+ JSObject* getter() const { return m_getter.get(); }
+ void setGetter(JSGlobalData& globalData, JSObject* getter) { m_getter.set(globalData, this, getter); }
+ JSObject* setter() const { return m_setter.get(); }
+ void setSetter(JSGlobalData& globalData, JSObject* setter) { m_setter.set(globalData, this, setter); }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount);
@@ -56,8 +54,8 @@ namespace JSC {
private:
virtual bool isGetterSetter() const;
- JSObject* m_getter;
- JSObject* m_setter;
+ WriteBarrier<JSObject> m_getter;
+ WriteBarrier<JSObject> m_setter;
};
GetterSetter* asGetterSetter(JSValue);
diff --git a/Source/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/Source/JavaScriptCore/runtime/GlobalEvalFunction.cpp
index 3ad4644..27207e2 100644
--- a/Source/JavaScriptCore/runtime/GlobalEvalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/GlobalEvalFunction.cpp
@@ -34,7 +34,7 @@ ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
: PrototypeFunction(exec, globalObject, structure, len, name, function)
- , m_cachedGlobalObject(cachedGlobalObject)
+ , m_cachedGlobalObject(exec->globalData(), this, cachedGlobalObject)
{
ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
}
@@ -42,7 +42,7 @@ GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, JSGlobalObject* globalOb
void GlobalEvalFunction::markChildren(MarkStack& markStack)
{
PrototypeFunction::markChildren(markStack);
- markStack.append(m_cachedGlobalObject);
+ markStack.append(&m_cachedGlobalObject);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/GlobalEvalFunction.h b/Source/JavaScriptCore/runtime/GlobalEvalFunction.h
index b889ca9..13f0946 100644
--- a/Source/JavaScriptCore/runtime/GlobalEvalFunction.h
+++ b/Source/JavaScriptCore/runtime/GlobalEvalFunction.h
@@ -33,7 +33,7 @@ namespace JSC {
class GlobalEvalFunction : public PrototypeFunction {
public:
GlobalEvalFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
- JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
+ JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject.get(); }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
@@ -46,7 +46,7 @@ namespace JSC {
private:
virtual void markChildren(MarkStack&);
- JSGlobalObject* m_cachedGlobalObject;
+ WriteBarrier<JSGlobalObject> m_cachedGlobalObject;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Heap.cpp b/Source/JavaScriptCore/runtime/Heap.cpp
index 3966324..c05233c 100644
--- a/Source/JavaScriptCore/runtime/Heap.cpp
+++ b/Source/JavaScriptCore/runtime/Heap.cpp
@@ -21,7 +21,8 @@
#include "config.h"
#include "Heap.h"
-#include "CollectorHeapIterator.h"
+#include "CodeBlock.h"
+#include "ConservativeSet.h"
#include "GCActivityCallback.h"
#include "GCHandle.h"
#include "Interpreter.h"
@@ -30,14 +31,19 @@
#include "JSLock.h"
#include "JSONObject.h"
#include "Tracing.h"
+#include <algorithm>
#define COLLECT_ON_EVERY_ALLOCATION 0
+using namespace std;
+
namespace JSC {
+const size_t minBytesPerCycle = 512 * 1024;
+
Heap::Heap(JSGlobalData* globalData)
- : m_markedSpace(globalData)
- , m_operationInProgress(NoOperation)
+ : m_operationInProgress(NoOperation)
+ , m_markedSpace(globalData)
, m_markListSet(0)
, m_activityCallback(DefaultGCActivityCallback::create(this))
, m_globalData(globalData)
@@ -71,14 +77,12 @@ void Heap::destroy()
delete m_markListSet;
m_markListSet = 0;
- ProtectCountSet protectedValuesCopy = m_protectedValues;
- m_markedSpace.destroy(protectedValuesCopy);
- ASSERT(!protectedObjectCount());
+ m_markedSpace.destroy();
m_globalData = 0;
}
-void Heap::recordExtraCost(size_t cost)
+void Heap::reportExtraMemoryCostSlowCase(size_t cost)
{
// Our frequency of garbage collection tries to balance memory use against speed
// by collecting based on the number of newly created values. However, for values
@@ -91,20 +95,8 @@ void Heap::recordExtraCost(size_t cost)
// if a large value survives one garbage collection, there is not much point to
// collecting more frequently as long as it stays alive.
- if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.size() / 2) {
- JAVASCRIPTCORE_GC_BEGIN();
-
- markRoots();
-
- JAVASCRIPTCORE_GC_MARKED();
-
- m_markedSpace.reset();
- m_extraCost = 0;
-
- JAVASCRIPTCORE_GC_END();
-
- (*m_activityCallback)();
- }
+ if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.capacity() / 2)
+ collectAllGarbage();
m_extraCost += cost;
}
@@ -113,7 +105,7 @@ void* Heap::allocate(size_t s)
ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
ASSERT(JSLock::lockCount() > 0);
ASSERT(JSLock::currentThreadIsHoldingLock());
- ASSERT_UNUSED(s, s <= HeapConstants::cellSize);
+ ASSERT_UNUSED(s, s <= MarkedBlock::CELL_SIZE);
ASSERT(m_operationInProgress == NoOperation);
#if COLLECT_ON_EVERY_ALLOCATION
@@ -124,34 +116,18 @@ void* Heap::allocate(size_t s)
m_operationInProgress = Allocation;
void* result = m_markedSpace.allocate(s);
m_operationInProgress = NoOperation;
-
if (!result) {
- JAVASCRIPTCORE_GC_BEGIN();
-
- markRoots();
-
- JAVASCRIPTCORE_GC_MARKED();
-
- m_markedSpace.reset();
- m_extraCost = 0;
-
- JAVASCRIPTCORE_GC_END();
-
- (*m_activityCallback)();
+ reset(DoNotSweep);
m_operationInProgress = Allocation;
result = m_markedSpace.allocate(s);
m_operationInProgress = NoOperation;
}
+
ASSERT(result);
return result;
}
-void Heap::markConservatively(ConservativeSet& conservativeSet, void* start, void* end)
-{
- m_markedSpace.markConservatively(conservativeSet, start, end);
-}
-
void Heap::updateWeakGCHandles()
{
for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
@@ -163,7 +139,7 @@ void WeakGCHandlePool::update()
for (unsigned i = 1; i < WeakGCHandlePool::numPoolEntries; ++i) {
if (m_entries[i].isValidPtr()) {
JSCell* cell = m_entries[i].get();
- if (!cell || !Heap::isCellMarked(cell))
+ if (!cell || !Heap::isMarked(cell))
m_entries[i].invalidate();
}
}
@@ -208,7 +184,7 @@ void Heap::markProtectedObjects(MarkStack& markStack)
{
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- markStack.append(it->first);
+ markStack.deprecatedAppend(&it->first);
}
void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
@@ -233,11 +209,16 @@ void Heap::markTempSortVectors(MarkStack& markStack)
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
if (vectorIt->first)
- markStack.append(vectorIt->first);
+ markStack.deprecatedAppend(&vectorIt->first);
}
}
}
-
+
+inline RegisterFile& Heap::registerFile()
+{
+ return m_globalData->interpreter->registerFile();
+}
+
void Heap::markRoots()
{
#ifndef NDEBUG
@@ -256,12 +237,11 @@ void Heap::markRoots()
// We gather the conservative set before clearing mark bits, because
// conservative gathering uses the mark bits from our last mark pass to
// determine whether a reference is valid.
- ConservativeSet conservativeSet;
+ ConservativeSet conservativeSet(this);
m_machineStackMarker.markMachineStackConservatively(conservativeSet);
- m_globalData->interpreter->registerFile().markCallFrames(conservativeSet, this);
+ conservativeSet.add(registerFile().start(), registerFile().end());
- // Reset mark bits.
- m_markedSpace.clearMarkBits();
+ m_markedSpace.clearMarks();
MarkStack& markStack = m_markStack;
conservativeSet.mark(markStack);
@@ -274,12 +254,17 @@ void Heap::markRoots()
// Mark temporary vector for Array sorting
markTempSortVectors(markStack);
markStack.drain();
+
+ HashSet<GlobalCodeBlock*>::const_iterator end = m_codeBlocks.end();
+ for (HashSet<GlobalCodeBlock*>::const_iterator it = m_codeBlocks.begin(); it != end; ++it)
+ (*it)->markAggregate(markStack);
+ markStack.drain();
// Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception)
- markStack.append(m_globalData->exception);
+ markStack.append(&m_globalData->exception);
if (m_globalData->firstStringifierToMark)
JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
markStack.drain();
@@ -301,39 +286,30 @@ size_t Heap::objectCount() const
return m_markedSpace.objectCount();
}
-MarkedSpace::Statistics Heap::statistics() const
+size_t Heap::size() const
{
- return m_markedSpace.statistics();
+ return m_markedSpace.size();
}
-size_t Heap::size() const
+size_t Heap::capacity() const
{
- return m_markedSpace.size();
+ return m_markedSpace.capacity();
}
size_t Heap::globalObjectCount()
{
- size_t count = 0;
- if (JSGlobalObject* head = m_globalData->head) {
- JSGlobalObject* o = head;
- do {
- ++count;
- o = o->next();
- } while (o != head);
- }
- return count;
+ return m_globalData->globalObjects.uncheckedSize();
}
size_t Heap::protectedGlobalObjectCount()
{
size_t count = 0;
- if (JSGlobalObject* head = m_globalData->head) {
- JSGlobalObject* o = head;
- do {
- if (m_protectedValues.contains(o))
- ++count;
- o = o->next();
- } while (o != head);
+
+ GlobalObjectMap& map = m_globalData->globalObjects;
+ GlobalObjectMap::iterator end = map.uncheckedEnd();
+ for (GlobalObjectMap::iterator it = map.uncheckedBegin(); it != end; ++it) {
+ if (map.isValid(it) && m_protectedValues.contains(it->second.get()))
+ ++count;
}
return count;
@@ -344,7 +320,23 @@ size_t Heap::protectedObjectCount()
return m_protectedValues.size();
}
-static const char* typeName(JSCell* cell)
+class TypeCounter {
+public:
+ TypeCounter();
+ void operator()(JSCell*);
+ PassOwnPtr<TypeCountSet> take();
+
+private:
+ const char* typeName(JSCell*);
+ OwnPtr<TypeCountSet> m_typeCountSet;
+};
+
+inline TypeCounter::TypeCounter()
+ : m_typeCountSet(new TypeCountSet)
+{
+}
+
+inline const char* TypeCounter::typeName(JSCell* cell)
{
if (cell->isString())
return "string";
@@ -360,27 +352,32 @@ static const char* typeName(JSCell* cell)
return info ? info->className : "Object";
}
-HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
+inline void TypeCounter::operator()(JSCell* cell)
+{
+ m_typeCountSet->add(typeName(cell));
+}
+
+inline PassOwnPtr<TypeCountSet> TypeCounter::take()
+{
+ return m_typeCountSet.release();
+}
+
+PassOwnPtr<TypeCountSet> Heap::protectedObjectTypeCounts()
{
- HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
+ TypeCounter typeCounter;
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- counts->add(typeName(it->first));
+ typeCounter(it->first);
- return counts;
+ return typeCounter.take();
}
-HashCountedSet<const char*>* Heap::objectTypeCounts()
+PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
{
- HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
-
- LiveObjectIterator it = primaryHeapBegin();
- LiveObjectIterator heapEnd = primaryHeapEnd();
- for ( ; it != heapEnd; ++it)
- counts->add(typeName(*it));
-
- return counts;
+ TypeCounter typeCounter;
+ forEach(typeCounter);
+ return typeCounter.take();
}
bool Heap::isBusy()
@@ -390,6 +387,11 @@ bool Heap::isBusy()
void Heap::collectAllGarbage()
{
+ reset(DoSweep);
+}
+
+void Heap::reset(SweepToggle sweepToggle)
+{
ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
JAVASCRIPTCORE_GC_BEGIN();
@@ -398,22 +400,19 @@ void Heap::collectAllGarbage()
JAVASCRIPTCORE_GC_MARKED();
m_markedSpace.reset();
- m_markedSpace.sweep();
m_extraCost = 0;
- JAVASCRIPTCORE_GC_END();
+ if (sweepToggle == DoSweep) {
+ m_markedSpace.sweep();
+ m_markedSpace.shrink();
+ }
- (*m_activityCallback)();
-}
+ size_t proportionalBytes = static_cast<size_t>(1.5 * m_markedSpace.size());
+ m_markedSpace.setHighWaterMark(max(proportionalBytes, minBytesPerCycle));
-LiveObjectIterator Heap::primaryHeapBegin()
-{
- return m_markedSpace.primaryHeapBegin();
-}
+ JAVASCRIPTCORE_GC_END();
-LiveObjectIterator Heap::primaryHeapEnd()
-{
- return m_markedSpace.primaryHeapEnd();
+ (*m_activityCallback)();
}
void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
diff --git a/Source/JavaScriptCore/runtime/Heap.h b/Source/JavaScriptCore/runtime/Heap.h
index f7f4deb..6591a5b 100644
--- a/Source/JavaScriptCore/runtime/Heap.h
+++ b/Source/JavaScriptCore/runtime/Heap.h
@@ -27,89 +27,86 @@
#include <wtf/Forward.h>
#include <wtf/HashSet.h>
-#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
-
namespace JSC {
- class JSValue;
- class UString;
class GCActivityCallback;
+ class GlobalCodeBlock;
class JSCell;
class JSGlobalData;
class JSValue;
+ class JSValue;
class LiveObjectIterator;
- class MarkedArgumentBuffer;
class MarkStack;
+ class MarkedArgumentBuffer;
+ class RegisterFile;
+ class UString;
class WeakGCHandlePool;
typedef std::pair<JSValue, UString> ValueStringPair;
+ typedef HashCountedSet<JSCell*> ProtectCountSet;
+ typedef HashCountedSet<const char*> TypeCountSet;
enum OperationInProgress { NoOperation, Allocation, Collection };
class Heap {
WTF_MAKE_NONCOPYABLE(Heap);
public:
- void destroy();
+ static Heap* heap(JSValue); // 0 for immediate values
+ static Heap* heap(JSCell*);
- void* allocate(size_t);
+ static bool isMarked(const JSCell*);
+ static bool testAndSetMarked(const JSCell*);
+ static void setMarked(JSCell*);
+
+ Heap(JSGlobalData*);
+ ~Heap();
+ void destroy(); // JSGlobalData must call destroy() before ~Heap().
- bool isBusy(); // true if an allocation or collection is in progress
- void collectAllGarbage();
+ JSGlobalData* globalData() const { return m_globalData; }
+ MarkedSpace& markedSpace() { return m_markedSpace; }
+ MachineStackMarker& machineStackMarker() { return m_machineStackMarker; }
GCActivityCallback* activityCallback();
void setActivityCallback(PassOwnPtr<GCActivityCallback>);
- static const size_t minExtraCost = 256;
- static const size_t maxExtraCost = 1024 * 1024;
+ bool isBusy(); // true if an allocation or collection is in progress
+ void* allocate(size_t);
+ void collectAllGarbage();
void reportExtraMemoryCost(size_t cost);
- size_t objectCount() const;
- MarkedSpace::Statistics statistics() const;
- size_t size() const;
-
void protect(JSValue);
- // Returns true if the value is no longer protected by any protect pointers
- // (though it may still be alive due to heap/stack references).
- bool unprotect(JSValue);
+ bool unprotect(JSValue); // True when the protect count drops to 0.
- static Heap* heap(JSValue); // 0 for immediate values
- static Heap* heap(JSCell*);
+ bool contains(void*);
+ size_t size() const;
+ size_t capacity() const;
+ size_t objectCount() const;
size_t globalObjectCount();
size_t protectedObjectCount();
size_t protectedGlobalObjectCount();
- HashCountedSet<const char*>* protectedObjectTypeCounts();
- HashCountedSet<const char*>* objectTypeCounts();
-
- static bool isCellMarked(const JSCell*);
- static bool checkMarkCell(const JSCell*);
- static void markCell(JSCell*);
+ PassOwnPtr<TypeCountSet> protectedObjectTypeCounts();
+ PassOwnPtr<TypeCountSet> objectTypeCounts();
WeakGCHandle* addWeakGCHandle(JSCell*);
- void markConservatively(ConservativeSet&, void* start, void* end);
-
- void pushTempSortVector(WTF::Vector<ValueStringPair>*);
- void popTempSortVector(WTF::Vector<ValueStringPair>*);
+ void pushTempSortVector(Vector<ValueStringPair>*);
+ void popTempSortVector(Vector<ValueStringPair>*);
+
+ HashSet<GlobalCodeBlock*>& codeBlocks() { return m_codeBlocks; }
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
-
- JSGlobalData* globalData() const { return m_globalData; }
- LiveObjectIterator primaryHeapBegin();
- LiveObjectIterator primaryHeapEnd();
+ template <typename Functor> void forEach(Functor&);
- MachineStackMarker& machineStackMarker() { return m_machineStackMarker; }
-
- MarkedSpace& markedSpace() { return m_markedSpace; }
-
private:
friend class JSGlobalData;
- Heap(JSGlobalData*);
- ~Heap();
- void recordExtraCost(size_t);
+ static const size_t minExtraCost = 256;
+ static const size_t maxExtraCost = 1024 * 1024;
+
+ void reportExtraMemoryCostSlowCase(size_t);
void markRoots();
void markProtectedObjects(MarkStack&);
@@ -117,13 +114,19 @@ namespace JSC {
void updateWeakGCHandles();
WeakGCHandlePool* weakGCHandlePool(size_t index);
+
+ enum SweepToggle { DoNotSweep, DoSweep };
+ void reset(SweepToggle);
+
+ RegisterFile& registerFile();
- MarkedSpace m_markedSpace;
OperationInProgress m_operationInProgress;
+ MarkedSpace m_markedSpace;
ProtectCountSet m_protectedValues;
- WTF::Vector<PageAllocationAligned> m_weakGCHandlePools;
- WTF::Vector<WTF::Vector<ValueStringPair>* > m_tempSortingVectors;
+ Vector<PageAllocationAligned> m_weakGCHandlePools;
+ Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
+ HashSet<GlobalCodeBlock*> m_codeBlocks;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
@@ -137,25 +140,30 @@ namespace JSC {
size_t m_extraCost;
};
- inline bool Heap::isCellMarked(const JSCell* cell)
+ inline bool Heap::isMarked(const JSCell* cell)
{
- return MarkedSpace::isCellMarked(cell);
+ return MarkedSpace::isMarked(cell);
}
- inline bool Heap::checkMarkCell(const JSCell* cell)
+ inline bool Heap::testAndSetMarked(const JSCell* cell)
{
- return MarkedSpace::checkMarkCell(cell);
+ return MarkedSpace::testAndSetMarked(cell);
}
- inline void Heap::markCell(JSCell* cell)
+ inline void Heap::setMarked(JSCell* cell)
{
- MarkedSpace::markCell(cell);
+ MarkedSpace::setMarked(cell);
+ }
+
+ inline bool Heap::contains(void* p)
+ {
+ return m_markedSpace.contains(p);
}
inline void Heap::reportExtraMemoryCost(size_t cost)
{
if (cost > minExtraCost)
- recordExtraCost(cost);
+ reportExtraMemoryCostSlowCase(cost);
}
inline WeakGCHandlePool* Heap::weakGCHandlePool(size_t index)
@@ -163,6 +171,11 @@ namespace JSC {
return static_cast<WeakGCHandlePool*>(m_weakGCHandlePools[index].base());
}
+ template <typename Functor> inline void Heap::forEach(Functor& functor)
+ {
+ m_markedSpace.forEach(functor);
+ }
+
} // namespace JSC
#endif // Heap_h
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index 0a8d9de..f19ae0d 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -46,7 +46,7 @@ InternalFunction::InternalFunction(NonNullPassRefPtr<Structure> structure)
InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const Identifier& name)
: JSObjectWithGlobalObject(globalObject, structure)
{
- putDirect(globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+ putDirect(*globalData, globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
}
const UString& InternalFunction::name(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 10ded4c..a113e91 100644
--- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -31,7 +31,7 @@ namespace JSC {
class JSAPIValueWrapper : public JSCell {
friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
public:
- JSValue value() const { return m_value; }
+ JSValue value() const { return m_value.get(); }
virtual bool isAPIValueWrapper() const { return true; }
@@ -44,12 +44,12 @@ namespace JSC {
private:
JSAPIValueWrapper(ExecState* exec, JSValue value)
: JSCell(exec->globalData().apiWrapperStructure.get())
- , m_value(value)
{
+ m_value.set(exec->globalData(), this, value);
ASSERT(!value.isCell());
}
- JSValue m_value;
+ WriteBarrier<Unknown> m_value;
};
inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index 428403d..6fb5ced 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -61,12 +61,12 @@ void JSActivation::markChildren(MarkStack& markStack)
size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
size_t count = numParametersMinusThis;
- markStack.appendValues(registerArray, count);
+ markStack.deprecatedAppendValues(registerArray, count);
size_t numVars = d()->functionExecutable->capturedVariableCount();
// Skip the call frame, which sits between the parameters and vars.
- markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
+ markStack.deprecatedAppendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
}
inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
@@ -132,8 +132,8 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
if (symbolTableGet(propertyName, slot))
return true;
- if (JSValue* location = getDirectLocation(propertyName)) {
- slot.setValueSlot(location);
+ if (WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName)) {
+ slot.setValue(location->get());
return true;
}
@@ -144,7 +144,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
return false;
}
-void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+void JSActivation::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -155,7 +155,7 @@ void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue value
// properties are non-standard extensions that other implementations do not
// expose in the activation object.
ASSERT(!hasGetterSetterProperties());
- putDirect(propertyName, value, 0, true, slot);
+ putDirect(exec->globalData(), propertyName, value, 0, true, slot);
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 556603b..ded6d87 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -188,9 +188,9 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength,
#endif
m_storage->m_length = initialLength;
m_storage->m_numValuesInVector = 0;
- JSValue* vector = m_storage->m_vector;
+ WriteBarrier<Unknown>* vector = m_storage->m_vector;
for (size_t i = 0; i < initialCapacity; ++i)
- vector[i] = JSValue();
+ vector[i].clear();
}
checkConsistency();
@@ -198,7 +198,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength,
Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity));
}
-JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
+JSArray::JSArray(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, const ArgList& list)
: JSObject(structure)
{
unsigned initialCapacity = list.size();
@@ -225,12 +225,12 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
#endif
size_t i = 0;
- JSValue* vector = m_storage->m_vector;
+ WriteBarrier<Unknown>* vector = m_storage->m_vector;
ArgList::const_iterator end = list.end();
for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
- vector[i] = *it;
+ vector[i].set(globalData, this, *it);
for (; i < initialStorage; i++)
- vector[i] = JSValue();
+ vector[i].clear();
checkConsistency();
@@ -257,16 +257,16 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
}
if (i < m_vectorLength) {
- JSValue& valueSlot = storage->m_vector[i];
- if (valueSlot) {
- slot.setValueSlot(&valueSlot);
+ JSValue value = storage->m_vector[i].get();
+ if (value) {
+ slot.setValue(value);
return true;
}
} else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
if (i >= MIN_SPARSE_ARRAY_INDEX) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->end()) {
- slot.setValueSlot(&it->second);
+ slot.setValue(it->second.get());
return true;
}
}
@@ -305,16 +305,16 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper
if (i >= storage->m_length)
return false;
if (i < m_vectorLength) {
- JSValue& value = storage->m_vector[i];
+ WriteBarrier<Unknown>& value = storage->m_vector[i];
if (value) {
- descriptor.setDescriptor(value, 0);
+ descriptor.setDescriptor(value.get(), 0);
return true;
}
} else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
if (i >= MIN_SPARSE_ARRAY_INDEX) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->end()) {
- descriptor.setDescriptor(it->second, 0);
+ descriptor.setDescriptor(it->second.get(), 0);
return true;
}
}
@@ -359,13 +359,13 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value)
}
if (i < m_vectorLength) {
- JSValue& valueSlot = storage->m_vector[i];
+ WriteBarrier<Unknown>& valueSlot = storage->m_vector[i];
if (valueSlot) {
- valueSlot = value;
+ valueSlot.set(exec->globalData(), this, value);
checkConsistency();
return;
}
- valueSlot = value;
+ valueSlot.set(exec->globalData(), this, value);
++storage->m_numValuesInVector;
checkConsistency();
return;
@@ -395,11 +395,11 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
storage->m_sparseValueMap = map;
}
- pair<SparseArrayValueMap::iterator, bool> result = map->add(i, value);
- if (!result.second) { // pre-existing entry
- result.first->second = value;
+ WriteBarrier<Unknown> temp;
+ pair<SparseArrayValueMap::iterator, bool> result = map->add(i, temp);
+ result.first->second.set(exec->globalData(), this, value);
+ if (!result.second) // pre-existing entry
return;
- }
size_t capacity = map->capacity();
if (capacity != storage->reportedMapCapacity) {
@@ -415,7 +415,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
if (!map || map->isEmpty()) {
if (increaseVectorLength(i + 1)) {
storage = m_storage;
- storage->m_vector[i] = value;
+ storage->m_vector[i].set(exec->globalData(), this, value);
++storage->m_numValuesInVector;
checkConsistency();
} else
@@ -457,18 +457,19 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
storage = m_storage;
unsigned vectorLength = m_vectorLength;
- JSValue* vector = storage->m_vector;
+ WriteBarrier<Unknown>* vector = storage->m_vector;
if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
for (unsigned j = vectorLength; j < newVectorLength; ++j)
- vector[j] = JSValue();
+ vector[j].clear();
if (i > MIN_SPARSE_ARRAY_INDEX)
map->remove(i);
} else {
for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
- vector[j] = JSValue();
+ vector[j].clear();
+ JSGlobalData& globalData = exec->globalData();
for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
- vector[j] = map->take(j);
+ vector[j].set(globalData, this, map->take(j).get());
}
ASSERT(i < newVectorLength);
@@ -476,7 +477,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
m_vectorLength = newVectorLength;
storage->m_numValuesInVector = newNumValuesInVector;
- storage->m_vector[i] = value;
+ storage->m_vector[i].set(exec->globalData(), this, value);
checkConsistency();
@@ -503,12 +504,12 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
ArrayStorage* storage = m_storage;
if (i < m_vectorLength) {
- JSValue& valueSlot = storage->m_vector[i];
+ WriteBarrier<Unknown>& valueSlot = storage->m_vector[i];
if (!valueSlot) {
checkConsistency();
return false;
}
- valueSlot = JSValue();
+ valueSlot.clear();
--storage->m_numValuesInVector;
checkConsistency();
return true;
@@ -605,9 +606,9 @@ bool JSArray::increaseVectorLength(unsigned newLength)
storage = m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue));
m_storage->m_allocBase = baseStorage;
- JSValue* vector = storage->m_vector;
+ WriteBarrier<Unknown>* vector = storage->m_vector;
for (unsigned i = vectorLength; i < newVectorLength; ++i)
- vector[i] = JSValue();
+ vector[i].clear();
m_vectorLength = newVectorLength;
@@ -666,9 +667,9 @@ void JSArray::setLength(unsigned newLength)
if (newLength < length) {
unsigned usedVectorLength = min(length, m_vectorLength);
for (unsigned i = newLength; i < usedVectorLength; ++i) {
- JSValue& valueSlot = storage->m_vector[i];
+ WriteBarrier<Unknown>& valueSlot = storage->m_vector[i];
bool hadValue = valueSlot;
- valueSlot = JSValue();
+ valueSlot.clear();
storage->m_numValuesInVector -= hadValue;
}
@@ -706,11 +707,11 @@ JSValue JSArray::pop()
JSValue result;
if (length < m_vectorLength) {
- JSValue& valueSlot = storage->m_vector[length];
+ WriteBarrier<Unknown>& valueSlot = storage->m_vector[length];
if (valueSlot) {
--storage->m_numValuesInVector;
- result = valueSlot;
- valueSlot = JSValue();
+ result = valueSlot.get();
+ valueSlot.clear();
} else
result = jsUndefined();
} else {
@@ -718,7 +719,7 @@ JSValue JSArray::pop()
if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(length);
if (it != map->end()) {
- result = it->second;
+ result = it->second.get();
map->remove(it);
if (map->isEmpty()) {
delete map;
@@ -742,7 +743,7 @@ void JSArray::push(ExecState* exec, JSValue value)
ArrayStorage* storage = m_storage;
if (storage->m_length < m_vectorLength) {
- storage->m_vector[storage->m_length] = value;
+ storage->m_vector[storage->m_length].set(exec->globalData(), this, value);
++storage->m_numValuesInVector;
++storage->m_length;
checkConsistency();
@@ -754,7 +755,7 @@ void JSArray::push(ExecState* exec, JSValue value)
if (!map || map->isEmpty()) {
if (increaseVectorLength(storage->m_length + 1)) {
storage = m_storage;
- storage->m_vector[storage->m_length] = value;
+ storage->m_vector[storage->m_length].set(exec->globalData(), this, value);
++storage->m_numValuesInVector;
++storage->m_length;
checkConsistency();
@@ -857,9 +858,9 @@ void JSArray::unshiftCount(ExecState* exec, int count)
return;
}
- JSValue* vector = m_storage->m_vector;
+ WriteBarrier<Unknown>* vector = m_storage->m_vector;
for (int i = 0; i < count; i++)
- vector[i] = JSValue();
+ vector[i].clear();
}
void JSArray::markChildren(MarkStack& markStack)
@@ -941,7 +942,7 @@ void JSArray::sort(ExecState* exec)
Heap::heap(this)->pushTempSortVector(&values);
for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
- JSValue value = storage->m_vector[i];
+ JSValue value = storage->m_vector[i].get();
ASSERT(!value.isUndefined());
values[i].first = value;
}
@@ -974,9 +975,10 @@ void JSArray::sort(ExecState* exec)
increaseVectorLength(lengthNotIncludingUndefined);
if (storage->m_length < lengthNotIncludingUndefined)
storage->m_length = lengthNotIncludingUndefined;
-
+
+ JSGlobalData& globalData = exec->globalData();
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- storage->m_vector[i] = values[i].first;
+ storage->m_vector[i].set(globalData, this, values[i].first);
Heap::heap(this)->popTempSortVector(&values);
@@ -1105,14 +1107,14 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue v = storage->m_vector[numDefined];
+ JSValue v = storage->m_vector[numDefined].get();
if (!v || v.isUndefined())
break;
tree.abstractor().m_nodes[numDefined].value = v;
tree.insert(numDefined);
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValue v = storage->m_vector[i];
+ JSValue v = storage->m_vector[i].get();
if (v) {
if (v.isUndefined())
++numUndefined;
@@ -1140,7 +1142,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
- tree.abstractor().m_nodes[numDefined].value = it->second;
+ tree.abstractor().m_nodes[numDefined].value = it->second.get();
tree.insert(numDefined);
++numDefined;
}
@@ -1157,18 +1159,19 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
// Copy the values back into m_storage.
AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
iter.start_iter_least(tree);
+ JSGlobalData& globalData = exec->globalData();
for (unsigned i = 0; i < numDefined; ++i) {
- storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value;
+ storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
++iter;
}
// Put undefined values back in.
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
- storage->m_vector[i] = jsUndefined();
+ storage->m_vector[i].setUndefined();
// Ensure that unused values in the vector are zeroed out.
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- storage->m_vector[i] = JSValue();
+ storage->m_vector[i].clear();
storage->m_numValuesInVector = newUsedVectorLength;
@@ -1179,14 +1182,14 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
ArrayStorage* storage = m_storage;
- JSValue* vector = storage->m_vector;
+ WriteBarrier<Unknown>* vector = storage->m_vector;
unsigned vectorEnd = min(storage->m_length, m_vectorLength);
unsigned i = 0;
for (; i < vectorEnd; ++i) {
- JSValue& v = vector[i];
+ WriteBarrier<Unknown>& v = vector[i];
if (!v)
break;
- args.append(v);
+ args.append(v.get());
}
for (; i < storage->m_length; ++i)
@@ -1197,14 +1200,14 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz
{
ASSERT(m_storage->m_length >= maxSize);
UNUSED_PARAM(maxSize);
- JSValue* vector = m_storage->m_vector;
+ WriteBarrier<Unknown>* vector = m_storage->m_vector;
unsigned vectorEnd = min(maxSize, m_vectorLength);
unsigned i = 0;
for (; i < vectorEnd; ++i) {
- JSValue& v = vector[i];
+ WriteBarrier<Unknown>& v = vector[i];
if (!v)
break;
- buffer[i] = v;
+ buffer[i] = v.get();
}
for (; i < maxSize; ++i)
@@ -1223,17 +1226,18 @@ unsigned JSArray::compactForSorting()
unsigned numUndefined = 0;
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue v = storage->m_vector[numDefined];
+ JSValue v = storage->m_vector[numDefined].get();
if (!v || v.isUndefined())
break;
}
+
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValue v = storage->m_vector[i];
+ JSValue v = storage->m_vector[i].get();
if (v) {
if (v.isUndefined())
++numUndefined;
else
- storage->m_vector[numDefined++] = v;
+ storage->m_vector[numDefined++].setWithoutWriteBarrier(v);
}
}
@@ -1252,16 +1256,16 @@ unsigned JSArray::compactForSorting()
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
- storage->m_vector[numDefined++] = it->second;
+ storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.get());
delete map;
storage->m_sparseValueMap = 0;
}
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
- storage->m_vector[i] = jsUndefined();
+ storage->m_vector[i].setUndefined();
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- storage->m_vector[i] = JSValue();
+ storage->m_vector[i].clear();
storage->m_numValuesInVector = newUsedVectorLength;
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index de28b65..b5caa47 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -27,7 +27,7 @@
namespace JSC {
- typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
+ typedef HashMap<unsigned, WriteBarrier<Unknown> > SparseArrayValueMap;
// This struct holds the actual data values of an array. A JSArray object points to it's contained ArrayStorage
// struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and
@@ -44,7 +44,7 @@ namespace JSC {
#if CHECK_ARRAY_CONSISTENCY
bool m_inCompactInitialization;
#endif
- JSValue m_vector[1];
+ WriteBarrier<Unknown> m_vector[1];
};
// The CreateCompact creation mode is used for fast construction of arrays
@@ -67,7 +67,7 @@ namespace JSC {
explicit JSArray(NonNullPassRefPtr<Structure>);
JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength, ArrayCreationMode);
- JSArray(NonNullPassRefPtr<Structure>, const ArgList& initialValues);
+ JSArray(JSGlobalData&, NonNullPassRefPtr<Structure>, const ArgList& initialValues);
virtual ~JSArray();
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -94,32 +94,32 @@ namespace JSC {
JSValue getIndex(unsigned i)
{
ASSERT(canGetIndex(i));
- return m_storage->m_vector[i];
+ return m_storage->m_vector[i].get();
}
bool canSetIndex(unsigned i) { return i < m_vectorLength; }
- void setIndex(unsigned i, JSValue v)
+ void setIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
ASSERT(canSetIndex(i));
- JSValue& x = m_storage->m_vector[i];
+ WriteBarrier<Unknown>& x = m_storage->m_vector[i];
if (!x) {
ArrayStorage *storage = m_storage;
++storage->m_numValuesInVector;
if (i >= storage->m_length)
storage->m_length = i + 1;
}
- x = v;
+ x.set(globalData, this, v);
}
- void uncheckedSetIndex(unsigned i, JSValue v)
+ void uncheckedSetIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
ASSERT(canSetIndex(i));
ArrayStorage *storage = m_storage;
#if CHECK_ARRAY_CONSISTENCY
ASSERT(storage->m_inCompactInitialization);
#endif
- storage->m_vector[i] = v;
+ storage->m_vector[i].set(globalData, this, v);
}
void fillArgList(ExecState*, MarkedArgumentBuffer&);
@@ -194,13 +194,13 @@ namespace JSC {
if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
- markStack.append(it->second);
+ markStack.append(&it->second);
}
}
inline void MarkStack::markChildren(JSCell* cell)
{
- ASSERT(Heap::isCellMarked(cell));
+ ASSERT(Heap::isMarked(cell));
if (!cell->structure()->typeInfo().overridesMarkChildren()) {
#ifdef NDEBUG
asObject(cell)->markChildrenDirect(*this);
@@ -240,7 +240,7 @@ namespace JSC {
current.m_values++;
JSCell* cell;
- if (!value || !value.isCell() || Heap::checkMarkCell(cell = value.asCell())) {
+ if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
if (current.m_values == end) {
m_markSets.removeLast();
continue;
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.cpp b/Source/JavaScriptCore/runtime/JSByteArray.cpp
index 6af9d75..3f7d806 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSByteArray.cpp
@@ -40,7 +40,7 @@ JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure
, m_storage(storage)
, m_classInfo(classInfo)
{
- putDirect(exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete);
+ putDirect(exec->globalData(), exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete);
}
#if !ASSERT_DISABLED
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 95f4efa..66f6197 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -64,6 +64,7 @@ namespace JSC {
friend class JSZombie;
friend class JSGlobalData;
friend class MarkedSpace;
+ friend class MarkedBlock;
private:
explicit JSCell(Structure*);
@@ -336,22 +337,50 @@ namespace JSC {
{
return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
}
+
+ template <typename T> void MarkStack::append(DeprecatedPtr<T>* slot)
+ {
+ internalAppend(slot->get());
+ }
+
+ template <typename T> void MarkStack::append(WriteBarrierBase<T>* slot)
+ {
+ internalAppend(slot->get());
+ }
- ALWAYS_INLINE void MarkStack::append(JSCell* cell)
+ ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
{
ASSERT(!m_isCheckingForDefaultMarkViolation);
ASSERT(cell);
- if (Heap::checkMarkCell(cell))
+ if (Heap::testAndSetMarked(cell))
return;
if (cell->structure()->typeInfo().type() >= CompoundType)
m_values.append(cell);
}
- ALWAYS_INLINE void MarkStack::append(JSValue value)
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
+ {
+ ASSERT(value);
+ internalAppend(*value);
+ }
+
+ ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value)
+ {
+ ASSERT(value);
+ internalAppend(value->jsValue());
+ }
+
+ ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
{
ASSERT(value);
if (value.isCell())
- append(value.asCell());
+ internalAppend(value.asCell());
}
inline Heap* Heap::heap(JSValue v)
@@ -363,7 +392,7 @@ namespace JSC {
inline Heap* Heap::heap(JSCell* c)
{
- return MarkedSpace::cellBlock(c)->heap;
+ return MarkedSpace::heap(c);
}
#if ENABLE(JSC_ZOMBIES)
@@ -372,6 +401,23 @@ namespace JSC {
return isCell() && asCell() && asCell()->isZombie();
}
#endif
+
+ inline void* MarkedBlock::allocate(size_t& nextCell)
+ {
+ do {
+ ASSERT(nextCell < CELLS_PER_BLOCK);
+ if (!marked.testAndSet(nextCell)) { // Always false for the last cell in the block
+ JSCell* cell = reinterpret_cast<JSCell*>(&cells[nextCell++]);
+ cell->~JSCell();
+ return cell;
+ }
+ nextCell = marked.nextPossiblyUnset(nextCell);
+ } while (nextCell != CELLS_PER_BLOCK);
+
+ nextCell = 0;
+ return 0;
+ }
+
} // namespace JSC
#endif // JSCell_h
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 99f8e6f..c569722 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -71,8 +71,8 @@ JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPas
, m_executable(thunk)
, m_scopeChain(globalObject->globalScopeChain())
{
- putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
- putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
#endif
@@ -83,9 +83,9 @@ JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPas
#endif
, m_scopeChain(globalObject->globalScopeChain())
{
- putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
#if ENABLE(JIT)
- putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
#else
UNUSED_PARAM(length);
UNUSED_PARAM(func);
@@ -99,7 +99,7 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> ex
, m_scopeChain(scopeChainNode)
{
const Identifier& name = static_cast<FunctionExecutable*>(m_executable.get())->name();
- putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
}
JSFunction::~JSFunction()
@@ -203,16 +203,16 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
if (propertyName == exec->propertyNames().prototype) {
- JSValue* location = getDirectLocation(propertyName);
+ WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName);
if (!location) {
JSObject* prototype = new (exec) JSObject(scope().globalObject()->emptyObjectStructure());
- prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
- putDirect(exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
+ prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, this, DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
location = getDirectLocation(propertyName);
}
- slot.setValueSlot(this, location, offsetForLocation(location));
+ slot.setValue(this, location->get(), offsetForLocation(location));
}
if (propertyName == exec->propertyNames().arguments) {
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index 3928c82..ff88048 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -31,7 +31,6 @@
#include "ArgList.h"
#include "Heap.h"
-#include "CollectorHeapIterator.h"
#include "CommonIdentifiers.h"
#include "FunctionConstructor.h"
#include "GetterSetter.h"
@@ -87,25 +86,26 @@ void* JSGlobalData::jsFunctionVPtr;
void JSGlobalData::storeVPtrs()
{
- CollectorCell cell;
- void* storage = &cell;
+ // Enough storage to fit a JSArray, JSByteArray, JSString, or JSFunction.
+ // COMPILE_ASSERTS below check that this is true.
+ char storage[64];
- COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell);
+ COMPILE_ASSERT(sizeof(JSArray) <= sizeof(storage), sizeof_JSArray_must_be_less_than_storage);
JSCell* jsArray = new (storage) JSArray(JSArray::VPtrStealingHack);
JSGlobalData::jsArrayVPtr = jsArray->vptr();
jsArray->~JSCell();
- COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell);
+ COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(storage), sizeof_JSByteArray_must_be_less_than_storage);
JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
jsByteArray->~JSCell();
- COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell);
+ COMPILE_ASSERT(sizeof(JSString) <= sizeof(storage), sizeof_JSString_must_be_less_than_storage);
JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
JSGlobalData::jsStringVPtr = jsString->vptr();
jsString->~JSCell();
- COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell);
+ COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(storage), sizeof_JSFunction_must_be_less_than_storage);
JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
jsFunction->~JSCell();
@@ -140,7 +140,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, parser(new Parser)
, interpreter(new Interpreter)
, heap(this)
- , head(0)
, dynamicGlobalObject(0)
, firstStringifierToMark(0)
, cachedUTCOffset(NaN)
@@ -166,11 +165,14 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
if (canUseJIT) {
m_canUseJIT = kCFBooleanTrue == canUseJIT;
CFRelease(canUseJIT);
- } else
- m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
+ } else {
+ char* canUseJITString = getenv("JavaScriptCoreUseJIT");
+ m_canUseJIT = !canUseJITString || atoi(canUseJITString);
+ }
CFRelease(canUseJITKey);
#elif OS(UNIX)
- m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
+ char* canUseJITString = getenv("JavaScriptCoreUseJIT");
+ m_canUseJIT = !canUseJITString || atoi(canUseJITString);
#else
m_canUseJIT = true;
#endif
@@ -311,21 +313,30 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
+class Recompiler {
+public:
+ void operator()(JSCell*);
+};
+
+inline void Recompiler::operator()(JSCell* cell)
+{
+ if (!cell->inherits(&JSFunction::info))
+ return;
+ JSFunction* function = asFunction(cell);
+ if (function->executable()->isHostFunction())
+ return;
+ function->jsExecutable()->discardCode();
+}
+
+
void JSGlobalData::recompileAllJSFunctions()
{
// If JavaScript is running, it's not safe to recompile, since we'll end
// up throwing away code that is live on the stack.
ASSERT(!dynamicGlobalObject);
-
- LiveObjectIterator it = heap.primaryHeapBegin();
- LiveObjectIterator heapEnd = heap.primaryHeapEnd();
- for ( ; it != heapEnd; ++it) {
- if ((*it)->inherits(&JSFunction::info)) {
- JSFunction* function = asFunction(*it);
- if (!function->executable()->isHostFunction())
- function->jsExecutable()->discardCode();
- }
- }
+
+ Recompiler recompiler;
+ heap.forEach(recompiler);
}
#if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 31f41e9..7b69055 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -39,6 +39,7 @@
#include "SmallStrings.h"
#include "Terminator.h"
#include "TimeoutChecker.h"
+#include "WeakGCMap.h"
#include "WeakRandom.h"
#include <wtf/BumpPointerAllocator.h>
#include <wtf/Forward.h>
@@ -72,7 +73,9 @@ namespace JSC {
#endif
struct HashTable;
- struct Instruction;
+ struct Instruction;
+
+ typedef WeakGCMap<JSGlobalObject*, JSGlobalObject> GlobalObjectMap; // FIXME: Would be nice to use a WeakGCSet here.
struct DSTOffsetCache {
DSTOffsetCache()
@@ -203,14 +206,14 @@ namespace JSC {
Terminator terminator;
Heap heap;
- JSValue exception;
+ DeprecatedPtr<Unknown> exception;
#if ENABLE(JIT)
ReturnAddressPtr exceptionLocation;
#endif
HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- JSGlobalObject* head;
+ GlobalObjectMap globalObjects;
JSGlobalObject* dynamicGlobalObject;
HashSet<JSObject*> stringRecursionCheckVisitedObjects;
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 9b67dbb..f303196 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -80,16 +80,16 @@ static const int initialTickCountThreshold = 255;
// Preferred number of milliseconds between each timeout check
static const int preferredScriptCheckTimeInterval = 1000;
-static inline void markIfNeeded(MarkStack& markStack, JSValue v)
+template <typename T> static inline void markIfNeeded(MarkStack& markStack, WriteBarrier<T>* v)
{
- if (v)
+ if (*v)
markStack.append(v);
}
static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s)
{
- if (s)
- markIfNeeded(markStack, s->storedPrototype());
+ if (s && s->storedPrototype())
+ markStack.append(s->storedPrototypeSlot());
}
JSGlobalObject::~JSGlobalObject()
@@ -104,18 +104,8 @@ JSGlobalObject::~JSGlobalObject()
(*profiler)->stopProfiling(globalExec(), UString());
}
- d()->next->d()->prev = d()->prev;
- d()->prev->d()->next = d()->next;
- JSGlobalObject*& headObject = head();
- if (headObject == this)
- headObject = d()->next;
- if (headObject == this)
- headObject = 0;
-
- HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
- (*it)->clearGlobalObject();
-
+ d()->globalData->globalObjects.take(this);
+
RegisterFile& registerFile = globalData().interpreter->registerFile();
if (registerFile.clearGlobalObject(this))
registerFile.setNumGlobals(0);
@@ -125,22 +115,15 @@ JSGlobalObject::~JSGlobalObject()
void JSGlobalObject::init(JSObject* thisValue)
{
ASSERT(JSLock::currentThreadIsHoldingLock());
-
+
structure()->disableSpecificFunctionTracking();
d()->globalData = Heap::heap(this)->globalData();
+ d()->globalData->globalObjects.set(this, this);
d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue);
JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0);
- if (JSGlobalObject*& headObject = head()) {
- d()->prev = headObject;
- d()->next = headObject->d()->next;
- headObject->d()->next->d()->prev = this;
- headObject->d()->next = this;
- } else
- headObject = d()->next = d()->prev = this;
-
d()->debugger = 0;
d()->profileGroup = 0;
@@ -202,117 +185,117 @@ void JSGlobalObject::reset(JSValue prototype)
// Prototypes
- d()->functionPrototype = new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
- d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
- d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype);
+ d()->functionPrototype.set(exec->globalData(), this, new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull()))); // The real prototype will be set once ObjectPrototype is created.
+ d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype.get());
+ d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype.get());
NativeFunctionWrapper* callFunction = 0;
NativeFunctionWrapper* applyFunction = 0;
d()->functionPrototype->addFunctionProperties(exec, this, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
- d()->callFunction = callFunction;
- d()->applyFunction = applyFunction;
- d()->objectPrototype = new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get());
- d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype);
+ d()->callFunction.set(exec->globalData(), this, callFunction);
+ d()->applyFunction.set(exec->globalData(), this, applyFunction);
+ d()->objectPrototype.set(exec->globalData(), this, new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get()));
+ d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype.get());
d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
- d()->functionStructure = JSFunction::createStructure(d()->functionPrototype);
- d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype);
- d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype);
- d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype);
- d()->callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(d()->objectPrototype);
+ d()->functionStructure = JSFunction::createStructure(d()->functionPrototype.get());
+ d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype.get());
+ d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype.get());
+ d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype.get());
+ d()->callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(d()->objectPrototype.get());
- d()->arrayPrototype = new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(d()->objectPrototype));
- d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype);
- d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype);
+ d()->arrayPrototype.set(exec->globalData(), this, new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(d()->objectPrototype.get())));
+ d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype.get());
+ d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype.get());
- d()->stringPrototype = new (exec) StringPrototype(exec, this, StringPrototype::createStructure(d()->objectPrototype));
- d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype);
+ d()->stringPrototype.set(exec->globalData(), this, new (exec) StringPrototype(exec, this, StringPrototype::createStructure(d()->objectPrototype.get())));
+ d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype.get());
- d()->booleanPrototype = new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype);
+ d()->booleanPrototype.set(exec->globalData(), this, new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(d()->objectPrototype.get()), d()->prototypeFunctionStructure.get()));
+ d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype.get());
- d()->numberPrototype = new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype);
+ d()->numberPrototype.set(exec->globalData(), this, new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(d()->objectPrototype.get()), d()->prototypeFunctionStructure.get()));
+ d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype.get());
- d()->datePrototype = new (exec) DatePrototype(exec, this, DatePrototype::createStructure(d()->objectPrototype));
- d()->dateStructure = DateInstance::createStructure(d()->datePrototype);
+ d()->datePrototype.set(exec->globalData(), this, new (exec) DatePrototype(exec, this, DatePrototype::createStructure(d()->objectPrototype.get())));
+ d()->dateStructure = DateInstance::createStructure(d()->datePrototype.get());
- d()->regExpPrototype = new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype);
+ d()->regExpPrototype.set(exec->globalData(), this, new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(d()->objectPrototype.get()), d()->prototypeFunctionStructure.get()));
+ d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype.get());
- d()->methodCallDummy = constructEmptyObject(exec);
+ d()->methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
- ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(d()->objectPrototype.get()), d()->prototypeFunctionStructure.get());
d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
// Constructors
- JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get());
- JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
- JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get());
- JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
- JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
- JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
- JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+ JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(d()->functionPrototype.get()), d()->objectPrototype.get(), d()->prototypeFunctionStructure.get());
+ JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(d()->functionPrototype.get()), d()->functionPrototype.get());
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(d()->functionPrototype.get()), d()->arrayPrototype.get(), d()->prototypeFunctionStructure.get());
+ JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(d()->functionPrototype.get()), d()->prototypeFunctionStructure.get(), d()->stringPrototype.get());
+ JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(d()->functionPrototype.get()), d()->booleanPrototype.get());
+ JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(d()->functionPrototype.get()), d()->numberPrototype.get());
+ JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(d()->functionPrototype.get()), d()->prototypeFunctionStructure.get(), d()->datePrototype.get());
- d()->regExpConstructor = new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype);
+ d()->regExpConstructor.set(exec->globalData(), this, new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(d()->functionPrototype.get()), d()->regExpPrototype.get()));
- d()->errorConstructor = new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
+ d()->errorConstructor.set(exec->globalData(), this, new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(d()->functionPrototype.get()), errorPrototype));
RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
- RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
- d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError");
- d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError");
- d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError");
- d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError");
- d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError");
- d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError");
-
- d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
- d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
- d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
- d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
- d()->stringPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
- d()->numberPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
- d()->datePrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
- d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
- errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
+ RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype.get());
+ d()->evalErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"));
+ d()->rangeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"));
+ d()->referenceErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"));
+ d()->syntaxErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"));
+ d()->typeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"));
+ d()->URIErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"));
+
+ d()->objectPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
+ d()->functionPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
+ d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
+ d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
+ d()->stringPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
+ d()->numberPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
+ d()->datePrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
+ d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->regExpConstructor.get(), DontEnum);
+ errorPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->errorConstructor.get(), DontEnum);
// Set global constructors
// FIXME: These properties could be handled by a static hash table.
- putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor, DontEnum);
- putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Object"), objectConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Function"), functionConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Array"), arrayConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "String"), stringConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Number"), numberConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Date"), dateConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), d()->regExpConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Error"), d()->errorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), d()->evalErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), d()->rangeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), d()->typeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), d()->URIErrorConstructor.get(), DontEnum);
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete),
GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
+ GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
// Set global functions.
- d()->evalFunction = new (exec) GlobalEvalFunction(exec, this, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
- putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
+ d()->evalFunction.set(exec->globalData(), this, new (exec) GlobalEvalFunction(exec, this, GlobalEvalFunction::createStructure(d()->functionPrototype.get()), 1, exec->propertyNames().eval, globalFuncEval, this));
+ putDirectFunctionWithoutTransition(exec, d()->evalFunction.get(), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
@@ -336,7 +319,7 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
setPrototype(prototype);
JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
- JSObject* objectPrototype = d()->objectPrototype;
+ JSObject* objectPrototype = d()->objectPrototype.get();
if (oldLastInPrototypeChain != objectPrototype)
oldLastInPrototypeChain->setPrototype(objectPrototype);
}
@@ -345,33 +328,29 @@ void JSGlobalObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
- HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
- (*it)->markAggregate(markStack);
-
- markIfNeeded(markStack, d()->regExpConstructor);
- markIfNeeded(markStack, d()->errorConstructor);
- markIfNeeded(markStack, d()->evalErrorConstructor);
- markIfNeeded(markStack, d()->rangeErrorConstructor);
- markIfNeeded(markStack, d()->referenceErrorConstructor);
- markIfNeeded(markStack, d()->syntaxErrorConstructor);
- markIfNeeded(markStack, d()->typeErrorConstructor);
- markIfNeeded(markStack, d()->URIErrorConstructor);
-
- markIfNeeded(markStack, d()->evalFunction);
- markIfNeeded(markStack, d()->callFunction);
- markIfNeeded(markStack, d()->applyFunction);
-
- markIfNeeded(markStack, d()->objectPrototype);
- markIfNeeded(markStack, d()->functionPrototype);
- markIfNeeded(markStack, d()->arrayPrototype);
- markIfNeeded(markStack, d()->booleanPrototype);
- markIfNeeded(markStack, d()->stringPrototype);
- markIfNeeded(markStack, d()->numberPrototype);
- markIfNeeded(markStack, d()->datePrototype);
- markIfNeeded(markStack, d()->regExpPrototype);
-
- markIfNeeded(markStack, d()->methodCallDummy);
+ markIfNeeded(markStack, &d()->regExpConstructor);
+ markIfNeeded(markStack, &d()->errorConstructor);
+ markIfNeeded(markStack, &d()->evalErrorConstructor);
+ markIfNeeded(markStack, &d()->rangeErrorConstructor);
+ markIfNeeded(markStack, &d()->referenceErrorConstructor);
+ markIfNeeded(markStack, &d()->syntaxErrorConstructor);
+ markIfNeeded(markStack, &d()->typeErrorConstructor);
+ markIfNeeded(markStack, &d()->URIErrorConstructor);
+
+ markIfNeeded(markStack, &d()->evalFunction);
+ markIfNeeded(markStack, &d()->callFunction);
+ markIfNeeded(markStack, &d()->applyFunction);
+
+ markIfNeeded(markStack, &d()->objectPrototype);
+ markIfNeeded(markStack, &d()->functionPrototype);
+ markIfNeeded(markStack, &d()->arrayPrototype);
+ markIfNeeded(markStack, &d()->booleanPrototype);
+ markIfNeeded(markStack, &d()->stringPrototype);
+ markIfNeeded(markStack, &d()->numberPrototype);
+ markIfNeeded(markStack, &d()->datePrototype);
+ markIfNeeded(markStack, &d()->regExpPrototype);
+
+ markIfNeeded(markStack, &d()->methodCallDummy);
markIfNeeded(markStack, d()->errorStructure);
markIfNeeded(markStack, d()->argumentsStructure);
@@ -396,12 +375,12 @@ void JSGlobalObject::markChildren(MarkStack& markStack)
if (d()->registerArray) {
// Outside the execution of global code, when our variables are torn off,
// we can mark the torn-off array.
- markStack.appendValues(d()->registerArray.get(), d()->registerArraySize);
+ markStack.deprecatedAppendValues(d()->registerArray.get(), d()->registerArraySize);
} else if (d()->registers) {
// During execution of global code, when our variables are in the register file,
// the symbol table tells us how many variables there are, and registers
// points to where they end, and the registers used for execution begin.
- markStack.appendValues(d()->registers - symbolTable().size(), symbolTable().size());
+ markStack.deprecatedAppendValues(d()->registers - symbolTable().size(), symbolTable().size());
}
}
@@ -425,9 +404,10 @@ void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
d()->registers = 0;
return;
}
-
- Register* registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals);
- setRegisters(registerArray + numGlobals, registerArray, numGlobals);
+
+ OwnArrayPtr<Register> registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals);
+ Register* registers = registerArray.get() + numGlobals;
+ setRegisters(registers, registerArray.release(), numGlobals);
}
void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 24bc2f8..d13d2da 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -73,26 +73,6 @@ namespace JSC {
, destructor(destructor)
, registerArraySize(0)
, globalScopeChain(NoScopeChain())
- , regExpConstructor(0)
- , errorConstructor(0)
- , evalErrorConstructor(0)
- , rangeErrorConstructor(0)
- , referenceErrorConstructor(0)
- , syntaxErrorConstructor(0)
- , typeErrorConstructor(0)
- , URIErrorConstructor(0)
- , evalFunction(0)
- , callFunction(0)
- , applyFunction(0)
- , objectPrototype(0)
- , functionPrototype(0)
- , arrayPrototype(0)
- , booleanPrototype(0)
- , stringPrototype(0)
- , numberPrototype(0)
- , datePrototype(0)
- , regExpPrototype(0)
- , methodCallDummy(0)
, weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
}
@@ -109,29 +89,29 @@ namespace JSC {
ScopeChain globalScopeChain;
Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
- RegExpConstructor* regExpConstructor;
- ErrorConstructor* errorConstructor;
- NativeErrorConstructor* evalErrorConstructor;
- NativeErrorConstructor* rangeErrorConstructor;
- NativeErrorConstructor* referenceErrorConstructor;
- NativeErrorConstructor* syntaxErrorConstructor;
- NativeErrorConstructor* typeErrorConstructor;
- NativeErrorConstructor* URIErrorConstructor;
-
- GlobalEvalFunction* evalFunction;
- NativeFunctionWrapper* callFunction;
- NativeFunctionWrapper* applyFunction;
-
- ObjectPrototype* objectPrototype;
- FunctionPrototype* functionPrototype;
- ArrayPrototype* arrayPrototype;
- BooleanPrototype* booleanPrototype;
- StringPrototype* stringPrototype;
- NumberPrototype* numberPrototype;
- DatePrototype* datePrototype;
- RegExpPrototype* regExpPrototype;
-
- JSObject* methodCallDummy;
+ WriteBarrier<RegExpConstructor> regExpConstructor;
+ WriteBarrier<ErrorConstructor> errorConstructor;
+ WriteBarrier<NativeErrorConstructor> evalErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> rangeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> referenceErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> syntaxErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> typeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> URIErrorConstructor;
+
+ WriteBarrier<GlobalEvalFunction> evalFunction;
+ WriteBarrier<NativeFunctionWrapper> callFunction;
+ WriteBarrier<NativeFunctionWrapper> applyFunction;
+
+ WriteBarrier<ObjectPrototype> objectPrototype;
+ WriteBarrier<FunctionPrototype> functionPrototype;
+ WriteBarrier<ArrayPrototype> arrayPrototype;
+ WriteBarrier<BooleanPrototype> booleanPrototype;
+ WriteBarrier<StringPrototype> stringPrototype;
+ WriteBarrier<NumberPrototype> numberPrototype;
+ WriteBarrier<DatePrototype> datePrototype;
+ WriteBarrier<RegExpPrototype> regExpPrototype;
+
+ WriteBarrier<JSObject> methodCallDummy;
RefPtr<Structure> argumentsStructure;
RefPtr<Structure> arrayStructure;
@@ -155,7 +135,6 @@ namespace JSC {
RefPtr<JSGlobalData> globalData;
- HashSet<GlobalCodeBlock*> codeBlocks;
WeakMapSet weakMaps;
WeakRandom weakRandom;
};
@@ -167,7 +146,7 @@ namespace JSC {
: JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
- putAnonymousValue(0, this);
+ putThisToAnonymousValue(0);
init(this);
}
@@ -175,7 +154,7 @@ namespace JSC {
: JSVariableObject(structure, new JSGlobalObjectData(destroyJSGlobalObjectData))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
- putAnonymousValue(0, this);
+ putThisToAnonymousValue(0);
init(this);
}
@@ -184,7 +163,7 @@ namespace JSC {
: JSVariableObject(structure, data)
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
- putAnonymousValue(0, this);
+ putThisToAnonymousValue(0);
init(thisValue);
}
@@ -202,35 +181,31 @@ namespace JSC {
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
- // Linked list of all global objects that use the same JSGlobalData.
- JSGlobalObject*& head() { return d()->globalData->head; }
- JSGlobalObject* next() { return d()->next; }
-
// The following accessors return pristine values, even if a script
// replaces the global object's associated property.
- RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
+ RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor.get(); }
- ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
- NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
- NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
- NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
- NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
- NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
- NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
+ ErrorConstructor* errorConstructor() const { return d()->errorConstructor.get(); }
+ NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor.get(); }
+ NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor.get(); }
+ NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor.get(); }
+ NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor.get(); }
+ NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor.get(); }
+ NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor.get(); }
- GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
+ GlobalEvalFunction* evalFunction() const { return d()->evalFunction.get(); }
- ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
- FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
- ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
- BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
- StringPrototype* stringPrototype() const { return d()->stringPrototype; }
- NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
- DatePrototype* datePrototype() const { return d()->datePrototype; }
- RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
+ ObjectPrototype* objectPrototype() const { return d()->objectPrototype.get(); }
+ FunctionPrototype* functionPrototype() const { return d()->functionPrototype.get(); }
+ ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype.get(); }
+ BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype.get(); }
+ StringPrototype* stringPrototype() const { return d()->stringPrototype.get(); }
+ NumberPrototype* numberPrototype() const { return d()->numberPrototype.get(); }
+ DatePrototype* datePrototype() const { return d()->datePrototype.get(); }
+ RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype.get(); }
- JSObject* methodCallDummy() const { return d()->methodCallDummy; }
+ JSObject* methodCallDummy() const { return d()->methodCallDummy.get(); }
Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
Structure* arrayStructure() const { return d()->arrayStructure.get(); }
@@ -270,8 +245,6 @@ namespace JSC {
virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
- HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
-
void copyGlobalsFrom(RegisterFile&);
void copyGlobalsTo(RegisterFile&);
@@ -322,7 +295,7 @@ namespace JSC {
void init(JSObject* thisValue);
void reset(JSValue prototype);
- void setRegisters(Register* registers, Register* registerArray, size_t count);
+ void setRegisters(Register* registers, PassOwnArrayPtr<Register> registerArray, size_t count);
void* operator new(size_t); // can only be allocated with JSGlobalData
};
@@ -335,7 +308,7 @@ namespace JSC {
return static_cast<JSGlobalObject*>(asObject(value));
}
- inline void JSGlobalObject::setRegisters(Register* registers, Register* registerArray, size_t count)
+ inline void JSGlobalObject::setRegisters(Register* registers, PassOwnArrayPtr<Register> registerArray, size_t count)
{
JSVariableObject::setRegisters(registers, registerArray);
d()->registerArraySize = count;
@@ -385,7 +358,7 @@ namespace JSC {
inline JSValue Structure::prototypeForLookup(ExecState* exec) const
{
if (typeInfo().type() == ObjectType)
- return m_prototype;
+ return m_prototype.get();
ASSERT(typeInfo().type() == StringType);
return exec->lexicalGlobalObject()->stringPrototype();
@@ -457,12 +430,12 @@ namespace JSC {
{
MarkedArgumentBuffer values;
values.append(singleItemValue);
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+ return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), values);
}
inline JSArray* constructArray(ExecState* exec, const ArgList& values)
{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+ return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), values);
}
class DynamicGlobalObjectScope {
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index df4be52..0f7a576 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -84,12 +84,13 @@ private:
public:
Holder(JSObject*);
- JSObject* object() const { return m_object; }
+ JSObject* object() const { return m_object.get(); }
+ DeprecatedPtr<JSObject>* objectSlot() { return &m_object; }
bool appendNextProperty(Stringifier&, UStringBuilder&);
private:
- JSObject* const m_object;
+ DeprecatedPtr<JSObject> m_object;
const bool m_isArray;
bool m_isJSArray;
unsigned m_index;
@@ -258,7 +259,7 @@ void Stringifier::markAggregate(MarkStack& markStack)
for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) {
size_t size = m_holderStack.size();
for (size_t i = 0; i < size; ++i)
- markStack.append(m_holderStack[i].object());
+ markStack.append(m_holderStack[i].objectSlot());
}
}
@@ -269,7 +270,7 @@ JSValue Stringifier::stringify(JSValue value)
return jsNull();
PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
- object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value);
+ object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value);
UStringBuilder result;
if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
@@ -284,9 +285,6 @@ void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& val
{
int length = value.length();
- // String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters.
- builder.reserveCapacity(builder.length() + length + 2 + 8);
-
builder.append('"');
const UChar* data = value.characters();
@@ -502,7 +500,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu
// First time through, initialize.
if (!m_index) {
if (m_isArray) {
- m_isJSArray = isJSArray(&exec->globalData(), m_object);
+ m_isJSArray = isJSArray(&exec->globalData(), m_object.get());
m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
builder.append('[');
} else {
@@ -535,10 +533,10 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu
if (m_isArray) {
// Get the value.
JSValue value;
- if (m_isJSArray && asArray(m_object)->canGetIndex(index))
- value = asArray(m_object)->getIndex(index);
+ if (m_isJSArray && asArray(m_object.get())->canGetIndex(index))
+ value = asArray(m_object.get())->getIndex(index);
else {
- PropertySlot slot(m_object);
+ PropertySlot slot(m_object.get());
if (!m_object->getOwnPropertySlot(exec, index, slot))
slot.setUndefined();
if (exec->hadException())
@@ -552,10 +550,10 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu
stringifier.startNewLine(builder);
// Append the stringified value.
- stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, index);
+ stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object.get(), index);
} else {
// Get the value.
- PropertySlot slot(m_object);
+ PropertySlot slot(m_object.get());
Identifier& propertyName = m_propertyNames->propertyNameVector()[index];
if (!m_object->getOwnPropertySlot(exec, propertyName, slot))
return true;
@@ -577,7 +575,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu
builder.append(' ');
// Append the stringified value.
- stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, propertyName);
+ stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object.get(), propertyName);
}
// From this point on, no access to the this pointer or to any members, because the
@@ -644,13 +642,13 @@ private:
{
JSValue args[] = { property, unfiltered };
ArgList argList(args, 2);
- return call(m_exec, m_function, m_callType, m_callData, thisObj, argList);
+ return call(m_exec, m_function.get(), m_callType, m_callData, thisObj, argList);
}
friend class Holder;
ExecState* m_exec;
- JSObject* m_function;
+ DeprecatedPtr<JSObject> m_function;
CallType m_callType;
CallData m_callData;
};
@@ -729,7 +727,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
array->deleteProperty(m_exec, indexStack.last());
else {
if (isJSArray(&m_exec->globalData(), array) && array->canSetIndex(indexStack.last()))
- array->setIndex(indexStack.last(), filteredValue);
+ array->setIndex(m_exec->globalData(), indexStack.last(), filteredValue);
else
array->put(m_exec, indexStack.last(), filteredValue);
}
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 6ecc73f..277ffff 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -312,7 +312,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
JSValue object = getDirect(propertyName);
if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
- asGetterSetter(object)->setGetter(getterFunction);
+ asGetterSetter(object)->setGetter(exec->globalData(), getterFunction);
return;
}
@@ -331,7 +331,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
}
m_structure->setHasGetterSetterProperties(true);
- getterSetter->setGetter(getterFunction);
+ getterSetter->setGetter(exec->globalData(), getterFunction);
}
void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes)
@@ -339,7 +339,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
JSValue object = getDirect(propertyName);
if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
- asGetterSetter(object)->setSetter(setterFunction);
+ asGetterSetter(object)->setSetter(exec->globalData(), setterFunction);
return;
}
@@ -358,7 +358,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
}
m_structure->setHasGetterSetterProperties(true);
- getterSetter->setSetter(setterFunction);
+ getterSetter->setSetter(exec->globalData(), setterFunction);
}
JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
@@ -512,39 +512,39 @@ void JSObject::removeDirect(const Identifier& propertyName)
if (m_structure->isUncacheableDictionary()) {
offset = m_structure->removePropertyWithoutTransition(propertyName);
if (offset != WTF::notFound)
- putDirectOffset(offset, jsUndefined());
+ putUndefinedAtDirectOffset(offset);
return;
}
RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
setStructure(structure.release());
if (offset != WTF::notFound)
- putDirectOffset(offset, jsUndefined());
+ putUndefinedAtDirectOffset(offset);
}
void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
+ putDirectFunction(exec->globalData(), Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr)
{
- putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
+ putDirectFunction(exec->globalData(), Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr)
{
- putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, function->name(exec)), function, attr);
}
-NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
+NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, WriteBarrierBase<Unknown>* location)
{
- if (JSObject* getterFunction = asGetterSetter(*location)->getter()) {
+ if (JSObject* getterFunction = asGetterSetter(location->get())->getter()) {
if (!structure()->isDictionary())
slot.setCacheableGetterSlot(this, getterFunction, offsetForLocation(location));
else
@@ -595,11 +595,11 @@ static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& p
GetterSetter* accessor = new (exec) GetterSetter(exec);
if (oldDescriptor.getter()) {
attributes |= Getter;
- accessor->setGetter(asObject(oldDescriptor.getter()));
+ accessor->setGetter(exec->globalData(), asObject(oldDescriptor.getter()));
}
if (oldDescriptor.setter()) {
attributes |= Setter;
- accessor->setSetter(asObject(oldDescriptor.setter()));
+ accessor->setSetter(exec->globalData(), asObject(oldDescriptor.setter()));
}
target->putWithAttributes(exec, propertyName, accessor, attributes);
return true;
@@ -720,9 +720,9 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
GetterSetter* getterSetter = asGetterSetter(accessor);
if (current.attributesEqual(descriptor)) {
if (descriptor.setter())
- getterSetter->setSetter(asObject(descriptor.setter()));
+ getterSetter->setSetter(exec->globalData(), asObject(descriptor.setter()));
if (descriptor.getter())
- getterSetter->setGetter(asObject(descriptor.getter()));
+ getterSetter->setGetter(exec->globalData(), asObject(descriptor.getter()));
return true;
}
deleteProperty(exec, propertyName);
@@ -731,7 +731,7 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
attrs |= Setter;
if (descriptor.getter())
attrs |= Getter;
- putDirect(propertyName, getterSetter, attrs);
+ putDirect(exec->globalData(), propertyName, getterSetter, attrs);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 803abfd..b79249c 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -70,8 +70,8 @@ namespace JSC {
Setter = 1 << 6 // property is a setter
};
- typedef EncodedJSValue* PropertyStorage;
- typedef const EncodedJSValue* ConstPropertyStorage;
+ typedef WriteBarrierBase<Unknown>* PropertyStorage;
+ typedef const WriteBarrierBase<Unknown>* ConstPropertyStorage;
class JSObject : public JSCell {
friend class BatchedTransitionOptimizer;
@@ -155,22 +155,22 @@ namespace JSC {
return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
}
- JSValue* getDirectLocation(const Identifier& propertyName)
+ WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName)
{
size_t offset = m_structure->get(propertyName);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
{
JSCell* specificFunction;
size_t offset = m_structure->get(propertyName, attributes, specificFunction);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- size_t offsetForLocation(JSValue* location) const
+ size_t offsetForLocation(WriteBarrierBase<Unknown>* location) const
{
- return location - reinterpret_cast<const JSValue*>(propertyStorage());
+ return location - propertyStorage();
}
void transitionTo(Structure*);
@@ -179,25 +179,26 @@ namespace JSC {
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
- bool putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
- void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
- bool putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
+ bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&);
+ void putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr = 0);
+ bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
- void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
- void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ void putDirectFunction(JSGlobalData&, const Identifier& propertyName, JSCell*, unsigned attr = 0);
+ void putDirectFunction(JSGlobalData&, const Identifier& propertyName, JSCell*, unsigned attr, bool checkReadOnly, PutPropertySlot&);
void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
void putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr = 0);
- void putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attr = 0);
- void putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
+ void putDirectWithoutTransition(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr = 0);
+ void putDirectFunctionWithoutTransition(JSGlobalData&, const Identifier& propertyName, JSCell* value, unsigned attr = 0);
void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
void putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr = 0);
// Fast access to known property offsets.
- JSValue getDirectOffset(size_t offset) const { return JSValue::decode(propertyStorage()[offset]); }
- void putDirectOffset(size_t offset, JSValue value) { propertyStorage()[offset] = JSValue::encode(value); }
+ JSValue getDirectOffset(size_t offset) const { return propertyStorage()[offset].get(); }
+ void putDirectOffset(JSGlobalData& globalData, size_t offset, JSValue value) { propertyStorage()[offset].set(globalData, this, value); }
+ void putUndefinedAtDirectOffset(size_t offset) { propertyStorage()[offset].setUndefined(); }
- void fillGetterPropertySlot(PropertySlot&, JSValue* location);
+ void fillGetterPropertySlot(PropertySlot&, WriteBarrierBase<Unknown>* location);
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0);
@@ -225,25 +226,35 @@ namespace JSC {
return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
}
- void flattenDictionaryObject()
+ void flattenDictionaryObject(JSGlobalData& globalData)
{
- m_structure->flattenDictionaryStructure(this);
+ m_structure->flattenDictionaryStructure(globalData, this);
}
- void putAnonymousValue(unsigned index, JSValue value)
+ void putAnonymousValue(JSGlobalData& globalData, unsigned index, JSValue value)
{
ASSERT(index < m_structure->anonymousSlotCount());
- *locationForOffset(index) = value;
+ locationForOffset(index)->set(globalData, this, value);
+ }
+ void clearAnonymousValue(unsigned index)
+ {
+ ASSERT(index < m_structure->anonymousSlotCount());
+ locationForOffset(index)->clear();
}
JSValue getAnonymousValue(unsigned index) const
{
ASSERT(index < m_structure->anonymousSlotCount());
- return *locationForOffset(index);
+ return locationForOffset(index)->get();
}
protected:
static const unsigned StructureFlags = 0;
+ void putThisToAnonymousValue(unsigned index)
+ {
+ locationForOffset(index)->setWithoutWriteBarrier(this);
+ }
+
private:
// Nobody should ever ask any of these questions on something already known to be a JSObject.
using JSCell::isAPIValueWrapper;
@@ -253,22 +264,22 @@ namespace JSC {
void getString(ExecState* exec);
void isObject();
void isString();
-
+
ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
- const JSValue* locationForOffset(size_t offset) const
+ const WriteBarrierBase<Unknown>* locationForOffset(size_t offset) const
{
- return reinterpret_cast<const JSValue*>(&propertyStorage()[offset]);
+ return &propertyStorage()[offset];
}
- JSValue* locationForOffset(size_t offset)
+ WriteBarrierBase<Unknown>* locationForOffset(size_t offset)
{
- return reinterpret_cast<JSValue*>(&propertyStorage()[offset]);
+ return &propertyStorage()[offset];
}
- bool putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
- bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&, JSCell*);
+ bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&);
void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0);
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -278,7 +289,7 @@ namespace JSC {
union {
PropertyStorage m_externalStorage;
- EncodedJSValue m_inlineStorage[inlineStorageCapacity];
+ WriteBarrierBase<Unknown> m_inlineStorage[inlineStorageCapacity];
};
RefPtr<Structure> m_inheritorID;
@@ -372,11 +383,11 @@ inline bool JSValue::inherits(const ClassInfo* classInfo) const
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (JSValue* location = getDirectLocation(propertyName)) {
- if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter())
+ if (WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName)) {
+ if (m_structure->hasGetterSetterProperties() && location->isGetterSetter())
fillGetterPropertySlot(slot, location);
else
- slot.setValueSlot(this, location, offsetForLocation(location));
+ slot.setValue(this, location->get(), offsetForLocation(location));
return true;
}
@@ -450,7 +461,7 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
+inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -467,7 +478,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
if (checkReadOnly && currentAttributes & ReadOnly)
return false;
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
// At this point, the objects structure only has a specific value set if previously there
// had been one set, and if the new value being specified is the same (otherwise we would
// have despecified, above). So, if currentSpecificFunction is not set, or if the new
@@ -485,7 +496,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
ASSERT(offset < m_structure->propertyStorageCapacity());
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
// See comment on setNewProperty call below.
if (!specificFunction)
slot.setNewProperty(this, offset);
@@ -500,7 +511,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
ASSERT(offset < structure->propertyStorageCapacity());
setStructure(structure.release());
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
if (!specificFunction)
@@ -527,7 +538,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
if (currentSpecificFunction) {
// case (1) Do the put, then return leaving the slot uncachable.
if (specificFunction == currentSpecificFunction) {
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
return true;
}
// case (2) Despecify, fall through to (3).
@@ -536,7 +547,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// case (3) set the slot, do the put, return.
slot.setExistingProperty(this, offset);
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
return true;
}
@@ -557,7 +568,7 @@ inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue
ASSERT(offset < structure->propertyStorageCapacity());
setStructure(structure.release());
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
if (!specificFunction)
@@ -570,61 +581,61 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
+ return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
}
inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
PutPropertySlot slot;
- putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
+ putDirectInternal(globalData, propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
}
-inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
+ return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, 0);
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes)
+inline void JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
PutPropertySlot slot;
- putDirectInternal(propertyName, value, attributes, false, slot, 0);
+ putDirectInternal(globalData, propertyName, value, attributes, false, slot, 0);
}
-inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- return putDirectInternal(propertyName, value, 0, false, slot, 0);
+ return putDirectInternal(globalData, propertyName, value, 0, false, slot, 0);
}
-inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline void JSObject::putDirectFunction(JSGlobalData& globalData, const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
- putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value);
+ putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, value);
}
-inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr)
+inline void JSObject::putDirectFunction(JSGlobalData& globalData, const Identifier& propertyName, JSCell* value, unsigned attr)
{
PutPropertySlot slot;
- putDirectInternal(propertyName, value, attr, false, slot, value);
+ putDirectInternal(globalData, propertyName, value, attr, false, slot, value);
}
-inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attributes)
+inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
size_t currentCapacity = m_structure->propertyStorageCapacity();
size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
}
-inline void JSObject::putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attributes)
+inline void JSObject::putDirectFunctionWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, JSCell* value, unsigned attributes)
{
size_t currentCapacity = m_structure->propertyStorageCapacity();
size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
- putDirectOffset(offset, value);
+ putDirectOffset(globalData, offset, value);
}
inline void JSObject::transitionTo(Structure* newStructure)
@@ -703,7 +714,7 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(isCell() && isObject());
- if (!asObject(asCell())->putDirect(propertyName, value, slot) && slot.isStrictMode())
+ if (!asObject(asCell())->putDirect(exec->globalData(), propertyName, value, slot) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
@@ -725,7 +736,7 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
bool wasInline = (oldSize == JSObject::inlineStorageCapacity);
PropertyStorage oldPropertyStorage = (wasInline ? m_inlineStorage : m_externalStorage);
- PropertyStorage newPropertyStorage = new EncodedJSValue[newSize];
+ PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
for (unsigned i = 0; i < oldSize; ++i)
newPropertyStorage[i] = oldPropertyStorage[i];
@@ -740,11 +751,10 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
{
JSCell::markChildren(markStack);
- markStack.append(prototype());
-
+ markStack.append(m_structure->storedPrototypeSlot());
PropertyStorage storage = propertyStorage();
size_t storageSize = m_structure->propertyStorageSize();
- markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize);
+ markStack.appendValues(storage, storageSize);
}
// --- JSValue inlines ----------------------------
diff --git a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
index e9d6c96..c16acb1 100644
--- a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
@@ -35,7 +35,10 @@ JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalObject* globalObject,
{
COMPILE_ASSERT(AnonymousSlotCount == 1, AnonymousSlotCount_must_be_one);
ASSERT(!globalObject || globalObject->isGlobalObject());
- putAnonymousValue(GlobalObjectSlot, globalObject);
+ if (!globalObject)
+ clearAnonymousValue(GlobalObjectSlot);
+ else
+ putAnonymousValue(globalObject->globalData(), GlobalObjectSlot, globalObject);
}
JSGlobalObject* JSObjectWithGlobalObject::globalObject() const
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index a5d4da0..6fd28e3 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -40,11 +40,11 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyN
, m_cachedStructure(0)
, m_numCacheableSlots(numCacheableSlots)
, m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
- , m_jsStrings(new JSValue[m_jsStringsSize])
+ , m_jsStrings(adoptArrayPtr(new WriteBarrier<Unknown>[m_jsStringsSize]))
{
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
for (size_t i = 0; i < m_jsStringsSize; ++i)
- m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring());
+ m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].ustring()));
}
JSPropertyNameIterator::~JSPropertyNameIterator()
@@ -91,7 +91,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
- JSValue& identifier = m_jsStrings[i];
+ JSValue identifier = m_jsStrings[i].get();
if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
return identifier;
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index 01700ac..cd46243 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -85,7 +85,7 @@ namespace JSC {
RefPtr<StructureChain> m_cachedPrototypeChain;
uint32_t m_numCacheableSlots;
uint32_t m_jsStringsSize;
- OwnArrayPtr<JSValue> m_jsStrings;
+ OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
};
inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index 7ab1d1c..80b048e 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -34,7 +34,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
void JSStaticScopeObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
- markStack.append(d()->registerStore.jsValue());
+ markStack.deprecatedAppend(&d()->registerStore);
}
JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index ba28139..848c431 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -255,7 +255,7 @@ UString JSString::toString(ExecState* exec) const
inline StringObject* StringObject::create(ExecState* exec, JSString* string)
{
- return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
+ return new (exec) StringObject(exec->globalData(), exec->lexicalGlobalObject()->stringObjectStructure(), string);
}
JSObject* JSString::toObject(ExecState* exec) const
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index cad9662..b2e7a51 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -47,6 +47,9 @@ namespace JSC {
struct ClassInfo;
struct Instruction;
+ template <class T> class DeprecatedPtr;
+ template <class T> class WriteBarrierBase;
+
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
#if USE(JSVALUE32_64)
@@ -212,6 +215,9 @@ namespace JSC {
#endif
private:
+ template <class T> JSValue(DeprecatedPtr<T>);
+ template <class T> JSValue(WriteBarrierBase<T>);
+
enum HashTableDeletedValueTag { HashTableDeletedValue };
JSValue(HashTableDeletedValueTag);
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 3f2e218..96a0ec4 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -89,8 +89,8 @@ namespace JSC {
{
}
- Register* copyRegisterArray(Register* src, size_t count);
- void setRegisters(Register* r, Register* registerArray);
+ PassOwnArrayPtr<Register> copyRegisterArray(Register* src, size_t count);
+ void setRegisters(Register* registers, PassOwnArrayPtr<Register> registerArray);
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertyDescriptor&);
@@ -149,18 +149,18 @@ namespace JSC {
return true;
}
- inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count)
+ inline PassOwnArrayPtr<Register> JSVariableObject::copyRegisterArray(Register* src, size_t count)
{
- Register* registerArray = new Register[count];
- memcpy(registerArray, src, count * sizeof(Register));
+ OwnArrayPtr<Register> registerArray = adoptArrayPtr(new Register[count]);
+ memcpy(registerArray.get(), src, count * sizeof(Register));
- return registerArray;
+ return registerArray.release();
}
- inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray)
+ inline void JSVariableObject::setRegisters(Register* registers, PassOwnArrayPtr<Register> registerArray)
{
- ASSERT(registerArray != d->registerArray.get());
- d->registerArray.set(registerArray);
+ ASSERT(registerArray != d->registerArray);
+ d->registerArray = registerArray;
d->registers = registers;
}
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
index 2c39f5c..6c73b2f 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -30,7 +30,7 @@ void JSWrapperObject::markChildren(MarkStack& markStack)
{
JSObject::markChildren(markStack);
if (m_internalValue)
- markStack.append(m_internalValue);
+ markStack.append(&m_internalValue);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index f19cd30..0b0d3fd 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -30,11 +30,11 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSObject {
protected:
- explicit JSWrapperObject(NonNullPassRefPtr<Structure>);
+ explicit JSWrapperObject(JSGlobalData&, NonNullPassRefPtr<Structure>);
public:
- JSValue internalValue() const { return m_internalValue; }
- void setInternalValue(JSValue);
+ JSValue internalValue() const { return m_internalValue.get(); }
+ void setInternalValue(JSGlobalData&, JSValue);
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
@@ -47,21 +47,21 @@ namespace JSC {
private:
virtual void markChildren(MarkStack&);
- JSValue m_internalValue;
+ WriteBarrier<Unknown> m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure)
+ inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
- putAnonymousValue(0, jsNull());
+ putAnonymousValue(globalData, 0, jsNull());
}
- inline void JSWrapperObject::setInternalValue(JSValue value)
+ inline void JSWrapperObject::setInternalValue(JSGlobalData& globalData, JSValue value)
{
ASSERT(value);
ASSERT(!value.isObject());
- m_internalValue = value;
- putAnonymousValue(0, value);
+ m_internalValue.set(globalData, this, value);
+ putAnonymousValue(globalData, 0, value);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp
index df87e7f..bc2e736 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp
@@ -373,7 +373,7 @@ JSValue LiteralParser::parse(ParserState initialState)
}
case DoParseObjectEndExpression:
{
- asObject(objectStack.last())->putDirect(identifierStack.last(), lastValue);
+ asObject(objectStack.last())->putDirect(m_exec->globalData(), identifierStack.last(), lastValue);
identifierStack.removeLast();
if (m_lexer.currentToken().type == TokComma)
goto doParseObjectStartExpression;
diff --git a/Source/JavaScriptCore/runtime/Lookup.cpp b/Source/JavaScriptCore/runtime/Lookup.cpp
index dac1c94..3c7d4be 100644
--- a/Source/JavaScriptCore/runtime/Lookup.cpp
+++ b/Source/JavaScriptCore/runtime/Lookup.cpp
@@ -74,7 +74,7 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
ASSERT(thisObj->structure()->anonymousSlotCount() > 0);
ASSERT(thisObj->getAnonymousValue(0).isCell() && asObject(thisObj->getAnonymousValue(0).asCell())->isGlobalObject());
ASSERT(entry->attributes() & Function);
- JSValue* location = thisObj->getDirectLocation(propertyName);
+ WriteBarrierBase<Unknown>* location = thisObj->getDirectLocation(propertyName);
if (!location) {
NativeFunctionWrapper* function;
@@ -86,11 +86,11 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
#endif
function = new (exec) NativeFunctionWrapper(exec, globalObject, globalObject->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
- thisObj->putDirectFunction(propertyName, function, entry->attributes());
+ thisObj->putDirectFunction(exec->globalData(), propertyName, function, entry->attributes());
location = thisObj->getDirectLocation(propertyName);
}
- slot.setValueSlot(thisObj, location, thisObj->offsetForLocation(location));
+ slot.setValue(thisObj, location->get(), thisObj->offsetForLocation(location));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Lookup.h b/Source/JavaScriptCore/runtime/Lookup.h
index 0d6d98f..43184e5 100644
--- a/Source/JavaScriptCore/runtime/Lookup.h
+++ b/Source/JavaScriptCore/runtime/Lookup.h
@@ -312,9 +312,9 @@ namespace JSC {
if (entry->attributes() & Function) { // function: put as override property
if (LIKELY(value.isCell()))
- thisObj->putDirectFunction(propertyName, value.asCell());
+ thisObj->putDirectFunction(exec->globalData(), propertyName, value.asCell());
else
- thisObj->putDirect(propertyName, value);
+ thisObj->putDirect(exec->globalData(), propertyName, value);
} else if (!(entry->attributes() & ReadOnly))
entry->propertyPutter()(exec, thisObj, value);
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
index e52f402..4430947 100644
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "MachineStackMarker.h"
+#include "ConservativeSet.h"
#include "Heap.h"
#include "JSArray.h"
#include "JSGlobalData.h"
@@ -73,6 +74,18 @@
namespace JSC {
+static inline void swapIfBackwards(void*& begin, void*& end)
+{
+#if OS(WINCE)
+ if (begin <= end)
+ return;
+ std::swap(begin, end);
+#else
+UNUSED_PARAM(begin);
+UNUSED_PARAM(end);
+#endif
+}
+
#if ENABLE(JSC_MULTIPLE_THREADS)
#if OS(DARWIN)
@@ -196,7 +209,10 @@ void MachineStackMarker::unregisterThread()
void NEVER_INLINE MachineStackMarker::markCurrentThreadConservativelyInternal(ConservativeSet& conservativeSet)
{
- m_heap->markConservatively(conservativeSet, m_heap->globalData()->stack().current(), m_heap->globalData()->stack().origin());
+ void* begin = m_heap->globalData()->stack().current();
+ void* end = m_heap->globalData()->stack().origin();
+ swapIfBackwards(begin, end);
+ conservativeSet.add(begin, end);
}
#if COMPILER(GCC)
@@ -358,10 +374,12 @@ void MachineStackMarker::markOtherThreadConservatively(ConservativeSet& conserva
size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
// mark the thread's registers
- m_heap->markConservatively(conservativeSet, static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+ conservativeSet.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
void* stackPointer = otherThreadStackPointer(regs);
- m_heap->markConservatively(conservativeSet, stackPointer, thread->stackBase);
+ void* stackBase = thread->stackBase;
+ swapIfBackwards(stackPointer, stackBase);
+ conservativeSet.add(stackPointer, stackBase);
resumeThread(thread->platformThread);
}
diff --git a/Source/JavaScriptCore/runtime/MarkStack.h b/Source/JavaScriptCore/runtime/MarkStack.h
index 7946e65..0b7941e 100644
--- a/Source/JavaScriptCore/runtime/MarkStack.h
+++ b/Source/JavaScriptCore/runtime/MarkStack.h
@@ -27,7 +27,8 @@
#define MarkStack_h
#include "JSValue.h"
-#include <wtf/HashSet.h>
+#include "WriteBarrier.h"
+#include <wtf/Vector.h>
#include <wtf/Noncopyable.h>
#include <wtf/OSAllocator.h>
@@ -49,17 +50,23 @@ namespace JSC {
#endif
{
}
-
- ALWAYS_INLINE void append(JSValue);
- void append(JSCell*);
- ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues)
+ void deprecatedAppend(JSValue*);
+ void deprecatedAppend(JSCell**);
+ void deprecatedAppend(Register*);
+ template <typename T> void append(WriteBarrierBase<T>*);
+ template <typename T> void append(DeprecatedPtr<T>*);
+
+ ALWAYS_INLINE void deprecatedAppendValues(Register* registers, size_t count, MarkSetProperties properties = NoNullValues)
{
- appendValues(reinterpret_cast<JSValue*>(values), count, properties);
+ JSValue* values = reinterpret_cast<JSValue*>(registers);
+ if (count)
+ m_markSets.append(MarkSet(values, values + count, properties));
}
- ALWAYS_INLINE void appendValues(JSValue* values, size_t count, MarkSetProperties properties = NoNullValues)
+ void appendValues(WriteBarrierBase<Unknown>* barriers, size_t count, MarkSetProperties properties = NoNullValues)
{
+ JSValue* values = barriers->slot();
if (count)
m_markSets.append(MarkSet(values, values + count, properties));
}
@@ -74,6 +81,8 @@ namespace JSC {
}
private:
+ void internalAppend(JSCell*);
+ void internalAppend(JSValue);
void markChildren(JSCell*);
struct MarkSet {
@@ -188,19 +197,6 @@ namespace JSC {
#endif
};
- class ConservativeSet {
- public:
- void add(JSCell* cell) { m_set.add(cell); }
- void mark(MarkStack& markStack)
- {
- HashSet<JSCell*>::iterator end = m_set.end();
- for (HashSet<JSCell*>::iterator it = m_set.begin(); it != end; ++it)
- markStack.append(*it);
- }
-
- private:
- HashSet<JSCell*> m_set;
- };
}
#endif
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.cpp b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
new file mode 100644
index 0000000..16053f2
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MarkedBlock.h"
+
+#include "JSCell.h"
+
+namespace JSC {
+
+MarkedBlock* MarkedBlock::create(JSGlobalData* globalData)
+{
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(BLOCK_SIZE, BLOCK_SIZE, OSAllocator::JSGCHeapPages);
+ if (!static_cast<bool>(allocation))
+ CRASH();
+ return new (allocation.base()) MarkedBlock(allocation, globalData);
+}
+
+void MarkedBlock::destroy(MarkedBlock* block)
+{
+ for (size_t i = 0; i < CELLS_PER_BLOCK; ++i)
+ reinterpret_cast<JSCell*>(&block->cells[i])->~JSCell();
+ block->m_allocation.deallocate();
+}
+
+MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData* globalData)
+ : m_allocation(allocation)
+ , m_heap(&globalData->heap)
+{
+ marked.set(CELLS_PER_BLOCK - 1);
+
+ Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get();
+ for (size_t i = 0; i < CELLS_PER_BLOCK; ++i)
+ new (&cells[i]) JSCell(dummyMarkableCellStructure);
+}
+
+void MarkedBlock::sweep()
+{
+#if !ENABLE(JSC_ZOMBIES)
+ Structure* dummyMarkableCellStructure = m_heap->globalData()->dummyMarkableCellStructure.get();
+#endif
+
+ for (size_t i = 0; i < CELLS_PER_BLOCK; ++i) {
+ if (marked.get(i))
+ continue;
+
+ JSCell* cell = reinterpret_cast<JSCell*>(&cells[i]);
+#if ENABLE(JSC_ZOMBIES)
+ if (!cell->isZombie()) {
+ const ClassInfo* info = cell->classInfo();
+ cell->~JSCell();
+ new (cell) JSZombie(info, JSZombie::leakedZombieStructure());
+ marked.set(i);
+ }
+#else
+ cell->~JSCell();
+ new (cell) JSCell(dummyMarkableCellStructure);
+#endif
+ }
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.h b/Source/JavaScriptCore/runtime/MarkedBlock.h
new file mode 100644
index 0000000..f726c25
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 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 Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef MarkedBlock_h
+#define MarkedBlock_h
+
+#include <wtf/Bitmap.h>
+#include <wtf/FixedArray.h>
+#include <wtf/PageAllocationAligned.h>
+
+#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= MarkedBlock::CELL_SIZE, class_fits_in_cell)
+
+namespace JSC {
+
+ class Heap;
+ class JSCell;
+ class JSGlobalData;
+
+ class MarkedBlock {
+#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
+ static const size_t BLOCK_SIZE = 64 * 1024; // 64k
+#else
+ static const size_t BLOCK_SIZE = 256 * 1024; // 256k
+#endif
+
+ static const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
+ static const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
+ static const size_t MINIMUM_CELL_SIZE = 64;
+ static const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
+ public:
+ // This is still public for now, for use in assertions.
+ static const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
+ private:
+ static const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
+ static const size_t CELL_MASK = CELL_SIZE - 1;
+ static const size_t CELL_ALIGN_MASK = ~CELL_MASK;
+ static const size_t BITS_PER_BLOCK = BLOCK_SIZE / CELL_SIZE;
+ static const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*) - sizeof(WTF::Bitmap<BITS_PER_BLOCK>)) / CELL_SIZE; // Division rounds down intentionally.
+
+ struct CollectorCell {
+ FixedArray<double, CELL_ARRAY_LENGTH> memory;
+ };
+
+ // Cell size needs to be a power of two for CELL_MASK to be valid.
+ COMPILE_ASSERT(!(sizeof(CollectorCell) % 2), Collector_cell_size_is_power_of_two);
+
+ public:
+ static MarkedBlock* create(JSGlobalData*);
+ static void destroy(MarkedBlock*);
+
+ static bool isCellAligned(const void*);
+ static MarkedBlock* blockFor(const void*);
+
+ Heap* heap() const;
+
+ void* allocate(size_t& nextCell);
+ void sweep();
+
+ bool isEmpty();
+
+ void clearMarks();
+ size_t markCount();
+ size_t size();
+ size_t capacity();
+
+ size_t cellNumber(const void*);
+ bool isMarked(const void*);
+ bool testAndSetMarked(const void*);
+ void setMarked(const void*);
+
+ template <typename Functor> void forEach(Functor&);
+
+ FixedArray<CollectorCell, CELLS_PER_BLOCK> cells;
+
+ private:
+ MarkedBlock(const PageAllocationAligned&, JSGlobalData*);
+
+ WTF::Bitmap<BITS_PER_BLOCK> marked;
+ PageAllocationAligned m_allocation;
+ Heap* m_heap;
+ };
+
+ inline bool MarkedBlock::isCellAligned(const void* p)
+ {
+ return !((intptr_t)(p) & CELL_MASK);
+ }
+
+ inline MarkedBlock* MarkedBlock::blockFor(const void* p)
+ {
+ return reinterpret_cast<MarkedBlock*>(reinterpret_cast<uintptr_t>(p) & BLOCK_MASK);
+ }
+
+ inline Heap* MarkedBlock::heap() const
+ {
+ return m_heap;
+ }
+
+ inline bool MarkedBlock::isEmpty()
+ {
+ marked.clear(CELLS_PER_BLOCK - 1); // Clear the always-set last bit to avoid confusing isEmpty().
+ bool result = marked.isEmpty();
+ marked.set(CELLS_PER_BLOCK - 1);
+ return result;
+ }
+
+ inline void MarkedBlock::clearMarks()
+ {
+ // allocate() assumes that the last mark bit is always set.
+ marked.clearAll();
+ marked.set(CELLS_PER_BLOCK - 1);
+ }
+
+ inline size_t MarkedBlock::markCount()
+ {
+ return marked.count() - 1; // The last mark bit is always set.
+ }
+
+ inline size_t MarkedBlock::size()
+ {
+ return markCount() * CELL_SIZE;
+ }
+
+ inline size_t MarkedBlock::capacity()
+ {
+ return BLOCK_SIZE;
+ }
+
+ inline size_t MarkedBlock::cellNumber(const void* cell)
+ {
+ return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
+ }
+
+ inline bool MarkedBlock::isMarked(const void* cell)
+ {
+ return marked.get(cellNumber(cell));
+ }
+
+ inline bool MarkedBlock::testAndSetMarked(const void* cell)
+ {
+ return marked.testAndSet(cellNumber(cell));
+ }
+
+ inline void MarkedBlock::setMarked(const void* cell)
+ {
+ marked.set(cellNumber(cell));
+ }
+
+ template <typename Functor> inline void MarkedBlock::forEach(Functor& functor)
+ {
+ for (size_t i = 0; i < CELLS_PER_BLOCK - 1; ++i) { // The last cell is a dummy place-holder.
+ if (!marked.get(i))
+ continue;
+ functor(reinterpret_cast<JSCell*>(&cells[i]));
+ }
+ }
+
+} // namespace JSC
+
+#endif // MarkedSpace_h
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.cpp b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
index 036c8f0..2f8075d 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
@@ -21,361 +21,118 @@
#include "config.h"
#include "MarkedSpace.h"
-#include "CollectorHeapIterator.h"
#include "JSCell.h"
#include "JSGlobalData.h"
#include "JSLock.h"
-using std::max;
-
namespace JSC {
class Structure;
-// tunable parameters
-
-const size_t GROWTH_FACTOR = 2;
-const size_t LOW_WATER_FACTOR = 4;
-const size_t ALLOCATIONS_PER_COLLECTION = 3600;
-// This value has to be a macro to be used in max() without introducing
-// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
-#define MIN_ARRAY_SIZE (static_cast<size_t>(14))
-
MarkedSpace::MarkedSpace(JSGlobalData* globalData)
- : m_globalData(globalData)
+ : m_waterMark(0)
+ , m_highWaterMark(0)
+ , m_globalData(globalData)
{
- memset(&m_heap, 0, sizeof(CollectorHeap));
allocateBlock();
}
-void MarkedSpace::destroy(ProtectCountSet& protectedValuesCopy)
+void MarkedSpace::destroy()
{
- clearMarkBits();
- ProtectCountSet::iterator protectedValuesEnd = protectedValuesCopy.end();
- for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it)
- markCell(it->first);
-
- m_heap.nextCell = 0;
- m_heap.nextBlock = 0;
- DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell);
- DeadObjectIterator end(m_heap, m_heap.usedBlocks);
- for ( ; it != end; ++it)
- (*it)->~JSCell();
+ clearMarks(); // Make sure weak pointers appear dead during destruction.
- protectedValuesEnd = protectedValuesCopy.end();
- for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it)
- it->first->~JSCell();
-
- for (size_t block = 0; block < m_heap.usedBlocks; ++block)
- m_heap.blocks[block].deallocate();
-
- fastFree(m_heap.blocks);
-
- memset(&m_heap, 0, sizeof(CollectorHeap));
+ while (m_heap.blocks.size())
+ freeBlock(0);
+ m_heap.blocks.clear();
}
-NEVER_INLINE CollectorBlock* MarkedSpace::allocateBlock()
+NEVER_INLINE MarkedBlock* MarkedSpace::allocateBlock()
{
- PageAllocationAligned allocation = PageAllocationAligned::allocate(BLOCK_SIZE, BLOCK_SIZE, OSAllocator::JSGCHeapPages);
- CollectorBlock* block = static_cast<CollectorBlock*>(allocation.base());
- if (!block)
- CRASH();
-
- // Initialize block.
-
- block->heap = &globalData()->heap;
- clearMarkBits(block);
-
- Structure* dummyMarkableCellStructure = globalData()->dummyMarkableCellStructure.get();
- for (size_t i = 0; i < HeapConstants::cellsPerBlock; ++i)
- new (&block->cells[i]) JSCell(dummyMarkableCellStructure);
-
- // Add block to blocks vector.
-
- size_t numBlocks = m_heap.numBlocks;
- if (m_heap.usedBlocks == numBlocks) {
- static const size_t maxNumBlocks = ULONG_MAX / sizeof(PageAllocationAligned) / GROWTH_FACTOR;
- if (numBlocks > maxNumBlocks)
- CRASH();
- numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
- m_heap.numBlocks = numBlocks;
- m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(PageAllocationAligned)));
- }
- m_heap.blocks[m_heap.usedBlocks++] = allocation;
-
+ MarkedBlock* block = MarkedBlock::create(globalData());
+ m_heap.blocks.append(block);
return block;
}
NEVER_INLINE void MarkedSpace::freeBlock(size_t block)
{
- ObjectIterator it(m_heap, block);
- ObjectIterator end(m_heap, block + 1);
- for ( ; it != end; ++it)
- (*it)->~JSCell();
- m_heap.blocks[block].deallocate();
+ MarkedBlock::destroy(m_heap.blocks[block]);
// swap with the last block so we compact as we go
- m_heap.blocks[block] = m_heap.blocks[m_heap.usedBlocks - 1];
- m_heap.usedBlocks--;
-
- if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) {
- m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR;
- m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(PageAllocationAligned)));
- }
+ m_heap.blocks[block] = m_heap.blocks.last();
+ m_heap.blocks.removeLast();
}
-void* MarkedSpace::allocate(size_t s)
+void* MarkedSpace::allocate(size_t)
{
- ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
- typedef HeapConstants::Block Block;
- typedef HeapConstants::Cell Cell;
-
- ASSERT(JSLock::lockCount() > 0);
- ASSERT(JSLock::currentThreadIsHoldingLock());
- ASSERT_UNUSED(s, s <= HeapConstants::cellSize);
-
- // Fast case: find the next garbage cell and recycle it.
-
do {
- ASSERT(m_heap.nextBlock < m_heap.usedBlocks);
- Block* block = m_heap.collectorBlock(m_heap.nextBlock);
- do {
- ASSERT(m_heap.nextCell < HeapConstants::cellsPerBlock);
- if (!block->marked.get(m_heap.nextCell)) { // Always false for the last cell in the block
- Cell* cell = &block->cells[m_heap.nextCell];
+ ASSERT(m_heap.nextBlock < m_heap.blocks.size());
+ MarkedBlock* block = m_heap.collectorBlock(m_heap.nextBlock);
+ if (void* result = block->allocate(m_heap.nextCell))
+ return result;
- JSCell* imp = reinterpret_cast<JSCell*>(cell);
- imp->~JSCell();
+ m_waterMark += block->capacity();
+ } while (++m_heap.nextBlock != m_heap.blocks.size());
- ++m_heap.nextCell;
- return cell;
- }
- block->marked.advanceToNextPossibleFreeCell(m_heap.nextCell);
- } while (m_heap.nextCell != HeapConstants::cellsPerBlock);
- m_heap.nextCell = 0;
- } while (++m_heap.nextBlock != m_heap.usedBlocks);
-
- return 0;
-}
+ if (m_waterMark < m_highWaterMark)
+ return allocateBlock()->allocate(m_heap.nextCell);
-void MarkedSpace::resizeBlocks()
-{
- size_t usedCellCount = markedCells();
- size_t minCellCount = usedCellCount + max(ALLOCATIONS_PER_COLLECTION, usedCellCount);
- size_t minBlockCount = (minCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock;
-
- size_t maxCellCount = 1.25f * minCellCount;
- size_t maxBlockCount = (maxCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock;
-
- if (m_heap.usedBlocks < minBlockCount)
- growBlocks(minBlockCount);
- else if (m_heap.usedBlocks > maxBlockCount)
- shrinkBlocks(maxBlockCount);
-}
-
-void MarkedSpace::growBlocks(size_t neededBlocks)
-{
- ASSERT(m_heap.usedBlocks < neededBlocks);
- while (m_heap.usedBlocks < neededBlocks)
- allocateBlock();
+ return 0;
}
-void MarkedSpace::shrinkBlocks(size_t neededBlocks)
+void MarkedSpace::shrink()
{
- ASSERT(m_heap.usedBlocks > neededBlocks);
-
- // Clear the always-on last bit, so isEmpty() isn't fooled by it.
- for (size_t i = 0; i < m_heap.usedBlocks; ++i)
- m_heap.collectorBlock(i)->marked.clear(HeapConstants::cellsPerBlock - 1);
-
- for (size_t i = 0; i != m_heap.usedBlocks && m_heap.usedBlocks != neededBlocks; ) {
- if (m_heap.collectorBlock(i)->marked.isEmpty()) {
+ for (size_t i = 0; i != m_heap.blocks.size() && m_heap.blocks.size() > 1; ) { // We assume at least one block exists at all times.
+ if (m_heap.collectorBlock(i)->isEmpty()) {
freeBlock(i);
} else
++i;
}
-
- // Reset the always-on last bit.
- for (size_t i = 0; i < m_heap.usedBlocks; ++i)
- m_heap.collectorBlock(i)->marked.set(HeapConstants::cellsPerBlock - 1);
}
-inline bool isPointerAligned(void* p)
+void MarkedSpace::clearMarks()
{
- return (((intptr_t)(p) & (sizeof(char*) - 1)) == 0);
-}
-
-// Cell size needs to be a power of two for isPossibleCell to be valid.
-COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two);
-
-static inline bool isCellAligned(void *p)
-{
- return (((intptr_t)(p) & CELL_MASK) == 0);
-}
-
-static inline bool isPossibleCell(void* p)
-{
- return isCellAligned(p) && p;
-}
-
-void MarkedSpace::markConservatively(ConservativeSet& conservativeSet, void* start, void* end)
-{
-#if OS(WINCE)
- if (start > end) {
- void* tmp = start;
- start = end;
- end = tmp;
- }
-#else
- ASSERT(start <= end);
-#endif
-
- ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000);
- ASSERT(isPointerAligned(start));
- ASSERT(isPointerAligned(end));
-
- char** p = static_cast<char**>(start);
- char** e = static_cast<char**>(end);
-
- while (p != e) {
- char* x = *p++;
- if (isPossibleCell(x)) {
- uintptr_t xAsBits = reinterpret_cast<uintptr_t>(x);
- xAsBits &= CELL_ALIGN_MASK;
-
- uintptr_t offset = xAsBits & BLOCK_OFFSET_MASK;
- const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
- if (offset > lastCellOffset)
- continue;
-
- CollectorBlock* blockAddr = reinterpret_cast<CollectorBlock*>(xAsBits - offset);
- size_t usedBlocks = m_heap.usedBlocks;
- for (size_t block = 0; block < usedBlocks; block++) {
- if (m_heap.collectorBlock(block) != blockAddr)
- continue;
-
- // x is a pointer into the heap. Now, verify that the cell it
- // points to is live. (If the cell is dead, we must not mark it,
- // since that would revive it in a zombie state.)
- if (block < m_heap.nextBlock) {
- conservativeSet.add(reinterpret_cast<JSCell*>(xAsBits));
- break;
- }
-
- size_t cellOffset = offset / CELL_SIZE;
-
- if (block == m_heap.nextBlock && cellOffset < m_heap.nextCell) {
- conservativeSet.add(reinterpret_cast<JSCell*>(xAsBits));
- break;
- }
-
- if (blockAddr->marked.get(cellOffset)) {
- conservativeSet.add(reinterpret_cast<JSCell*>(xAsBits));
- break;
- }
- }
- }
- }
-}
-
-void MarkedSpace::clearMarkBits()
-{
- for (size_t i = 0; i < m_heap.usedBlocks; ++i)
- clearMarkBits(m_heap.collectorBlock(i));
-}
-
-void MarkedSpace::clearMarkBits(CollectorBlock* block)
-{
- // allocate assumes that the last cell in every block is marked.
- block->marked.clearAll();
- block->marked.set(HeapConstants::cellsPerBlock - 1);
-}
-
-size_t MarkedSpace::markedCells(size_t startBlock, size_t startCell) const
-{
- ASSERT(startBlock <= m_heap.usedBlocks);
- ASSERT(startCell < HeapConstants::cellsPerBlock);
-
- if (startBlock >= m_heap.usedBlocks)
- return 0;
-
- size_t result = 0;
- result += m_heap.collectorBlock(startBlock)->marked.count(startCell);
- for (size_t i = startBlock + 1; i < m_heap.usedBlocks; ++i)
- result += m_heap.collectorBlock(i)->marked.count();
-
- return result;
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ m_heap.collectorBlock(i)->clearMarks();
}
void MarkedSpace::sweep()
{
-#if !ENABLE(JSC_ZOMBIES)
- Structure* dummyMarkableCellStructure = globalData()->dummyMarkableCellStructure.get();
-#endif
-
- DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell);
- DeadObjectIterator end(m_heap, m_heap.usedBlocks);
- for ( ; it != end; ++it) {
- JSCell* cell = *it;
-#if ENABLE(JSC_ZOMBIES)
- if (!cell->isZombie()) {
- const ClassInfo* info = cell->classInfo();
- cell->~JSCell();
- new (cell) JSZombie(info, JSZombie::leakedZombieStructure());
- Heap::markCell(cell);
- }
-#else
- cell->~JSCell();
- // Callers of sweep assume it's safe to mark any cell in the heap.
- new (cell) JSCell(dummyMarkableCellStructure);
-#endif
- }
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ m_heap.collectorBlock(i)->sweep();
}
size_t MarkedSpace::objectCount() const
{
- return m_heap.nextBlock * HeapConstants::cellsPerBlock // allocated full blocks
- + m_heap.nextCell // allocated cells in current block
- + markedCells(m_heap.nextBlock, m_heap.nextCell) // marked cells in remainder of m_heap
- - m_heap.usedBlocks; // 1 cell per block is a dummy sentinel
-}
-
-void MarkedSpace::addToStatistics(Statistics& statistics) const
-{
- statistics.size += m_heap.usedBlocks * BLOCK_SIZE;
- statistics.free += m_heap.usedBlocks * BLOCK_SIZE - (objectCount() * HeapConstants::cellSize);
+ size_t result = 0;
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ result += m_heap.collectorBlock(i)->markCount();
+ return result;
}
-MarkedSpace::Statistics MarkedSpace::statistics() const
+size_t MarkedSpace::size() const
{
- Statistics statistics = { 0, 0 };
- addToStatistics(statistics);
- return statistics;
+ size_t result = 0;
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ result += m_heap.collectorBlock(i)->size();
+ return result;
}
-size_t MarkedSpace::size() const
+size_t MarkedSpace::capacity() const
{
- return m_heap.usedBlocks * BLOCK_SIZE;
+ size_t result = 0;
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ result += m_heap.collectorBlock(i)->capacity();
+ return result;
}
void MarkedSpace::reset()
{
m_heap.nextCell = 0;
m_heap.nextBlock = 0;
+ m_waterMark = 0;
#if ENABLE(JSC_ZOMBIES)
sweep();
#endif
- resizeBlocks();
-}
-
-LiveObjectIterator MarkedSpace::primaryHeapBegin()
-{
- return LiveObjectIterator(m_heap, 0);
-}
-
-LiveObjectIterator MarkedSpace::primaryHeapEnd()
-{
- return LiveObjectIterator(m_heap, m_heap.usedBlocks);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.h b/Source/JavaScriptCore/runtime/MarkedSpace.h
index af312b5..fcb93b7 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.h
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.h
@@ -23,7 +23,9 @@
#define MarkedSpace_h
#include "MachineStackMarker.h"
+#include "MarkedBlock.h"
#include "PageAllocationAligned.h"
+#include <wtf/Bitmap.h>
#include <wtf/FixedArray.h>
#include <wtf/HashCountedSet.h>
#include <wtf/Noncopyable.h>
@@ -31,7 +33,6 @@
namespace JSC {
- class CollectorBlock;
class Heap;
class JSCell;
class JSGlobalData;
@@ -39,182 +40,115 @@ namespace JSC {
class MarkStack;
class WeakGCHandle;
-#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
- const size_t BLOCK_SIZE = 64 * 1024; // 64k
-#else
- const size_t BLOCK_SIZE = 256 * 1024; // 256k
-#endif
-
- typedef HashCountedSet<JSCell*> ProtectCountSet;
-
struct CollectorHeap {
- size_t nextBlock;
- size_t nextCell;
- PageAllocationAligned* blocks;
+ CollectorHeap()
+ : nextBlock(0)
+ , nextCell(0)
+ {
+ }
- size_t numBlocks;
- size_t usedBlocks;
-
- CollectorBlock* collectorBlock(size_t index) const
+ MarkedBlock* collectorBlock(size_t index) const
{
- return static_cast<CollectorBlock*>(blocks[index].base());
+ return blocks[index];
}
+
+ size_t nextBlock;
+ size_t nextCell;
+ Vector<MarkedBlock*> blocks;
};
class MarkedSpace {
WTF_MAKE_NONCOPYABLE(MarkedSpace);
public:
- MarkedSpace(JSGlobalData*);
- void destroy(ProtectCountSet&);
-
- void* allocate(size_t);
-
- size_t objectCount() const;
- struct Statistics {
- size_t size;
- size_t free;
- };
- Statistics statistics() const;
- size_t size() const;
-
static Heap* heap(JSCell*);
- static bool isCellMarked(const JSCell*);
- static bool checkMarkCell(const JSCell*);
- static void markCell(JSCell*);
-
- WeakGCHandle* addWeakGCHandle(JSCell*);
-
- void markConservatively(ConservativeSet&, void* start, void* end);
+ static bool isMarked(const JSCell*);
+ static bool testAndSetMarked(const JSCell*);
+ static void setMarked(const JSCell*);
- static bool isNumber(JSCell*);
-
- LiveObjectIterator primaryHeapBegin();
- LiveObjectIterator primaryHeapEnd();
+ MarkedSpace(JSGlobalData*);
+ void destroy();
JSGlobalData* globalData() { return m_globalData; }
- static CollectorBlock* cellBlock(const JSCell*);
- static size_t cellOffset(const JSCell*);
+ size_t highWaterMark() { return m_highWaterMark; }
+ void setHighWaterMark(size_t highWaterMark) { m_highWaterMark = highWaterMark; }
+
+ void* allocate(size_t);
+ void clearMarks();
+ void markRoots();
void reset();
void sweep();
+ void shrink();
- NEVER_INLINE CollectorBlock* allocateBlock();
- NEVER_INLINE void freeBlock(size_t);
- void resizeBlocks();
- void growBlocks(size_t neededBlocks);
- void shrinkBlocks(size_t neededBlocks);
- void clearMarkBits();
- void clearMarkBits(CollectorBlock*);
- size_t markedCells(size_t startBlock = 0, size_t startCell = 0) const;
+ size_t size() const;
+ size_t capacity() const;
+ size_t objectCount() const;
- void addToStatistics(Statistics&) const;
+ bool contains(const void*);
- void markRoots();
+ template<typename Functor> void forEach(Functor&);
private:
- CollectorHeap m_heap;
- JSGlobalData* m_globalData;
- };
+ NEVER_INLINE MarkedBlock* allocateBlock();
+ NEVER_INLINE void freeBlock(size_t);
- // tunable parameters
- // derived constants
- const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
- const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
- const size_t MINIMUM_CELL_SIZE = 64;
- const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
- const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
- const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
- const size_t CELL_MASK = CELL_SIZE - 1;
- const size_t CELL_ALIGN_MASK = ~CELL_MASK;
- const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(MarkedSpace*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells.
-
- const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8;
- const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
-
- struct CollectorBitmap {
- FixedArray<uint32_t, BITMAP_WORDS> bits;
- bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
- void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
- bool getset(size_t n)
- {
- unsigned i = (1 << (n & 0x1F));
- uint32_t& b = bits[n >> 5];
- bool r = !!(b & i);
- b |= i;
- return r;
- }
- void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
- void clearAll() { memset(bits.data(), 0, sizeof(bits)); }
- ALWAYS_INLINE void advanceToNextPossibleFreeCell(size_t& startCell)
- {
- if (!~bits[startCell >> 5])
- startCell = (startCell & (~0x1F)) + 32;
- else
- ++startCell;
- }
- size_t count(size_t startCell = 0)
- {
- size_t result = 0;
- for ( ; (startCell & 0x1F) != 0; ++startCell) {
- if (get(startCell))
- ++result;
- }
- for (size_t i = startCell >> 5; i < BITMAP_WORDS; ++i)
- result += WTF::bitCount(bits[i]);
- return result;
- }
- size_t isEmpty() // Much more efficient than testing count() == 0.
- {
- for (size_t i = 0; i < BITMAP_WORDS; ++i)
- if (bits[i] != 0)
- return false;
- return true;
- }
- };
-
- struct CollectorCell {
- FixedArray<double, CELL_ARRAY_LENGTH> memory;
- };
+ void clearMarks(MarkedBlock*);
- class CollectorBlock {
- public:
- FixedArray<CollectorCell, CELLS_PER_BLOCK> cells;
- CollectorBitmap marked;
- Heap* heap;
+ CollectorHeap m_heap;
+ size_t m_waterMark;
+ size_t m_highWaterMark;
+ JSGlobalData* m_globalData;
};
- struct HeapConstants {
- static const size_t cellSize = CELL_SIZE;
- static const size_t cellsPerBlock = CELLS_PER_BLOCK;
- typedef CollectorCell Cell;
- typedef CollectorBlock Block;
- };
+ inline Heap* MarkedSpace::heap(JSCell* cell)
+ {
+ return MarkedBlock::blockFor(cell)->heap();
+ }
- inline CollectorBlock* MarkedSpace::cellBlock(const JSCell* cell)
+ inline bool MarkedSpace::isMarked(const JSCell* cell)
{
- return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
+ return MarkedBlock::blockFor(cell)->isMarked(cell);
}
- inline size_t MarkedSpace::cellOffset(const JSCell* cell)
+ inline bool MarkedSpace::testAndSetMarked(const JSCell* cell)
{
- return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
+ return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
}
- inline bool MarkedSpace::isCellMarked(const JSCell* cell)
+ inline void MarkedSpace::setMarked(const JSCell* cell)
{
- return cellBlock(cell)->marked.get(cellOffset(cell));
+ MarkedBlock::blockFor(cell)->setMarked(cell);
}
- inline bool MarkedSpace::checkMarkCell(const JSCell* cell)
+ inline bool MarkedSpace::contains(const void* x)
{
- return cellBlock(cell)->marked.getset(cellOffset(cell));
+ if (!MarkedBlock::isCellAligned(x))
+ return false;
+
+ MarkedBlock* block = MarkedBlock::blockFor(x);
+ if (!block)
+ return false;
+
+ size_t size = m_heap.blocks.size();
+ for (size_t i = 0; i < size; i++) {
+ if (block != m_heap.collectorBlock(i))
+ continue;
+
+ // x is a pointer into the heap. Now, verify that the cell it
+ // points to is live. (If the cell is dead, we must not mark it,
+ // since that would revive it in a zombie state.)
+ return block->isMarked(x);
+ }
+
+ return false;
}
- inline void MarkedSpace::markCell(JSCell* cell)
+ template <typename Functor> inline void MarkedSpace::forEach(Functor& functor)
{
- cellBlock(cell)->marked.set(cellOffset(cell));
+ for (size_t i = 0; i < m_heap.blocks.size(); ++i)
+ m_heap.collectorBlock(i)->forEach(functor);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp
index 080d7d2..c79316b 100644
--- a/Source/JavaScriptCore/runtime/MathObject.cpp
+++ b/Source/JavaScriptCore/runtime/MathObject.cpp
@@ -89,14 +89,14 @@ const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
MathObject::MathObject(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
: JSObjectWithGlobalObject(globalObject, structure)
{
- putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "LOG10E"), jsNumber(1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LOG10E"), jsNumber(1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
}
// ECMA 15.8
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
index 06a319b..86101f5 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
@@ -32,11 +32,6 @@
namespace JSC {
-MarkedSpace::Statistics heapStatistics(JSGlobalData* commonGlobalData)
-{
- return commonGlobalData->heap.statistics();
-}
-
GlobalMemoryStatistics globalMemoryStatistics()
{
GlobalMemoryStatistics stats;
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.h b/Source/JavaScriptCore/runtime/MemoryStatistics.h
index 2659702..d4b8b6f 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.h
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.h
@@ -37,7 +37,6 @@ struct GlobalMemoryStatistics {
size_t JITBytes;
};
-MarkedSpace::Statistics heapStatistics(JSGlobalData* commonGlobalData);
GlobalMemoryStatistics globalMemoryStatistics();
}
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index eb508eb..421eecf 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -37,8 +37,8 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject*
{
NativeErrorPrototype* prototype = new (exec) NativeErrorPrototype(exec, globalObject, prototypeStructure, nameAndMessage, this);
- putDirect(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
- putDirect(exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
+ putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
m_errorStructure = ErrorInstance::createStructure(prototype);
}
diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 540220a..4e10268 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -34,9 +34,9 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& nameAndMessage, NativeErrorConstructor* constructor)
: JSObjectWithGlobalObject(globalObject, structure)
{
- putDirect(exec->propertyNames().name, jsString(exec, nameAndMessage), 0);
- putDirect(exec->propertyNames().message, jsString(exec, nameAndMessage), 0);
- putDirect(exec->propertyNames().constructor, constructor, DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().name, jsString(exec, nameAndMessage), 0);
+ putDirect(exec->globalData(), exec->propertyNames().message, jsString(exec, nameAndMessage), 0);
+ putDirect(exec->globalData(), exec->propertyNames().constructor, constructor, DontEnum);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index 5369ca0..7cec875 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -58,10 +58,10 @@ NumberConstructor::NumberConstructor(ExecState* exec, JSGlobalObject* globalObje
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, numberPrototype->info.className))
{
// Number.Prototype
- putDirectWithoutTransition(exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -102,9 +102,9 @@ static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&)
// ECMA 15.7.1
static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* exec)
{
- NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
double n = exec->argumentCount() ? exec->argument(0).toNumber(exec) : 0;
- object->setInternalValue(jsNumber(n));
+ object->setInternalValue(exec->globalData(), jsNumber(n));
return JSValue::encode(object);
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index 1a7e44c..603c2f0 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.cpp
+++ b/Source/JavaScriptCore/runtime/NumberObject.cpp
@@ -31,8 +31,8 @@ ASSERT_CLASS_FITS_IN_CELL(NumberObject);
const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
-NumberObject::NumberObject(NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+NumberObject::NumberObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(globalData, structure)
{
}
@@ -43,8 +43,8 @@ JSValue NumberObject::getJSNumber()
NumberObject* constructNumber(ExecState* exec, JSValue number)
{
- NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
- object->setInternalValue(number);
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
+ object->setInternalValue(exec->globalData(), number);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index e82b593..044f490 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -27,7 +27,7 @@ namespace JSC {
class NumberObject : public JSWrapperObject {
public:
- explicit NumberObject(NonNullPassRefPtr<Structure>);
+ explicit NumberObject(JSGlobalData&, NonNullPassRefPtr<Structure>);
static const ClassInfo info;
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index 0b86c00..fbe6992 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -47,9 +47,9 @@ static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);
// ECMA 15.7.4
NumberPrototype::NumberPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
- : NumberObject(structure)
+ : NumberObject(exec->globalData(), structure)
{
- setInternalValue(jsNumber(0));
+ setInternalValue(exec->globalData(), jsNumber(0));
// The constructor will be added later, after NumberConstructor has been constructed
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index ca3dcd7..f31da67 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -47,10 +47,10 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, JSGlobalObject* globalObje
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, "Object"))
{
// ECMA 15.2.3.1
- putDirectWithoutTransition(exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum);
@@ -117,15 +117,15 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState
JSObject* description = constructEmptyObject(exec);
if (!descriptor.isAccessorDescriptor()) {
- description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
- description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
} else {
- description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0);
- description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0);
}
- description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
- description->putDirect(exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
return JSValue::encode(description);
}
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 1252345..6e84123 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -429,7 +429,7 @@ namespace JSC {
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (cell->structure()->isDictionary()) {
- asObject(cell)->flattenDictionaryObject();
+ asObject(cell)->flattenDictionaryObject(callFrame->globalData());
if (slotBase == cell)
slotOffset = cell->structure()->get(propertyName);
}
@@ -454,7 +454,7 @@ namespace JSC {
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (base->structure()->isDictionary())
- asObject(base)->flattenDictionaryObject();
+ asObject(base)->flattenDictionaryObject(callFrame->globalData());
++count;
}
@@ -471,7 +471,7 @@ namespace JSC {
PropertySlot slot;
JSObject* base;
while (true) {
- base = *iter;
+ base = iter->get();
if (next == end)
return isStrictPut ? JSValue() : base;
if (base->getPropertySlot(callFrame, property, slot))
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h
index de9ddc9..cdda6ff 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PropertySlot.h
@@ -32,8 +32,7 @@ namespace JSC {
class ExecState;
class JSObject;
-#define JSC_VALUE_SLOT_MARKER 0
-#define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
+#define JSC_VALUE_MARKER 0
#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
@@ -67,10 +66,8 @@ namespace JSC {
JSValue getValue(ExecState* exec, const Identifier& propertyName) const
{
- if (m_getValue == JSC_VALUE_SLOT_MARKER)
- return *m_data.valueSlot;
- if (m_getValue == JSC_REGISTER_SLOT_MARKER)
- return (*m_data.registerSlot).jsValue();
+ if (m_getValue == JSC_VALUE_MARKER)
+ return m_value;
if (m_getValue == INDEX_GETTER_MARKER)
return m_getIndexValue(exec, slotBase(), index());
if (m_getValue == GETTER_FUNCTION_MARKER)
@@ -80,10 +77,8 @@ namespace JSC {
JSValue getValue(ExecState* exec, unsigned propertyName) const
{
- if (m_getValue == JSC_VALUE_SLOT_MARKER)
- return *m_data.valueSlot;
- if (m_getValue == JSC_REGISTER_SLOT_MARKER)
- return (*m_data.registerSlot).jsValue();
+ if (m_getValue == JSC_VALUE_MARKER)
+ return m_value;
if (m_getValue == INDEX_GETTER_MARKER)
return m_getIndexValue(exec, m_slotBase, m_data.index);
if (m_getValue == GETTER_FUNCTION_MARKER)
@@ -100,41 +95,32 @@ namespace JSC {
return m_offset;
}
- void setValueSlot(JSValue* valueSlot)
+ void setValue(JSValue slotBase, JSValue value)
{
- ASSERT(valueSlot);
- clearBase();
+ ASSERT(value);
clearOffset();
- m_getValue = JSC_VALUE_SLOT_MARKER;
- m_data.valueSlot = valueSlot;
- }
-
- void setValueSlot(JSValue slotBase, JSValue* valueSlot)
- {
- ASSERT(valueSlot);
- m_getValue = JSC_VALUE_SLOT_MARKER;
+ m_getValue = JSC_VALUE_MARKER;
m_slotBase = slotBase;
- m_data.valueSlot = valueSlot;
+ m_value = value;
}
- void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset)
+ void setValue(JSValue slotBase, JSValue value, size_t offset)
{
- ASSERT(valueSlot);
- m_getValue = JSC_VALUE_SLOT_MARKER;
+ ASSERT(value);
+ m_getValue = JSC_VALUE_MARKER;
m_slotBase = slotBase;
- m_data.valueSlot = valueSlot;
+ m_value = value;
m_offset = offset;
m_cachedPropertyType = Value;
}
-
+
void setValue(JSValue value)
{
ASSERT(value);
clearBase();
clearOffset();
- m_getValue = JSC_VALUE_SLOT_MARKER;
+ m_getValue = JSC_VALUE_MARKER;
m_value = value;
- m_data.valueSlot = &m_value;
}
void setRegisterSlot(Register* registerSlot)
@@ -142,8 +128,8 @@ namespace JSC {
ASSERT(registerSlot);
clearBase();
clearOffset();
- m_getValue = JSC_REGISTER_SLOT_MARKER;
- m_data.registerSlot = registerSlot;
+ m_getValue = JSC_VALUE_MARKER;
+ m_value = registerSlot->jsValue();
}
void setCustom(JSValue slotBase, GetValueFunc getValue)
@@ -251,8 +237,6 @@ namespace JSC {
JSValue m_slotBase;
union {
JSObject* getterFunc;
- JSValue* valueSlot;
- Register* registerSlot;
unsigned index;
} m_data;
diff --git a/Source/JavaScriptCore/runtime/PrototypeFunction.cpp b/Source/JavaScriptCore/runtime/PrototypeFunction.cpp
index 3529080..95e1033 100644
--- a/Source/JavaScriptCore/runtime/PrototypeFunction.cpp
+++ b/Source/JavaScriptCore/runtime/PrototypeFunction.cpp
@@ -37,7 +37,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, JSGlobalObject* globalObje
, m_function(function)
{
ASSERT_ARG(function, function);
- putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
PrototypeFunction::PrototypeFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
@@ -45,7 +45,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, JSGlobalObject* globalObje
, m_function(function)
{
ASSERT_ARG(function, function);
- putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
CallType PrototypeFunction::getCallData(CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/PutPropertySlot.h b/Source/JavaScriptCore/runtime/PutPropertySlot.h
index 4b0b394..4c9e0e6 100644
--- a/Source/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PutPropertySlot.h
@@ -45,14 +45,14 @@ namespace JSC {
{
}
- void setExistingProperty(JSObject* base, size_t offset)
+ void setExistingProperty(DeprecatedPtr<JSObject> base, size_t offset)
{
m_type = ExistingProperty;
m_base = base;
m_offset = offset;
}
- void setNewProperty(JSObject* base, size_t offset)
+ void setNewProperty(DeprecatedPtr<JSObject> base, size_t offset)
{
m_type = NewProperty;
m_base = base;
@@ -60,7 +60,7 @@ namespace JSC {
}
Type type() const { return m_type; }
- JSObject* base() const { return m_base; }
+ JSObject* base() const { return m_base.get(); }
bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
@@ -70,7 +70,7 @@ namespace JSC {
}
private:
Type m_type;
- JSObject* m_base;
+ DeprecatedPtr<JSObject> m_base;
size_t m_offset;
bool m_isStrictMode;
};
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 31a1abe..95ce5e9 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -25,6 +25,7 @@
#include "Lexer.h"
#include "yarr/Yarr.h"
+#include "yarr/YarrJIT.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -230,11 +231,12 @@ void RegExp::matchCompareWithInterpreter(const UString& s, int startOffset, int*
#if ENABLE(YARR_JIT)
Yarr::YarrCodeBlock& codeBlock = m_representation->m_regExpJITCode;
- char jitAddr[20];
+ const size_t jitAddrSize = 20;
+ char jitAddr[jitAddrSize];
if (m_state == JITCode)
- sprintf(jitAddr, "fallback");
+ snprintf(jitAddr, jitAddrSize, "fallback");
else
- sprintf(jitAddr, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.getAddr()));
+ snprintf(jitAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.getAddr()));
#else
const char* jitAddr = "JIT Off";
#endif
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index 30d3eab..1b30514 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -100,10 +100,10 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObje
, d(adoptPtr(new RegExpConstructorPrivate))
{
// ECMA 15.10.5.1 RegExp.prototype
- putDirectWithoutTransition(exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
}
RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.cpp b/Source/JavaScriptCore/runtime/ScopeChain.cpp
index 54c5082..976cff6 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.cpp
+++ b/Source/JavaScriptCore/runtime/ScopeChain.cpp
@@ -35,12 +35,12 @@ void ScopeChainNode::print() const
{
ScopeChainIterator scopeEnd = end();
for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
- JSObject* o = *scopeIter;
+ DeprecatedPtr<JSObject> o = *scopeIter;
PropertyNameArray propertyNames(globalObject->globalExec());
o->getPropertyNames(globalObject->globalExec(), propertyNames);
PropertyNameArray::const_iterator propEnd = propertyNames.end();
- fprintf(stderr, "----- [scope %p] -----\n", o);
+ fprintf(stderr, "----- [scope %p] -----\n", o.get());
for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) {
Identifier name = *propIter;
fprintf(stderr, "%s, ", name.ustring().utf8().data());
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.h b/Source/JavaScriptCore/runtime/ScopeChain.h
index b104e75..11f3692 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.h
+++ b/Source/JavaScriptCore/runtime/ScopeChain.h
@@ -21,6 +21,7 @@
#ifndef ScopeChain_h
#define ScopeChain_h
+#include "WriteBarrier.h"
#include <wtf/FastAllocBase.h>
namespace JSC {
@@ -52,7 +53,6 @@ namespace JSC {
~ScopeChainNode()
{
next = 0;
- object = 0;
globalData = 0;
globalObject = 0;
globalThis = 0;
@@ -60,7 +60,7 @@ namespace JSC {
#endif
ScopeChainNode* next;
- JSObject* object;
+ DeprecatedPtr<JSObject> object;
JSGlobalData* globalData;
JSGlobalObject* globalObject;
JSObject* globalThis;
@@ -131,8 +131,8 @@ namespace JSC {
{
}
- JSObject* const & operator*() const { return m_node->object; }
- JSObject* const * operator->() const { return &(operator*()); }
+ DeprecatedPtr<JSObject> const & operator*() const { return m_node->object; }
+ DeprecatedPtr<JSObject> const * operator->() const { return &(operator*()); }
ScopeChainIterator& operator++() { m_node = m_node->next; return *this; }
@@ -195,7 +195,7 @@ namespace JSC {
ScopeChainNode* node() const { return m_node; }
- JSObject* top() const { return m_node->object; }
+ JSObject* top() const { return m_node->object.get(); }
ScopeChainIterator begin() const { return m_node->begin(); }
ScopeChainIterator end() const { return m_node->end(); }
diff --git a/Source/JavaScriptCore/runtime/ScopeChainMark.h b/Source/JavaScriptCore/runtime/ScopeChainMark.h
index 984d101..faa4824 100644
--- a/Source/JavaScriptCore/runtime/ScopeChainMark.h
+++ b/Source/JavaScriptCore/runtime/ScopeChainMark.h
@@ -28,7 +28,7 @@ namespace JSC {
inline void ScopeChain::markAggregate(MarkStack& markStack) const
{
for (ScopeChainNode* n = m_node; n; n = n->next)
- markStack.append(n->object);
+ markStack.append(&n->object);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.cpp b/Source/JavaScriptCore/runtime/SmallStrings.cpp
index 5614932..9b193f5 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/Source/JavaScriptCore/runtime/SmallStrings.cpp
@@ -35,9 +35,9 @@ namespace JSC {
static const unsigned numCharactersToStore = 0x100;
-static inline bool isMarked(JSString* string)
+static inline bool isMarked(JSCell* string)
{
- return string && Heap::isCellMarked(string);
+ return string && Heap::isMarked(string);
}
class SmallStringsStorage {
@@ -83,9 +83,9 @@ void SmallStrings::markChildren(MarkStack& markStack)
so, it's probably reasonable to mark the rest. If not, we clear the cache.
*/
- bool isAnyStringMarked = isMarked(m_emptyString);
+ bool isAnyStringMarked = isMarked(m_emptyString.get());
for (unsigned i = 0; i < numCharactersToStore && !isAnyStringMarked; ++i)
- isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
+ isAnyStringMarked = isMarked(m_singleCharacterStrings[i].get());
if (!isAnyStringMarked) {
clear();
@@ -93,10 +93,10 @@ void SmallStrings::markChildren(MarkStack& markStack)
}
if (m_emptyString)
- markStack.append(m_emptyString);
+ markStack.append(&m_emptyString);
for (unsigned i = 0; i < numCharactersToStore; ++i) {
if (m_singleCharacterStrings[i])
- markStack.append(m_singleCharacterStrings[i]);
+ markStack.append(&m_singleCharacterStrings[i]);
}
}
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h
index ac84fe8..ee795b6 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.h
+++ b/Source/JavaScriptCore/runtime/SmallStrings.h
@@ -27,6 +27,7 @@
#define SmallStrings_h
#include "UString.h"
+#include "WriteBarrier.h"
#include <wtf/FixedArray.h>
#include <wtf/OwnPtr.h>
@@ -47,13 +48,13 @@ namespace JSC {
{
if (!m_emptyString)
createEmptyString(globalData);
- return m_emptyString;
+ return m_emptyString.get();
}
JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
{
if (!m_singleCharacterStrings[character])
createSingleCharacterString(globalData, character);
- return m_singleCharacterStrings[character];
+ return m_singleCharacterStrings[character].get();
}
StringImpl* singleCharacterStringRep(unsigned char character);
@@ -63,14 +64,14 @@ namespace JSC {
unsigned count() const;
#if ENABLE(JIT)
- JSString** singleCharacterStrings() { return m_singleCharacterStrings.data(); }
+ JSCell** singleCharacterStrings() { return m_singleCharacterStrings[0].slot(); }
#endif
private:
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
- JSString* m_emptyString;
- FixedArray<JSString*, 0x100> m_singleCharacterStrings;
+ DeprecatedPtr<JSString> m_emptyString;
+ FixedArray<DeprecatedPtr<JSString>, 0x100> m_singleCharacterStrings;
OwnPtr<SmallStringsStorage> m_storage;
};
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index 101650c..604473b 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -53,7 +53,7 @@ StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObje
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, stringPrototype->classInfo()->className))
{
// ECMA 15.5.3.1 String.prototype
- putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
// ECMA 15.5.3.2 fromCharCode()
#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
@@ -62,7 +62,7 @@ StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObje
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
#endif
// no. of arguments for constructor
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
// ECMA 15.5.2
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index dc27618..eb9cfa3 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -30,21 +30,21 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::info = { "String", 0, 0, 0 };
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+ : JSWrapperObject(exec->globalData(), structure)
{
- setInternalValue(jsEmptyString(exec));
+ setInternalValue(exec->globalData(), jsEmptyString(exec));
}
-StringObject::StringObject(NonNullPassRefPtr<Structure> structure, JSString* string)
- : JSWrapperObject(structure)
+StringObject::StringObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, JSString* string)
+ : JSWrapperObject(globalData, structure)
{
- setInternalValue(string);
+ setInternalValue(globalData, string);
}
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
- : JSWrapperObject(structure)
+ : JSWrapperObject(exec->globalData(), structure)
{
- setInternalValue(jsString(exec, string));
+ setInternalValue(exec->globalData(), jsString(exec, string));
}
bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index e3add77..03488f5 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -53,7 +53,7 @@ namespace JSC {
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
- StringObject(NonNullPassRefPtr<Structure>, JSString*);
+ StringObject(JSGlobalData&, NonNullPassRefPtr<Structure>, JSString*);
};
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 8b3d056..545c93e 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -134,9 +134,9 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec
StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
: StringObject(exec, structure)
{
- putAnonymousValue(0, globalObject);
+ putAnonymousValue(exec->globalData(), 0, globalObject);
// The constructor will be added later, after StringConstructor has been built
- putDirectWithoutTransition(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+ putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
}
bool StringPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 0179eed..e8f5d7a 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -242,7 +242,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo, unsigned anony
m_transitions.m_singleTransition = 0;
ASSERT(m_prototype);
- ASSERT(m_prototype.isObject() || m_prototype.isNull());
+ ASSERT(m_prototype->isObject() || m_prototype->isNull());
#ifndef NDEBUG
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -476,7 +476,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
return transition.release();
}
- RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo(), structure->anonymousSlotCount());
+ RefPtr<Structure> transition = create(structure->m_prototype.get(), structure->typeInfo(), structure->anonymousSlotCount());
transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
transition->m_previous = structure;
@@ -595,7 +595,7 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di
{
ASSERT(!structure->isUncacheableDictionary());
- RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo(), structure->anonymousSlotCount());
+ RefPtr<Structure> transition = create(structure->m_prototype.get(), structure->typeInfo(), structure->anonymousSlotCount());
transition->m_dictionaryKind = kind;
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
@@ -620,7 +620,7 @@ PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* st
return toDictionaryTransition(structure, UncachedDictionaryKind);
}
-PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
+PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObject* object)
{
ASSERT(isDictionary());
if (isUncacheableDictionary()) {
@@ -651,7 +651,7 @@ PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
// Copy the original property values into their final locations
for (unsigned i = 0; i < propertyCount; i++)
- object->putDirectOffset(anonymousSlotCount + i, values[i]);
+ object->putDirectOffset(globalData, anonymousSlotCount + i, values[i]);
if (m_propertyTable->deletedOffsets) {
delete m_propertyTable->deletedOffsets;
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index f480051..77724ac 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -80,7 +80,7 @@ namespace JSC {
static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*);
static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*);
- PassRefPtr<Structure> flattenDictionaryStructure(JSObject*);
+ PassRefPtr<Structure> flattenDictionaryStructure(JSGlobalData&, JSObject*);
~Structure();
@@ -94,7 +94,8 @@ namespace JSC {
const TypeInfo& typeInfo() const { return m_typeInfo; }
- JSValue storedPrototype() const { return m_prototype; }
+ JSValue storedPrototype() const { return m_prototype.get(); }
+ DeprecatedPtr<Unknown>* storedPrototypeSlot() { return &m_prototype; }
JSValue prototypeForLookup(ExecState*) const;
StructureChain* prototypeChain(ExecState*) const;
@@ -206,7 +207,7 @@ namespace JSC {
TypeInfo m_typeInfo;
- JSValue m_prototype;
+ DeprecatedPtr<Unknown> m_prototype;
mutable RefPtr<StructureChain> m_cachedPrototypeChain;
RefPtr<Structure> m_previous;
diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp
index 085876c..e4523c3 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp
@@ -38,7 +38,7 @@ StructureChain::StructureChain(Structure* head)
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
++size;
- m_vector.set(new RefPtr<Structure>[size + 1]);
+ m_vector = adoptArrayPtr(new RefPtr<Structure>[size + 1]);
size_t i = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index 316794f..7bf4503 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -46,22 +46,31 @@ class WeakGCMap {
*/
public:
- typedef typename HashMap<KeyType, MappedType>::iterator iterator;
- typedef typename HashMap<KeyType, MappedType>::const_iterator const_iterator;
+ typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::iterator iterator;
+ typedef typename HashMap<KeyType, DeprecatedPtr<MappedType> >::const_iterator const_iterator;
bool isEmpty() { return m_map.isEmpty(); }
void clear() { m_map.clear(); }
- MappedType get(const KeyType& key) const;
- pair<iterator, bool> set(const KeyType&, const MappedType&);
- MappedType take(const KeyType& key);
+ MappedType* get(const KeyType&) const;
+ pair<iterator, bool> set(const KeyType&, MappedType*);
+ MappedType* take(const KeyType&);
// These unchecked functions provide access to a value even if the value's
// mark bit is not set. This is used, among other things, to retrieve values
// during the GC mark phase, which begins by clearing all mark bits.
-
- MappedType uncheckedGet(const KeyType& key) const { return m_map.get(key); }
- bool uncheckedRemove(const KeyType&, const MappedType&);
+
+ size_t uncheckedSize() { return m_map.size(); }
+
+ MappedType* uncheckedGet(const KeyType& key) const { return m_map.get(key).get(); }
+ DeprecatedPtr<MappedType>* uncheckedGetSlot(const KeyType& key)
+ {
+ iterator iter = m_map.find(key);
+ if (iter == m_map.end())
+ return 0;
+ return &iter->second;
+ }
+ bool uncheckedRemove(const KeyType&, MappedType*);
iterator uncheckedBegin() { return m_map.begin(); }
iterator uncheckedEnd() { return m_map.end(); }
@@ -69,51 +78,54 @@ public:
const_iterator uncheckedBegin() const { return m_map.begin(); }
const_iterator uncheckedEnd() const { return m_map.end(); }
+ bool isValid(iterator it) const { return Heap::isMarked(it->second.get()); }
+ bool isValid(const_iterator it) const { return Heap::isMarked(it->second.get()); }
+
private:
- HashMap<KeyType, MappedType> m_map;
+ HashMap<KeyType, DeprecatedPtr<MappedType> > m_map;
};
template<typename KeyType, typename MappedType>
-inline MappedType WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const
+inline MappedType* WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const
{
- MappedType result = m_map.get(key);
- if (result == HashTraits<MappedType>::emptyValue())
+ MappedType* result = m_map.get(key).get();
+ if (result == HashTraits<MappedType*>::emptyValue())
return result;
- if (!Heap::isCellMarked(result))
- return HashTraits<MappedType>::emptyValue();
+ if (!Heap::isMarked(result))
+ return HashTraits<MappedType*>::emptyValue();
return result;
}
template<typename KeyType, typename MappedType>
-MappedType WeakGCMap<KeyType, MappedType>::take(const KeyType& key)
+MappedType* WeakGCMap<KeyType, MappedType>::take(const KeyType& key)
{
- MappedType result = m_map.take(key);
- if (result == HashTraits<MappedType>::emptyValue())
+ MappedType* result = m_map.take(key).get();
+ if (result == HashTraits<MappedType*>::emptyValue())
return result;
- if (!Heap::isCellMarked(result))
- return HashTraits<MappedType>::emptyValue();
+ if (!Heap::isMarked(result))
+ return HashTraits<MappedType*>::emptyValue();
return result;
}
template<typename KeyType, typename MappedType>
-pair<typename HashMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, const MappedType& value)
+pair<typename WeakGCMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, MappedType* value)
{
- Heap::markCell(value); // If value is newly allocated, it's not marked, so mark it now.
+ Heap::setMarked(value); // If value is newly allocated, it's not marked, so mark it now.
pair<iterator, bool> result = m_map.add(key, value);
if (!result.second) { // pre-existing entry
- result.second = !Heap::isCellMarked(result.first->second);
+ result.second = !Heap::isMarked(result.first->second.get());
result.first->second = value;
}
return result;
}
template<typename KeyType, typename MappedType>
-bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, const MappedType& value)
+bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, MappedType* value)
{
iterator it = m_map.find(key);
if (it == m_map.end())
return false;
- if (it->second != value)
+ if (it->second.get() != value)
return false;
m_map.remove(it);
return true;
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
new file mode 100644
index 0000000..64150ed
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WriteBarrier_h
+#define WriteBarrier_h
+
+#include "JSValue.h"
+
+namespace JSC {
+class JSCell;
+class JSGlobalData;
+
+typedef enum { } Unknown;
+
+template <class T> class DeprecatedPtr {
+public:
+ DeprecatedPtr() : m_cell(0) { }
+ DeprecatedPtr(T* cell) : m_cell(reinterpret_cast<JSCell*>(cell)) { }
+ T* get() const { return reinterpret_cast<T*>(m_cell); }
+ T* operator*() const { return static_cast<T*>(m_cell); }
+ T* operator->() const { return static_cast<T*>(m_cell); }
+
+ JSCell** slot() { return &m_cell; }
+
+ typedef T* (DeprecatedPtr::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const { return m_cell ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+
+ bool operator!() const { return !m_cell; }
+
+protected:
+ JSCell* m_cell;
+};
+
+template <> class DeprecatedPtr<Unknown> {
+public:
+ DeprecatedPtr() { }
+ DeprecatedPtr(JSValue value) : m_value(value) { }
+ DeprecatedPtr(JSCell* value) : m_value(value) { }
+ const JSValue& get() const { return m_value; }
+ const JSValue* operator*() const { return &m_value; }
+ const JSValue* operator->() const { return &m_value; }
+
+ JSValue* slot() { return &m_value; }
+
+ typedef JSValue (DeprecatedPtr::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const { return m_value ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+ bool operator!() const { return !m_value; }
+
+private:
+ JSValue m_value;
+};
+
+template <typename T> struct WriteBarrierCheck {
+ static const bool IsJSValue = false;
+};
+
+template <> struct WriteBarrierCheck<JSValue> {
+ static const bool IsJSValue = true;
+};
+
+template <typename T> class WriteBarrierBase {
+public:
+ COMPILE_ASSERT(!WriteBarrierCheck<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
+ void set(JSGlobalData&, const JSCell*, T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
+
+ T* get() const { return reinterpret_cast<T*>(m_cell); }
+ T* operator*() const { return static_cast<T*>(m_cell); }
+ T* operator->() const { return static_cast<T*>(m_cell); }
+ void clear() { m_cell = 0; }
+
+ JSCell** slot() { return &m_cell; }
+
+ typedef T* (WriteBarrierBase::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const { return m_cell ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+
+ bool operator!() const { return !m_cell; }
+
+ void setWithoutWriteBarrier(T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
+
+protected:
+ JSCell* m_cell;
+};
+
+template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
+public:
+ WriteBarrier() { this->m_cell = 0; }
+ WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
+ {
+ this->set(globalData, owner, value);
+ }
+
+};
+
+template <> class WriteBarrierBase<Unknown> {
+public:
+ void set(JSGlobalData&, const JSCell*, JSValue value) { m_value = JSValue::encode(value); }
+ void setWithoutWriteBarrier(JSValue value) { m_value = JSValue::encode(value); }
+ JSValue get() const { return JSValue::decode(m_value); }
+ void clear() { m_value = JSValue::encode(JSValue()); }
+ void setUndefined() { m_value = JSValue::encode(jsUndefined()); }
+ bool isNumber() const { return get().isNumber(); }
+ bool isGetterSetter() const { return get().isGetterSetter(); }
+
+ JSValue* slot()
+ {
+ union {
+ EncodedJSValue* v;
+ JSValue* slot;
+ } u;
+ u.v = &m_value;
+ return u.slot;
+ }
+
+ typedef JSValue (WriteBarrierBase::*UnspecifiedBoolType);
+ operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+ bool operator!() const { return !get(); }
+
+protected:
+ EncodedJSValue m_value;
+};
+
+template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
+public:
+ WriteBarrier() { m_value = JSValue::encode(JSValue()); }
+ WriteBarrier(JSGlobalData& globalData, const JSCell* owner, JSValue value)
+ {
+ this->set(globalData, owner, value);
+ }
+};
+
+template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+template <typename U, typename V> inline bool operator==(const WriteBarrierBase<U>& lhs, const WriteBarrierBase<V>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+}
+
+#endif // WriteBarrier_h