summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/JavaScriptCore/runtime
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h8
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp42
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.cpp58
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.h101
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.h6
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.h10
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/ExceptionHelpers.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h37
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h5
-rw-r--r--Source/JavaScriptCore/runtime/Heap.cpp408
-rw-r--r--Source/JavaScriptCore/runtime/Heap.h178
-rw-r--r--Source/JavaScriptCore/runtime/InitializeThreading.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSAPIValueWrapper.h5
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp28
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h9
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.h7
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h72
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h8
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp103
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h47
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp88
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h56
-rw-r--r--Source/JavaScriptCore/runtime/JSImmediate.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/JSImmediate.h568
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSNumberCell.cpp40
-rw-r--r--Source/JavaScriptCore/runtime/JSNumberCell.h171
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp73
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h132
-rw-r--r--Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp19
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h29
-rw-r--r--Source/JavaScriptCore/runtime/JSType.h7
-rw-r--r--Source/JavaScriptCore/runtime/JSTypeInfo.h1
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h545
-rw-r--r--Source/JavaScriptCore/runtime/JSValueInlineMethods.h532
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h14
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h8
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.h10
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.cpp491
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.h73
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.cpp127
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.h309
-rw-r--r--Source/JavaScriptCore/runtime/MarkStackPosix.cpp43
-rw-r--r--Source/JavaScriptCore/runtime/MarkStackSymbian.cpp38
-rw-r--r--Source/JavaScriptCore/runtime/MarkStackWin.cpp44
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.cpp91
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.h224
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.cpp166
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.h172
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.h8
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h5
-rw-r--r--Source/JavaScriptCore/runtime/PropertyMapHashTable.h31
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.h6
-rw-r--r--Source/JavaScriptCore/runtime/StrictEvalActivation.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h8
-rw-r--r--Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h4
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp332
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h165
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.h16
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h57
-rw-r--r--Source/JavaScriptCore/runtime/UString.h5
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h82
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCPtr.h104
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h118
133 files changed, 1738 insertions, 4797 deletions
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 950bb4e..b5aa46b 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -92,7 +92,7 @@ namespace JSC {
d->registers = &activation->registerAt(0);
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -143,7 +143,7 @@ namespace JSC {
}
inline Arguments::Arguments(CallFrame* callFrame)
- : JSNonFinalObject(callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
, d(adoptPtr(new ArgumentsData))
{
ASSERT(inherits(&s_info));
@@ -185,7 +185,7 @@ namespace JSC {
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
- : JSNonFinalObject(callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
, d(adoptPtr(new ArgumentsData))
{
ASSERT(inherits(&s_info));
@@ -247,7 +247,7 @@ namespace JSC {
int registerOffset = m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, m_registers - registerOffset, registerArraySize);
+ OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, m_registers - registerOffset, registerArraySize, m_numParametersMinusThis + 1);
WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset;
setRegisters(registers, registerArray.release());
}
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index e0f4b23..050e989 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -37,7 +37,7 @@ ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
static EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*);
-ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* functionStructure)
+ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ArrayPrototype* arrayPrototype, Structure* functionStructure)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
@@ -59,7 +59,7 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi
uint32_t n = args.at(0).toUInt32(exec);
if (n != args.at(0).toNumber(exec))
return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer."));
- return new (exec) JSArray(globalObject->arrayStructure(), n, CreateInitialized);
+ return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), n, CreateInitialized);
}
// otherwise the array is constructed with the arguments in it
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h
index 5e1408f..97b26c5 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ArrayConstructor : public InternalFunction {
public:
- ArrayConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ArrayPrototype*, Structure*);
+ ArrayConstructor(ExecState*, JSGlobalObject*, Structure*, ArrayPrototype*, Structure*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index fdbcd95..29caece 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -114,8 +114,8 @@ const ClassInfo ArrayPrototype::s_info = {"Array", &JSArray::s_info, 0, ExecStat
*/
// ECMA 15.4.4
-ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
- : JSArray(structure)
+ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, Structure* structure)
+ : JSArray(globalObject->globalData(), structure)
{
ASSERT(inherits(&s_info));
putAnonymousValue(globalObject->globalData(), 0, globalObject);
@@ -514,10 +514,14 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
JSValue iObj = thisObj->get(exec, i);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
unsigned themin = i;
JSValue minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
JSValue jObj = thisObj->get(exec, j);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
double compareResult;
if (jObj.isUndefined())
compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
@@ -570,7 +574,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
deleteCount = static_cast<unsigned>(deleteDouble);
}
- JSArray* resObj = new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact);
+ JSArray* resObj = new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact);
JSValue result = resObj;
JSGlobalData& globalData = exec->globalData();
for (unsigned k = 0; k < deleteCount; k++)
@@ -682,20 +686,19 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
}
for (; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
-
if (!thisObj->getPropertySlot(exec, k, slot))
continue;
-
JSValue v = slot.getValue(exec, k);
- MarkedArgumentBuffer eachArguments;
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
eachArguments.append(jsNumber(k));
eachArguments.append(thisObj);
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
-
if (result.toBoolean(exec))
resultArray->put(exec, filterIndex++, v);
}
@@ -739,15 +742,19 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
PropertySlot slot(thisObj);
if (!thisObj->getPropertySlot(exec, k, slot))
continue;
-
JSValue v = slot.getValue(exec, k);
- MarkedArgumentBuffer eachArguments;
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
eachArguments.append(jsNumber(k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
resultArray->put(exec, k, result);
}
@@ -797,18 +804,18 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
}
for (; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
-
if (!thisObj->getPropertySlot(exec, k, slot))
continue;
MarkedArgumentBuffer eachArguments;
-
eachArguments.append(slot.getValue(exec, k));
eachArguments.append(jsNumber(k));
eachArguments.append(thisObj);
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (!predicateResult) {
result = jsBoolean(false);
break;
@@ -860,6 +867,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
eachArguments.append(jsNumber(k));
eachArguments.append(thisObj);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
call(exec, function, callType, callData, applyThis, eachArguments);
}
return JSValue::encode(jsUndefined());
@@ -910,8 +920,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
eachArguments.append(jsNumber(k));
eachArguments.append(thisObj);
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (predicateResult) {
result = jsBoolean(true);
break;
@@ -979,6 +991,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
for (; i < length && !exec->hadException(); ++i) {
JSValue prop = getProperty(exec, thisObj, i);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
if (!prop)
continue;
@@ -1051,6 +1065,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
for (; i < length && !exec->hadException(); ++i) {
unsigned idx = length - i - 1;
JSValue prop = getProperty(exec, thisObj, idx);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
if (!prop)
continue;
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h
index 96641bd..6dadf51 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h
@@ -28,14 +28,14 @@ namespace JSC {
class ArrayPrototype : public JSArray {
public:
- explicit ArrayPrototype(JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ explicit ArrayPrototype(JSGlobalObject*, Structure*);
bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index 0f6a646..df7b7f6 100644
--- a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -39,7 +39,7 @@ namespace JSC {
, m_object(object)
{
if (!m_object->structure()->isDictionary())
- m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure()));
+ m_object->setStructure(globalData, Structure::toCacheableDictionaryTransition(globalData, m_object->structure()));
}
~BatchedTransitionOptimizer()
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index e5b0f3d..a1a4ed4 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -28,7 +28,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
-BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype)
+BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, BooleanPrototype* booleanPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, booleanPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h
index 2550b3b..fa0d05e 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class BooleanConstructor : public InternalFunction {
public:
- BooleanConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, BooleanPrototype*);
+ BooleanConstructor(ExecState*, JSGlobalObject*, Structure*, BooleanPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index 2945c0e..e24a30a 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::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0 };
-BooleanObject::BooleanObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+BooleanObject::BooleanObject(JSGlobalData& globalData, Structure* structure)
+ : JSWrapperObject(globalData, structure)
{
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index ef2d403..def44b4 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -27,11 +27,11 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
public:
- explicit BooleanObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure>);
+ explicit BooleanObject(JSGlobalData&, Structure*);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
index d0a64af..20990e1 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -37,7 +37,7 @@ static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*);
// ECMA 15.6.4
-BooleanPrototype::BooleanPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
+BooleanPrototype::BooleanPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure)
: BooleanObject(exec->globalData(), structure)
{
setInternalValue(exec->globalData(), jsBoolean(false));
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.h b/Source/JavaScriptCore/runtime/BooleanPrototype.h
index d6d3d9f..5ccbd2b 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.h
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class BooleanPrototype : public BooleanObject {
public:
- BooleanPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure);
+ BooleanPrototype(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.cpp b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
deleted file mode 100644
index 8872023..0000000
--- a/Source/JavaScriptCore/runtime/ConservativeSet.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 ConservativeRoots::grow()
-{
- size_t newCapacity = m_capacity == inlineCapacity ? nonInlineCapacity : m_capacity * 2;
- JSCell** newRoots = static_cast<JSCell**>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));
- memcpy(newRoots, m_roots, m_size * sizeof(JSCell*));
- if (m_roots != m_inlineRoots)
- OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
- m_capacity = newCapacity;
- m_roots = newRoots;
-}
-
-void ConservativeRoots::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)
- add(*it);
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.h b/Source/JavaScriptCore/runtime/ConservativeSet.h
deleted file mode 100644
index d078606..0000000
--- a/Source/JavaScriptCore/runtime/ConservativeSet.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 ConservativeRoots_h
-#define ConservativeRoots_h
-
-#include "Heap.h"
-#include <wtf/OSAllocator.h>
-#include <wtf/Vector.h>
-
-namespace JSC {
-
-class JSCell;
-class Heap;
-
-// May contain duplicates.
-
-class ConservativeRoots {
-public:
- ConservativeRoots(Heap*);
- ~ConservativeRoots();
-
- void add(void*);
- void add(void* begin, void* end);
-
- size_t size();
- JSCell** roots();
-
-private:
- static const size_t inlineCapacity = 128;
- static const size_t nonInlineCapacity = 8192 / sizeof(JSCell*);
-
- void grow();
-
- Heap* m_heap;
- JSCell** m_roots;
- size_t m_size;
- size_t m_capacity;
- JSCell* m_inlineRoots[inlineCapacity];
-};
-
-inline ConservativeRoots::ConservativeRoots(Heap* heap)
- : m_heap(heap)
- , m_roots(m_inlineRoots)
- , m_size(0)
- , m_capacity(inlineCapacity)
-{
-}
-
-inline ConservativeRoots::~ConservativeRoots()
-{
- if (m_roots != m_inlineRoots)
- OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
-}
-
-inline void ConservativeRoots::add(void* p)
-{
- if (!m_heap->contains(p))
- return;
-
- if (m_size == m_capacity)
- grow();
-
- m_roots[m_size++] = reinterpret_cast<JSCell*>(p);
-}
-
-inline size_t ConservativeRoots::size()
-{
- return m_size;
-}
-
-inline JSCell** ConservativeRoots::roots()
-{
- return m_roots;
-}
-
-} // namespace JSC
-
-#endif // ConservativeRoots_h
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index 0a06148..9bbb688 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -57,7 +57,7 @@ static EncodedJSValue JSC_HOST_CALL dateParse(ExecState*);
static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*);
static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*);
-DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure, DatePrototype* datePrototype)
+DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure, DatePrototype* datePrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, datePrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, datePrototype, DontEnum | DontDelete | ReadOnly);
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.h b/Source/JavaScriptCore/runtime/DateConstructor.h
index bd529f1..23a0311 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.h
+++ b/Source/JavaScriptCore/runtime/DateConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class DateConstructor : public InternalFunction {
public:
- DateConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure, DatePrototype*);
+ DateConstructor(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure, DatePrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/Source/JavaScriptCore/runtime/DateInstance.cpp b/Source/JavaScriptCore/runtime/DateInstance.cpp
index 74adda4..d8ca072 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.cpp
+++ b/Source/JavaScriptCore/runtime/DateInstance.cpp
@@ -34,15 +34,15 @@ namespace JSC {
const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, 0};
-DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+DateInstance::DateInstance(ExecState* exec, Structure* structure)
+ : JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsNaN());
}
-DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure, double time)
- : JSWrapperObject(structure)
+DateInstance::DateInstance(ExecState* exec, Structure* structure, double time)
+ : JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
diff --git a/Source/JavaScriptCore/runtime/DateInstance.h b/Source/JavaScriptCore/runtime/DateInstance.h
index d0dcf0b..6195c85 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.h
+++ b/Source/JavaScriptCore/runtime/DateInstance.h
@@ -31,8 +31,8 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
public:
- DateInstance(ExecState*, NonNullPassRefPtr<Structure>, double);
- explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>);
+ DateInstance(ExecState*, Structure*, double);
+ explicit DateInstance(ExecState*, Structure*);
double internalNumber() const { return internalValue().uncheckedGetNumber(); }
@@ -52,7 +52,7 @@ namespace JSC {
return calculateGregorianDateTimeUTC(exec);
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 314baa4..444fa98 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -429,7 +429,7 @@ const ClassInfo DatePrototype::s_info = {"Date", &DateInstance::s_info, 0, ExecS
// ECMA 15.9.4
-DatePrototype::DatePrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
+DatePrototype::DatePrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: DateInstance(exec, structure)
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.h b/Source/JavaScriptCore/runtime/DatePrototype.h
index 0ebbedc..2e1030d 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.h
+++ b/Source/JavaScriptCore/runtime/DatePrototype.h
@@ -29,14 +29,14 @@ namespace JSC {
class DatePrototype : public DateInstance {
public:
- DatePrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ DatePrototype(ExecState*, JSGlobalObject*, Structure*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index b84f5ea..7eda19f 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -167,7 +167,7 @@ JSObject* throwSyntaxError(ExecState* exec)
class StrictModeTypeErrorFunction : public InternalFunction {
public:
- StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& message)
+ StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& message)
: InternalFunction(&exec->globalData(), globalObject, structure, exec->globalData().propertyNames->emptyIdentifier)
, m_message(message)
{
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index 7f4f82c..df112dd 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -29,7 +29,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
-ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ErrorPrototype* errorPrototype)
+ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ErrorPrototype* errorPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, errorPrototype->classInfo()->className))
{
// ECMA 15.11.3.1 Error.prototype
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.h b/Source/JavaScriptCore/runtime/ErrorConstructor.h
index 3d0d706..ceec005 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.h
@@ -30,7 +30,7 @@ namespace JSC {
class ErrorConstructor : public InternalFunction {
public:
- ErrorConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ErrorPrototype*);
+ ErrorConstructor(ExecState*, JSGlobalObject*, Structure*, ErrorPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
index 0db2af8..ed95ba4 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -25,28 +25,28 @@ namespace JSC {
const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, 0 };
-ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure)
- : JSNonFinalObject(structure)
+ErrorInstance::ErrorInstance(JSGlobalData* globalData, Structure* structure)
+ : JSNonFinalObject(*globalData, structure)
, m_appendSourceToMessage(false)
{
ASSERT(inherits(&s_info));
putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, ""));
}
-ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message)
- : JSNonFinalObject(structure)
+ErrorInstance::ErrorInstance(JSGlobalData* globalData, Structure* structure, const UString& message)
+ : JSNonFinalObject(*globalData, structure)
, m_appendSourceToMessage(false)
{
ASSERT(inherits(&s_info));
putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
}
-ErrorInstance* ErrorInstance::create(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message)
+ErrorInstance* ErrorInstance::create(JSGlobalData* globalData, Structure* structure, const UString& message)
{
return new (globalData) ErrorInstance(globalData, structure, message);
}
-ErrorInstance* ErrorInstance::create(ExecState* exec, NonNullPassRefPtr<Structure> structure, JSValue message)
+ErrorInstance* ErrorInstance::create(ExecState* exec, Structure* structure, JSValue message)
{
if (message.isUndefined())
return new (exec) ErrorInstance(&exec->globalData(), structure);
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index 82dbf0f..afcf158 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -29,13 +29,13 @@ namespace JSC {
public:
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- static ErrorInstance* create(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&);
- static ErrorInstance* create(ExecState* exec, NonNullPassRefPtr<Structure>, JSValue message);
+ static ErrorInstance* create(JSGlobalData*, Structure*, const UString&);
+ static ErrorInstance* create(ExecState*, Structure*, JSValue message);
bool appendSourceToMessage() { return m_appendSourceToMessage; }
@@ -45,8 +45,8 @@ namespace JSC {
virtual bool isErrorInstance() const { return true; }
protected:
- explicit ErrorInstance(JSGlobalData*, NonNullPassRefPtr<Structure>);
- explicit ErrorInstance(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&);
+ explicit ErrorInstance(JSGlobalData*, Structure*);
+ explicit ErrorInstance(JSGlobalData*, Structure*, const UString&);
bool m_appendSourceToMessage;
};
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index e13251c..a57e947 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -35,7 +35,7 @@ ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*);
// ECMA 15.9.4
-ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
+ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure)
: ErrorInstance(&exec->globalData(), structure)
{
// The constructor will be added later in ErrorConstructor's constructor
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.h b/Source/JavaScriptCore/runtime/ErrorPrototype.h
index 3c2fed3..9437d3a 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.h
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class ErrorPrototype : public ErrorInstance {
public:
- ErrorPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure);
+ ErrorPrototype(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
index d3c637e..1d74315 100644
--- a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -44,7 +44,7 @@ namespace JSC {
class InterruptedExecutionError : public JSNonFinalObject {
public:
InterruptedExecutionError(JSGlobalData* globalData)
- : JSNonFinalObject(globalData->interruptedExecutionErrorStructure)
+ : JSNonFinalObject(*globalData, globalData->interruptedExecutionErrorStructure.get())
{
}
@@ -61,7 +61,7 @@ JSObject* createInterruptedExecutionException(JSGlobalData* globalData)
class TerminatedExecutionError : public JSNonFinalObject {
public:
TerminatedExecutionError(JSGlobalData* globalData)
- : JSNonFinalObject(globalData->terminatedExecutionErrorStructure)
+ : JSNonFinalObject(*globalData, globalData->terminatedExecutionErrorStructure.get())
{
}
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index a059ed2..fa14ad5 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -40,13 +40,15 @@
namespace JSC {
+const ClassInfo ExecutableBase::s_info = { "Executable", 0, 0, 0 };
+
+const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0 };
+
NativeExecutable::~NativeExecutable()
{
}
-VPtrHackExecutable::~VPtrHackExecutable()
-{
-}
+const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0 };
EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
: ScriptExecutable(exec->globalData().evalExecutableStructure.get(), exec, source, inStrictContext)
@@ -57,6 +59,8 @@ EvalExecutable::~EvalExecutable()
{
}
+const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0 };
+
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
: ScriptExecutable(exec->globalData().programExecutableStructure.get(), exec, source, false)
{
@@ -66,6 +70,8 @@ ProgramExecutable::~ProgramExecutable()
{
}
+const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0 };
+
FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
: ScriptExecutable(globalData->functionExecutableStructure.get(), globalData, source, inStrictContext)
, m_numCapturedVariables(0)
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index f15df07..fbe33cf 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -52,8 +52,8 @@ namespace JSC {
static const int NUM_PARAMETERS_NOT_COMPILED = -1;
public:
- ExecutableBase(Structure* structure, int numParameters)
- : JSCell(structure)
+ ExecutableBase(JSGlobalData& globalData, Structure* structure, int numParameters)
+ : JSCell(globalData, structure)
, m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
@@ -65,10 +65,11 @@ namespace JSC {
return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, &s_info); }
protected:
static const unsigned StructureFlags = 0;
+ static const ClassInfo s_info;
int m_numParametersForCall;
int m_numParametersForConstruct;
@@ -115,10 +116,12 @@ namespace JSC {
NativeFunction function() { return m_function; }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(LeafType, StructureFlags), AnonymousSlotCount, &s_info); }
+
private:
#if ENABLE(JIT)
NativeExecutable(JSGlobalData& globalData, JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
- : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
+ : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -129,7 +132,7 @@ namespace JSC {
}
#else
NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
- : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
+ : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -140,22 +143,13 @@ namespace JSC {
// Probably should be a NativeConstructor, but this will currently require rewriting the JIT
// trampoline. It may be easier to make NativeFunction be passed 'this' as a part of the ArgList.
NativeFunction m_constructor;
- };
-
- class VPtrHackExecutable : public ExecutableBase {
- public:
- VPtrHackExecutable(Structure* structure)
- : ExecutableBase(structure, NUM_PARAMETERS_IS_HOST)
- {
- }
-
- ~VPtrHackExecutable();
+ static const ClassInfo s_info;
};
class ScriptExecutable : public ExecutableBase {
public:
ScriptExecutable(Structure* structure, JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
+ : ExecutableBase(*globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -169,7 +163,7 @@ namespace JSC {
}
ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
+ : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -238,10 +232,11 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
+ static const ClassInfo s_info;
EvalExecutable(ExecState*, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
@@ -284,10 +279,11 @@ namespace JSC {
}
#endif
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
+ static const ClassInfo s_info;
ProgramExecutable(ExecState*, const SourceCode&);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
@@ -376,7 +372,7 @@ namespace JSC {
void discardCode();
void markChildren(MarkStack&);
static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
@@ -386,6 +382,7 @@ namespace JSC {
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
+ static const ClassInfo s_info;
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index a9f0a06..9e7d8d5 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -37,7 +37,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
-FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
+FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, FunctionPrototype* functionPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, functionPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h
index 7f21b20..31a04c9 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class FunctionConstructor : public InternalFunction {
public:
- FunctionConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, FunctionPrototype*);
+ FunctionConstructor(ExecState*, JSGlobalObject*, Structure*, FunctionPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index c2d8ad3..e2a4941 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -37,7 +37,7 @@ static EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*);
-FunctionPrototype::FunctionPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
+FunctionPrototype::FunctionPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: InternalFunction(&exec->globalData(), globalObject, structure, exec->propertyNames().nullIdentifier)
{
putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.h b/Source/JavaScriptCore/runtime/FunctionPrototype.h
index 447f00b..ab708dd 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.h
@@ -27,10 +27,10 @@ namespace JSC {
class FunctionPrototype : public InternalFunction {
public:
- FunctionPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ FunctionPrototype(ExecState*, JSGlobalObject*, Structure*);
void addFunctionProperties(ExecState*, JSGlobalObject*, Structure* functionStructure, JSFunction** callFunction, JSFunction** applyFunction);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto)
{
return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index 8241275..a222c7a 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -26,6 +26,7 @@
#include "JSCell.h"
#include "CallFrame.h"
+#include "Structure.h"
namespace JSC {
@@ -37,7 +38,7 @@ namespace JSC {
friend class JIT;
public:
GetterSetter(ExecState* exec)
- : JSCell(exec->globalData().getterSetterStructure.get())
+ : JSCell(exec->globalData(), exec->globalData().getterSetterStructure.get())
{
}
@@ -47,7 +48,7 @@ namespace JSC {
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(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount, 0);
}
diff --git a/Source/JavaScriptCore/runtime/Heap.cpp b/Source/JavaScriptCore/runtime/Heap.cpp
deleted file mode 100644
index e3ef8bb..0000000
--- a/Source/JavaScriptCore/runtime/Heap.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * 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
- *
- */
-
-#include "config.h"
-#include "Heap.h"
-
-#include "CodeBlock.h"
-#include "ConservativeSet.h"
-#include "GCActivityCallback.h"
-#include "Interpreter.h"
-#include "JSGlobalData.h"
-#include "JSGlobalObject.h"
-#include "JSLock.h"
-#include "JSONObject.h"
-#include "Tracing.h"
-#include <algorithm>
-
-#define COLLECT_ON_EVERY_SLOW_ALLOCATION 0
-
-using namespace std;
-
-namespace JSC {
-
-const size_t minBytesPerCycle = 512 * 1024;
-
-Heap::Heap(JSGlobalData* globalData)
- : m_operationInProgress(NoOperation)
- , m_markedSpace(globalData)
- , m_markListSet(0)
- , m_activityCallback(DefaultGCActivityCallback::create(this))
- , m_globalData(globalData)
- , m_machineThreads(this)
- , m_markStack(globalData->jsArrayVPtr)
- , m_handleHeap(globalData)
- , m_extraCost(0)
-{
- m_markedSpace.setHighWaterMark(minBytesPerCycle);
- (*m_activityCallback)();
-}
-
-Heap::~Heap()
-{
- // The destroy function must already have been called, so assert this.
- ASSERT(!m_globalData);
-}
-
-void Heap::destroy()
-{
- JSLock lock(SilenceAssertionsOnly);
-
- if (!m_globalData)
- return;
-
- ASSERT(!m_globalData->dynamicGlobalObject);
- ASSERT(m_operationInProgress == NoOperation);
-
- // The global object is not GC protected at this point, so sweeping may delete it
- // (and thus the global data) before other objects that may use the global data.
- RefPtr<JSGlobalData> protect(m_globalData);
-
-#if ENABLE(JIT)
- m_globalData->jitStubs->clearHostFunctionStubs();
-#endif
-
- delete m_markListSet;
- m_markListSet = 0;
- m_markedSpace.clearMarks();
- m_handleHeap.clearWeakPointers();
- m_markedSpace.destroy();
-
- m_globalData = 0;
-}
-
-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
- // that hold on to a great deal of memory that's not in the form of other JS values,
- // that is not good enough - in some cases a lot of those objects can pile up and
- // use crazy amounts of memory without a GC happening. So we track these extra
- // memory costs. Only unusually large objects are noted, and we only keep track
- // of this extra cost until the next GC. In garbage collected languages, most values
- // are either very short lived temporaries, or have extremely long lifetimes. So
- // 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.highWaterMark() / 2)
- collectAllGarbage();
- m_extraCost += cost;
-}
-
-void* Heap::allocateSlowCase(size_t bytes)
-{
- ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
- ASSERT(JSLock::lockCount() > 0);
- ASSERT(JSLock::currentThreadIsHoldingLock());
- ASSERT(bytes <= MarkedSpace::maxCellSize);
- ASSERT(m_operationInProgress == NoOperation);
-
-#if COLLECT_ON_EVERY_SLOW_ALLOCATION
- collectAllGarbage();
- ASSERT(m_operationInProgress == NoOperation);
-#endif
-
- reset(DoNotSweep);
-
- m_operationInProgress = Allocation;
- void* result = m_markedSpace.allocate(bytes);
- m_operationInProgress = NoOperation;
-
- ASSERT(result);
- return result;
-}
-
-void Heap::protect(JSValue k)
-{
- ASSERT(k);
- ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
-
- if (!k.isCell())
- return;
-
- m_protectedValues.add(k.asCell());
-}
-
-bool Heap::unprotect(JSValue k)
-{
- ASSERT(k);
- ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
-
- if (!k.isCell())
- return false;
-
- return m_protectedValues.remove(k.asCell());
-}
-
-void Heap::markProtectedObjects(HeapRootMarker& heapRootMarker)
-{
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- heapRootMarker.mark(&it->first);
-}
-
-void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
-{
- m_tempSortingVectors.append(tempVector);
-}
-
-void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
-{
- ASSERT_UNUSED(tempVector, tempVector == m_tempSortingVectors.last());
- m_tempSortingVectors.removeLast();
-}
-
-void Heap::markTempSortVectors(HeapRootMarker& heapRootMarker)
-{
- typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
-
- VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
- for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
- Vector<ValueStringPair>* tempSortingVector = *it;
-
- Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
- for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
- if (vectorIt->first)
- heapRootMarker.mark(&vectorIt->first);
- }
- }
-}
-
-inline RegisterFile& Heap::registerFile()
-{
- return m_globalData->interpreter->registerFile();
-}
-
-void Heap::markRoots()
-{
-#ifndef NDEBUG
- if (m_globalData->isSharedInstance()) {
- ASSERT(JSLock::lockCount() > 0);
- ASSERT(JSLock::currentThreadIsHoldingLock());
- }
-#endif
-
- void* dummy;
-
- ASSERT(m_operationInProgress == NoOperation);
- if (m_operationInProgress != NoOperation)
- CRASH();
-
- m_operationInProgress = Collection;
-
- MarkStack& markStack = m_markStack;
- HeapRootMarker heapRootMarker(markStack);
-
- // We gather conservative roots before clearing mark bits because
- // conservative gathering uses the mark bits from our last mark pass to
- // determine whether a reference is valid.
- ConservativeRoots machineThreadRoots(this);
- m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
-
- ConservativeRoots registerFileRoots(this);
- registerFile().gatherConservativeRoots(registerFileRoots);
-
- m_markedSpace.clearMarks();
-
- markStack.append(machineThreadRoots);
- markStack.drain();
-
- markStack.append(registerFileRoots);
- markStack.drain();
-
- markProtectedObjects(heapRootMarker);
- markStack.drain();
-
- markTempSortVectors(heapRootMarker);
- markStack.drain();
-
- if (m_markListSet && m_markListSet->size())
- MarkedArgumentBuffer::markLists(heapRootMarker, *m_markListSet);
- if (m_globalData->exception)
- heapRootMarker.mark(&m_globalData->exception);
- markStack.drain();
-
- m_handleHeap.markStrongHandles(heapRootMarker);
- m_handleStack.mark(heapRootMarker);
-
- // Mark the small strings cache last, since it will clear itself if nothing
- // else has marked it.
- m_globalData->smallStrings.markChildren(heapRootMarker);
-
- markStack.drain();
- markStack.compact();
-
- m_handleHeap.updateAfterMark();
-
- m_operationInProgress = NoOperation;
-}
-
-size_t Heap::objectCount() const
-{
- return m_markedSpace.objectCount();
-}
-
-size_t Heap::size() const
-{
- return m_markedSpace.size();
-}
-
-size_t Heap::capacity() const
-{
- return m_markedSpace.capacity();
-}
-
-size_t Heap::globalObjectCount()
-{
- return m_globalData->globalObjectCount;
-}
-
-size_t Heap::protectedGlobalObjectCount()
-{
- size_t count = m_handleHeap.protectedGlobalObjectCount();
-
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
- if (it->first->isObject() && asObject(it->first)->isGlobalObject())
- count++;
- }
-
- return count;
-}
-
-size_t Heap::protectedObjectCount()
-{
- return m_protectedValues.size();
-}
-
-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";
- if (cell->isGetterSetter())
- return "Getter-Setter";
- if (cell->isAPIValueWrapper())
- return "API wrapper";
- if (cell->isPropertyNameIterator())
- return "For-in iterator";
- if (!cell->isObject())
- return "[empty cell]";
- const ClassInfo* info = cell->classInfo();
- return info ? info->className : "Object";
-}
-
-inline void TypeCounter::operator()(JSCell* cell)
-{
- m_typeCountSet->add(typeName(cell));
-}
-
-inline PassOwnPtr<TypeCountSet> TypeCounter::take()
-{
- return m_typeCountSet.release();
-}
-
-PassOwnPtr<TypeCountSet> Heap::protectedObjectTypeCounts()
-{
- TypeCounter typeCounter;
-
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- typeCounter(it->first);
-
- return typeCounter.take();
-}
-
-PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
-{
- TypeCounter typeCounter;
- forEach(typeCounter);
- return typeCounter.take();
-}
-
-bool Heap::isBusy()
-{
- return m_operationInProgress != NoOperation;
-}
-
-void Heap::collectAllGarbage()
-{
- reset(DoSweep);
-}
-
-void Heap::reset(SweepToggle sweepToggle)
-{
- ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
- JAVASCRIPTCORE_GC_BEGIN();
-
- markRoots();
-
- JAVASCRIPTCORE_GC_MARKED();
-
- m_markedSpace.reset();
- m_extraCost = 0;
-
-#if ENABLE(JSC_ZOMBIES)
- sweepToggle = DoSweep;
-#endif
-
- if (sweepToggle == DoSweep) {
- m_markedSpace.sweep();
- m_markedSpace.shrink();
- }
-
- // To avoid pathological GC churn in large heaps, we set the allocation high
- // water mark to be proportional to the current size of the heap. The exact
- // proportion is a bit arbitrary. A 2X multiplier gives a 1:1 (heap size :
- // new bytes allocated) proportion, and seems to work well in benchmarks.
- size_t proportionalBytes = 2 * m_markedSpace.size();
- m_markedSpace.setHighWaterMark(max(proportionalBytes, minBytesPerCycle));
-
- JAVASCRIPTCORE_GC_END();
-
- (*m_activityCallback)();
-}
-
-void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
-{
- m_activityCallback = activityCallback;
-}
-
-GCActivityCallback* Heap::activityCallback()
-{
- return m_activityCallback.get();
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Heap.h b/Source/JavaScriptCore/runtime/Heap.h
deleted file mode 100644
index c2d3bac..0000000
--- a/Source/JavaScriptCore/runtime/Heap.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 Heap_h
-#define Heap_h
-
-#include "HandleHeap.h"
-#include "HandleStack.h"
-#include "MarkStack.h"
-#include "MarkedSpace.h"
-#include <wtf/Forward.h>
-#include <wtf/HashCountedSet.h>
-#include <wtf/HashSet.h>
-
-namespace JSC {
-
- class GCActivityCallback;
- class GlobalCodeBlock;
- class HeapRootMarker;
- class JSCell;
- class JSGlobalData;
- class JSValue;
- class LiveObjectIterator;
- 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:
- static Heap* heap(JSValue); // 0 for immediate values
- static Heap* heap(JSCell*);
-
- 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().
-
- JSGlobalData* globalData() const { return m_globalData; }
- MarkedSpace& markedSpace() { return m_markedSpace; }
- MachineThreads& machineThreads() { return m_machineThreads; }
-
- GCActivityCallback* activityCallback();
- void setActivityCallback(PassOwnPtr<GCActivityCallback>);
-
- bool isBusy(); // true if an allocation or collection is in progress
- void* allocate(size_t);
- void collectAllGarbage();
-
- void reportExtraMemoryCost(size_t cost);
-
- void protect(JSValue);
- bool unprotect(JSValue); // True when the protect count drops to 0.
-
- bool contains(void*);
-
- size_t size() const;
- size_t capacity() const;
- size_t objectCount() const;
- size_t globalObjectCount();
- size_t protectedObjectCount();
- size_t protectedGlobalObjectCount();
- PassOwnPtr<TypeCountSet> protectedObjectTypeCounts();
- PassOwnPtr<TypeCountSet> objectTypeCounts();
-
- void pushTempSortVector(Vector<ValueStringPair>*);
- void popTempSortVector(Vector<ValueStringPair>*);
-
- HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
-
- template <typename Functor> void forEach(Functor&);
-
- HandleSlot allocateGlobalHandle() { return m_handleHeap.allocate(); }
- HandleSlot allocateLocalHandle() { return m_handleStack.push(); }
-
- HandleStack* handleStack() { return &m_handleStack; }
-
- private:
- friend class JSGlobalData;
-
- static const size_t minExtraCost = 256;
- static const size_t maxExtraCost = 1024 * 1024;
-
- void* allocateSlowCase(size_t);
- void reportExtraMemoryCostSlowCase(size_t);
-
- void markRoots();
- void markProtectedObjects(HeapRootMarker&);
- void markTempSortVectors(HeapRootMarker&);
-
- enum SweepToggle { DoNotSweep, DoSweep };
- void reset(SweepToggle);
-
- RegisterFile& registerFile();
-
- OperationInProgress m_operationInProgress;
- MarkedSpace m_markedSpace;
-
- ProtectCountSet m_protectedValues;
- Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
-
- HashSet<MarkedArgumentBuffer*>* m_markListSet;
-
- OwnPtr<GCActivityCallback> m_activityCallback;
-
- JSGlobalData* m_globalData;
-
- MachineThreads m_machineThreads;
- MarkStack m_markStack;
- HandleHeap m_handleHeap;
- HandleStack m_handleStack;
-
- size_t m_extraCost;
- };
-
- inline bool Heap::isMarked(const JSCell* cell)
- {
- return MarkedSpace::isMarked(cell);
- }
-
- inline bool Heap::testAndSetMarked(const JSCell* cell)
- {
- return MarkedSpace::testAndSetMarked(cell);
- }
-
- inline void Heap::setMarked(JSCell* 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)
- reportExtraMemoryCostSlowCase(cost);
- }
-
- template <typename Functor> inline void Heap::forEach(Functor& functor)
- {
- m_markedSpace.forEach(functor);
- }
-
-} // namespace JSC
-
-#endif // Heap_h
diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
index aef60c8..27611b7 100644
--- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -59,7 +59,6 @@ static void initializeThreadingOnce()
s_dtoaP5Mutex = new Mutex;
initializeDates();
RegisterFile::initializeThreading();
- Structure::initializeThreading();
#endif
}
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index 27106a1..c3b07f8 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -36,13 +36,12 @@ ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
const ClassInfo InternalFunction::s_info = { "Function", &JSObjectWithGlobalObject::s_info, 0, 0 };
-InternalFunction::InternalFunction(NonNullPassRefPtr<Structure> structure)
- : JSObjectWithGlobalObject(structure)
+InternalFunction::InternalFunction(VPtrStealingHackType)
+ : JSObjectWithGlobalObject(VPtrStealingHack)
{
- ASSERT(inherits(&s_info));
}
-InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const Identifier& name)
+InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, Structure* structure, const Identifier& name)
: JSObjectWithGlobalObject(globalObject, structure)
{
ASSERT(inherits(&s_info));
@@ -51,12 +50,12 @@ InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* glo
const UString& InternalFunction::name(ExecState* exec)
{
- return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue();
+ return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue();
}
const UString InternalFunction::displayName(ExecState* exec)
{
- JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
+ JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
if (displayName && isJSString(&exec->globalData(), displayName))
return asString(displayName)->tryGetValue();
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index 08c98a5..28e260e 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -39,7 +39,7 @@ namespace JSC {
const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto)
{
return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -48,9 +48,9 @@ namespace JSC {
static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
// Only used to allow us to determine the JSFunction vptr
- InternalFunction(NonNullPassRefPtr<Structure> structure);
+ InternalFunction(VPtrStealingHackType);
- InternalFunction(JSGlobalData*, JSGlobalObject*, NonNullPassRefPtr<Structure>, const Identifier&);
+ InternalFunction(JSGlobalData*, JSGlobalObject*, Structure*, const Identifier&);
private:
virtual CallType getCallData(CallData&) = 0;
diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 54fe909..0165488 100644
--- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -25,6 +25,7 @@
#include "JSCell.h"
#include "CallFrame.h"
+#include "Structure.h"
namespace JSC {
@@ -35,7 +36,7 @@ namespace JSC {
virtual bool isAPIValueWrapper() const { return true; }
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount, 0);
}
@@ -43,7 +44,7 @@ namespace JSC {
private:
JSAPIValueWrapper(ExecState* exec, JSValue value)
- : JSCell(exec->globalData().apiWrapperStructure.get())
+ : JSCell(exec->globalData(), exec->globalData().apiWrapperStructure.get())
{
m_value.set(exec->globalData(), this, value);
ASSERT(!value.isCell());
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index d0c50dd..4e36641 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -40,7 +40,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0 };
JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
- : Base(callFrame->globalData().activationStructure, functionExecutable->symbolTable(), callFrame->registers())
+ : Base(callFrame->globalData(), callFrame->globalData().activationStructure.get(), functionExecutable->symbolTable(), callFrame->registers())
, m_numParametersMinusThis(static_cast<int>(functionExecutable->parameterCount()))
, m_numCapturedVars(functionExecutable->capturedVariableCount())
, m_requiresDynamicChecks(functionExecutable->usesEval())
@@ -142,7 +142,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
if (symbolTableGet(propertyName, slot))
return true;
- if (WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName)) {
+ if (WriteBarrierBase<Unknown>* location = getDirectLocation(exec->globalData(), propertyName)) {
slot.setValue(location->get());
return true;
}
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 7463f47..65642f1 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -66,7 +66,7 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 1d621fe..bf61097 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -127,26 +127,12 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
#endif
JSArray::JSArray(VPtrStealingHackType)
- : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
+ : JSNonFinalObject(VPtrStealingHack)
{
- ASSERT(inherits(&s_info));
-
- unsigned initialCapacity = 0;
-
- m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
- m_storage->m_allocBase = m_storage;
- m_indexBias = 0;
- m_vectorLength = initialCapacity;
-
- checkConsistency();
-
- // It's not safe to call Heap::heap(this) in order to report extra memory
- // cost here, because the VPtrStealingHackType JSArray is not allocated on
- // the heap. For the same reason, it's OK not to report extra cost.
}
-JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
- : JSNonFinalObject(structure)
+JSArray::JSArray(JSGlobalData& globalData, Structure* structure)
+ : JSNonFinalObject(globalData, structure)
{
ASSERT(inherits(&s_info));
@@ -162,8 +148,8 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
Heap::heap(this)->reportExtraMemoryCost(storageSize(0));
}
-JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength, ArrayCreationMode creationMode)
- : JSNonFinalObject(structure)
+JSArray::JSArray(JSGlobalData& globalData, Structure* structure, unsigned initialLength, ArrayCreationMode creationMode)
+ : JSNonFinalObject(globalData, structure)
{
ASSERT(inherits(&s_info));
@@ -204,8 +190,8 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength,
Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity));
}
-JSArray::JSArray(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, const ArgList& list)
- : JSNonFinalObject(structure)
+JSArray::JSArray(JSGlobalData& globalData, Structure* structure, const ArgList& list)
+ : JSNonFinalObject(globalData, structure)
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index 1a6eba8..8be8513 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -61,12 +61,11 @@ namespace JSC {
friend class Walker;
public:
- enum VPtrStealingHackType { VPtrStealingHack };
JSArray(VPtrStealingHackType);
- explicit JSArray(NonNullPassRefPtr<Structure>);
- JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength, ArrayCreationMode);
- JSArray(JSGlobalData&, NonNullPassRefPtr<Structure>, const ArgList& initialValues);
+ explicit JSArray(JSGlobalData&, Structure*);
+ JSArray(JSGlobalData&, Structure*, unsigned initialLength, ArrayCreationMode);
+ JSArray(JSGlobalData&, Structure*, const ArgList& initialValues);
virtual ~JSArray();
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -124,7 +123,7 @@ namespace JSC {
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToRegisters(ExecState*, Register*, uint32_t);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.cpp b/Source/JavaScriptCore/runtime/JSByteArray.cpp
index fbaea1d..c2abaee 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSByteArray.cpp
@@ -35,8 +35,8 @@ namespace JSC {
const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", &Base::s_info, 0, 0 };
-JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure, ByteArray* storage)
- : JSNonFinalObject(structure)
+JSByteArray::JSByteArray(ExecState* exec, Structure* structure, ByteArray* storage)
+ : JSNonFinalObject(exec->globalData(), structure)
, m_storage(storage)
{
putDirect(exec->globalData(), exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete);
@@ -50,7 +50,7 @@ JSByteArray::~JSByteArray()
#endif
-PassRefPtr<Structure> JSByteArray::createStructure(JSGlobalData& globalData, JSValue prototype, const JSC::ClassInfo* classInfo)
+Structure* JSByteArray::createStructure(JSGlobalData& globalData, JSValue prototype, const JSC::ClassInfo* classInfo)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, classInfo);
}
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.h b/Source/JavaScriptCore/runtime/JSByteArray.h
index e674958..c481bb4 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.h
+++ b/Source/JavaScriptCore/runtime/JSByteArray.h
@@ -75,8 +75,8 @@ namespace JSC {
setIndex(i, byteValue);
}
- JSByteArray(ExecState*, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage);
- static PassRefPtr<Structure> createStructure(JSGlobalData&, JSValue prototype, const JSC::ClassInfo* = &s_defaultInfo);
+ JSByteArray(ExecState*, Structure*, WTF::ByteArray* storage);
+ static Structure* createStructure(JSGlobalData&, JSValue prototype, const JSC::ClassInfo* = &s_defaultInfo);
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
@@ -100,9 +100,8 @@ namespace JSC {
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
private:
- enum VPtrStealingHackType { VPtrStealingHack };
JSByteArray(VPtrStealingHackType)
- : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
+ : JSNonFinalObject(VPtrStealingHack)
{
}
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index ce7fe22..afd8450 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -209,4 +209,14 @@ JSObject* JSCell::toObject(ExecState*, JSGlobalObject*) const
return 0;
}
+bool isZombie(const JSCell* cell)
+{
+#if ENABLE(JSC_ZOMBIES)
+ return cell && cell->isZombie();
+#else
+ UNUSED_PARAM(cell);
+ return false;
+#endif
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index ab0e237..7ee871c 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -24,18 +24,18 @@
#define JSCell_h
#include "CallData.h"
+#include "CallFrame.h"
#include "ConstructData.h"
#include "Heap.h"
-#include "JSImmediate.h"
#include "JSLock.h"
-#include "JSValue.h"
+#include "JSValueInlineMethods.h"
#include "MarkStack.h"
-#include "Structure.h"
#include <wtf/Noncopyable.h>
namespace JSC {
class JSGlobalObject;
+ class Structure;
#if COMPILER(MSVC)
// If WTF_MAKE_NONCOPYABLE is applied to JSCell we end up with a bunch of
@@ -68,17 +68,19 @@ namespace JSC {
friend class MarkedSpace;
friend class MarkedBlock;
friend class ScopeChainNode;
+ friend class Structure;
friend class StructureChain;
+ protected:
+ enum VPtrStealingHackType { VPtrStealingHack };
+
private:
- explicit JSCell(Structure*);
+ explicit JSCell(VPtrStealingHackType) { }
+ JSCell(JSGlobalData&, Structure*);
virtual ~JSCell();
public:
- static PassRefPtr<Structure> createDummyStructure(JSGlobalData& globalData)
- {
- return Structure::create(globalData, jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
- }
+ static Structure* createDummyStructure(JSGlobalData&);
// Querying the type.
bool isString() const;
@@ -122,7 +124,7 @@ namespace JSC {
#endif
// Object operations, with the toObject operation included.
- const ClassInfo* classInfo() const { return m_structure->classInfo(); }
+ const ClassInfo* classInfo() const;
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual void put(ExecState*, unsigned propertyName, JSValue);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
@@ -144,7 +146,7 @@ namespace JSC {
return OBJECT_OFFSETOF(JSCell, m_structure);
}
- Structure* const * addressOfStructure() const
+ const void* addressOfStructure() const
{
return &m_structure;
}
@@ -157,35 +159,28 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- Structure* m_structure;
+ WriteBarrier<Structure> m_structure;
};
- inline JSCell::JSCell(Structure* structure)
- : m_structure(structure)
+ inline JSCell::JSCell(JSGlobalData& globalData, Structure* structure)
+ : m_structure(globalData, this, structure)
{
+ // Very first set of allocations won't have a real structure.
+ ASSERT(m_structure || !globalData.dummyMarkableCellStructure);
}
inline JSCell::~JSCell()
{
}
- inline bool JSCell::isObject() const
- {
- return m_structure->typeInfo().type() == ObjectType;
- }
-
- inline bool JSCell::isString() const
- {
- return m_structure->typeInfo().type() == StringType;
- }
-
inline Structure* JSCell::structure() const
{
- return m_structure;
+ return m_structure.get();
}
- inline void JSCell::markChildren(MarkStack&)
+ inline void JSCell::markChildren(MarkStack& markStack)
{
+ markStack.append(&m_structure);
}
// --- JSValue inlines ----------------------------
@@ -254,14 +249,6 @@ namespace JSC {
return false;
}
-#if USE(JSVALUE64)
- ALWAYS_INLINE JSCell* JSValue::asCell() const
- {
- ASSERT(isCell());
- return m_ptr;
- }
-#endif // USE(JSVALUE64)
-
inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
@@ -321,13 +308,6 @@ namespace JSC {
return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
}
- inline bool JSValue::needsThisConversion() const
- {
- if (UNLIKELY(!isCell()))
- return true;
- return asCell()->structure()->typeInfo().needsThisConversion();
- }
-
inline JSValue JSValue::getJSNumber()
{
if (isInt32() || isDouble())
@@ -351,16 +331,6 @@ namespace JSC {
{
return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
}
-
- ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
- {
- ASSERT(!m_isCheckingForDefaultMarkViolation);
- ASSERT(cell);
- if (Heap::testAndSetMarked(cell))
- return;
- if (cell->structure()->typeInfo().type() >= CompoundType)
- m_values.append(cell);
- }
inline Heap* Heap::heap(JSValue v)
{
@@ -377,7 +347,7 @@ namespace JSC {
#if ENABLE(JSC_ZOMBIES)
inline bool JSValue::isZombie() const
{
- return isCell() && asCell() && asCell()->isZombie();
+ return isCell() && asCell() > (JSCell*)0x1ffffffffL && asCell()->isZombie();
}
#endif
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index dbfc606..a18e973 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -56,14 +56,12 @@ bool JSFunction::isHostFunctionNonInline() const
return isHostFunction();
}
-JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure, VPtrHackExecutable* executable)
- : Base(structure)
+JSFunction::JSFunction(VPtrStealingHackType)
+ : Base(VPtrStealingHack)
{
- ASSERT(inherits(&s_info));
- m_executable.setWithoutWriteBarrier(executable);
}
-JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeExecutable* thunk)
+JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeExecutable* thunk)
: Base(globalObject, structure)
, m_executable(exec->globalData(), this, thunk)
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
@@ -73,7 +71,7 @@ JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPas
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
-JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
+JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeFunction func)
: Base(globalObject, structure)
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
@@ -112,12 +110,12 @@ static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescrip
const UString& JSFunction::name(ExecState* exec)
{
- return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue();
+ return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue();
}
const UString JSFunction::displayName(ExecState* exec)
{
- JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
+ JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
if (displayName && isJSString(&exec->globalData(), displayName))
return asString(displayName)->tryGetValue();
@@ -186,13 +184,13 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
if (propertyName == exec->propertyNames().prototype) {
- WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName);
+ WriteBarrierBase<Unknown>* location = getDirectLocation(exec->globalData(), propertyName);
if (!location) {
JSObject* prototype = constructEmptyObject(exec, scope()->globalObject->emptyObjectStructure());
prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, this, DontEnum);
putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
- location = getDirectLocation(propertyName);
+ location = getDirectLocation(exec->globalData(), propertyName);
}
slot.setValue(this, location->get(), offsetForLocation(location));
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 505b9de..174cd38 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -45,8 +45,8 @@ namespace JSC {
typedef JSObjectWithGlobalObject Base;
public:
- JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
- JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeExecutable*);
+ JSFunction(ExecState*, JSGlobalObject*, Structure*, int length, const Identifier&, NativeFunction);
+ JSFunction(ExecState*, JSGlobalObject*, Structure*, int length, const Identifier&, NativeExecutable*);
JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
virtual ~JSFunction();
@@ -73,7 +73,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -87,7 +87,7 @@ namespace JSC {
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
private:
- JSFunction(NonNullPassRefPtr<Structure>, VPtrHackExecutable*);
+ explicit JSFunction(VPtrStealingHackType);
bool isHostFunctionNonInline() const;
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index ee1829b..d9e5df0 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -45,6 +45,7 @@
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
#include "JSStaticScopeObject.h"
+#include "JSZombie.h"
#include "Lexer.h"
#include "Lookup.h"
#include "Nodes.h"
@@ -106,6 +107,15 @@ void* JSGlobalData::jsByteArrayVPtr;
void* JSGlobalData::jsStringVPtr;
void* JSGlobalData::jsFunctionVPtr;
+#if COMPILER(GCC)
+// Work around for gcc trying to coalesce our reads of the various cell vptrs
+#define CLOBBER_MEMORY() do { \
+ asm volatile ("" : : : "memory"); \
+} while (false)
+#else
+#define CLOBBER_MEMORY() do { } while (false)
+#endif
+
void JSGlobalData::storeVPtrs()
{
// Enough storage to fit a JSArray, JSByteArray, JSString, or JSFunction.
@@ -114,27 +124,23 @@ void JSGlobalData::storeVPtrs()
COMPILE_ASSERT(sizeof(JSArray) <= sizeof(storage), sizeof_JSArray_must_be_less_than_storage);
JSCell* jsArray = new (storage) JSArray(JSArray::VPtrStealingHack);
+ CLOBBER_MEMORY();
JSGlobalData::jsArrayVPtr = jsArray->vptr();
- jsArray->~JSCell();
COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(storage), sizeof_JSByteArray_must_be_less_than_storage);
JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
+ CLOBBER_MEMORY();
JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
- jsByteArray->~JSCell();
COMPILE_ASSERT(sizeof(JSString) <= sizeof(storage), sizeof_JSString_must_be_less_than_storage);
JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
+ CLOBBER_MEMORY();
JSGlobalData::jsStringVPtr = jsString->vptr();
- jsString->~JSCell();
COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(storage), sizeof_JSFunction_must_be_less_than_storage);
- char executableStorage[sizeof(VPtrHackExecutable)];
- RefPtr<Structure> executableStructure = Structure::create(Structure::VPtrStealingHack, 0);
- JSCell* executable = new (executableStorage) VPtrHackExecutable(executableStructure.get());
- JSCell* jsFunction = new (storage) JSFunction(Structure::create(Structure::VPtrStealingHack, &JSFunction::s_info), static_cast<VPtrHackExecutable*>(executable));
+ JSCell* jsFunction = new (storage) JSFunction(JSCell::VPtrStealingHack);
+ CLOBBER_MEMORY();
JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
- executable->~JSCell();
- jsFunction->~JSCell();
}
JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType)
@@ -168,28 +174,39 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, exclusiveThread(0)
#endif
{
- activationStructure = JSActivation::createStructure(*this, jsNull());
- interruptedExecutionErrorStructure = JSNonFinalObject::createStructure(*this, jsNull());
- terminatedExecutionErrorStructure = JSNonFinalObject::createStructure(*this, jsNull());
- staticScopeStructure = JSStaticScopeObject::createStructure(*this, jsNull());
- strictEvalActivationStructure = StrictEvalActivation::createStructure(*this, jsNull());
- stringStructure = JSString::createStructure(*this, jsNull());
- notAnObjectStructure = JSNotAnObject::createStructure(*this, jsNull());
- propertyNameIteratorStructure = JSPropertyNameIterator::createStructure(*this, jsNull());
- getterSetterStructure = GetterSetter::createStructure(*this, jsNull());
- apiWrapperStructure = JSAPIValueWrapper::createStructure(*this, jsNull());
- scopeChainNodeStructure = ScopeChainNode::createStructure(*this, jsNull());
- executableStructure = ExecutableBase::createStructure(*this, jsNull());
- evalExecutableStructure = EvalExecutable::createStructure(*this, jsNull());
- programExecutableStructure = ProgramExecutable::createStructure(*this, jsNull());
- functionExecutableStructure = FunctionExecutable::createStructure(*this, jsNull());
- dummyMarkableCellStructure = JSCell::createDummyStructure(*this);
- structureChainStructure = StructureChain::createStructure(*this, jsNull());
-
interpreter = new Interpreter(*this);
if (globalDataType == Default)
m_stack = wtfThreadData().stack();
+ // Need to be careful to keep everything consistent here
+ IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable);
+ JSLock lock(SilenceAssertionsOnly);
+ structureStructure.set(*this, Structure::createStructure(*this));
+ activationStructure.set(*this, JSActivation::createStructure(*this, jsNull()));
+ interruptedExecutionErrorStructure.set(*this, JSNonFinalObject::createStructure(*this, jsNull()));
+ terminatedExecutionErrorStructure.set(*this, JSNonFinalObject::createStructure(*this, jsNull()));
+ staticScopeStructure.set(*this, JSStaticScopeObject::createStructure(*this, jsNull()));
+ strictEvalActivationStructure.set(*this, StrictEvalActivation::createStructure(*this, jsNull()));
+ stringStructure.set(*this, JSString::createStructure(*this, jsNull()));
+ notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, jsNull()));
+ propertyNameIteratorStructure.set(*this, JSPropertyNameIterator::createStructure(*this, jsNull()));
+ getterSetterStructure.set(*this, GetterSetter::createStructure(*this, jsNull()));
+ apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, jsNull()));
+ scopeChainNodeStructure.set(*this, ScopeChainNode::createStructure(*this, jsNull()));
+ executableStructure.set(*this, ExecutableBase::createStructure(*this, jsNull()));
+ nativeExecutableStructure.set(*this, NativeExecutable::createStructure(*this, jsNull()));
+ evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, jsNull()));
+ programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, jsNull()));
+ functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, jsNull()));
+ dummyMarkableCellStructure.set(*this, JSCell::createDummyStructure(*this));
+ structureChainStructure.set(*this, StructureChain::createStructure(*this, jsNull()));
+
+#if ENABLE(JSC_ZOMBIES)
+ zombieStructure.set(*this, JSZombie::createStructure(*this, jsNull()));
+#endif
+
+ wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
+
#if PLATFORM(MAC)
startProfilerServerIfNeeded();
#endif
@@ -221,6 +238,33 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
#endif
}
+void JSGlobalData::clearBuiltinStructures()
+{
+ structureStructure.clear();
+ activationStructure.clear();
+ interruptedExecutionErrorStructure.clear();
+ terminatedExecutionErrorStructure.clear();
+ staticScopeStructure.clear();
+ strictEvalActivationStructure.clear();
+ stringStructure.clear();
+ notAnObjectStructure.clear();
+ propertyNameIteratorStructure.clear();
+ getterSetterStructure.clear();
+ apiWrapperStructure.clear();
+ scopeChainNodeStructure.clear();
+ executableStructure.clear();
+ nativeExecutableStructure.clear();
+ evalExecutableStructure.clear();
+ programExecutableStructure.clear();
+ functionExecutableStructure.clear();
+ dummyMarkableCellStructure.clear();
+ structureChainStructure.clear();
+
+#if ENABLE(JSC_ZOMBIES)
+ zombieStructure.clear();
+#endif
+}
+
JSGlobalData::~JSGlobalData()
{
// By the time this is destroyed, heap.destroy() must already have been called.
@@ -281,10 +325,7 @@ PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
{
- Structure::startIgnoringLeaks();
- RefPtr<JSGlobalData> data = create(type);
- Structure::stopIgnoringLeaks();
- return data.release();
+ return create(type);
}
bool JSGlobalData::sharedInstanceExists()
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 34ea75d..f1085af 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -33,6 +33,7 @@
#include "Heap.h"
#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
+#include "Strong.h"
#include "JITStubs.h"
#include "JSValue.h"
#include "NumericStrings.h"
@@ -145,23 +146,29 @@ namespace JSC {
const HashTable* regExpConstructorTable;
const HashTable* stringTable;
- RefPtr<Structure> activationStructure;
- RefPtr<Structure> interruptedExecutionErrorStructure;
- RefPtr<Structure> terminatedExecutionErrorStructure;
- RefPtr<Structure> staticScopeStructure;
- RefPtr<Structure> strictEvalActivationStructure;
- RefPtr<Structure> stringStructure;
- RefPtr<Structure> notAnObjectStructure;
- RefPtr<Structure> propertyNameIteratorStructure;
- RefPtr<Structure> getterSetterStructure;
- RefPtr<Structure> apiWrapperStructure;
- RefPtr<Structure> scopeChainNodeStructure;
- RefPtr<Structure> executableStructure;
- RefPtr<Structure> evalExecutableStructure;
- RefPtr<Structure> programExecutableStructure;
- RefPtr<Structure> functionExecutableStructure;
- RefPtr<Structure> dummyMarkableCellStructure;
- RefPtr<Structure> structureChainStructure;
+ Strong<Structure> structureStructure;
+ Strong<Structure> activationStructure;
+ Strong<Structure> interruptedExecutionErrorStructure;
+ Strong<Structure> terminatedExecutionErrorStructure;
+ Strong<Structure> staticScopeStructure;
+ Strong<Structure> strictEvalActivationStructure;
+ Strong<Structure> stringStructure;
+ Strong<Structure> notAnObjectStructure;
+ Strong<Structure> propertyNameIteratorStructure;
+ Strong<Structure> getterSetterStructure;
+ Strong<Structure> apiWrapperStructure;
+ Strong<Structure> scopeChainNodeStructure;
+ Strong<Structure> executableStructure;
+ Strong<Structure> nativeExecutableStructure;
+ Strong<Structure> evalExecutableStructure;
+ Strong<Structure> programExecutableStructure;
+ Strong<Structure> functionExecutableStructure;
+ Strong<Structure> dummyMarkableCellStructure;
+ Strong<Structure> structureChainStructure;
+
+#if ENABLE(JSC_ZOMBIES)
+ Strong<Structure> zombieStructure;
+#endif
static void storeVPtrs();
static JS_EXPORTDATA void* jsArrayVPtr;
@@ -260,6 +267,7 @@ namespace JSC {
void dumpRegExpTrace();
HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
+ void clearBuiltinStructures();
private:
JSGlobalData(GlobalDataType, ThreadStackType);
@@ -271,6 +279,11 @@ namespace JSC {
StackBounds m_stack;
};
+ inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
+ {
+ return globalData.allocateGlobalHandle();
+ }
+
} // namespace JSC
#endif // JSGlobalData_h
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index a2bbfbd..b82949a 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -84,14 +84,6 @@ template <typename T> static inline void markIfNeeded(MarkStack& markStack, Writ
markStack.append(v);
}
-static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s)
-{
- if (s && s->storedPrototype())
- markStack.append(s->storedPrototypeSlot());
- if (s && *s->cachedPrototypeChainSlot())
- markStack.append(s->cachedPrototypeChainSlot());
-}
-
JSGlobalObject::~JSGlobalObject()
{
ASSERT(JSLock::currentThreadIsHoldingLock());
@@ -139,11 +131,11 @@ void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& proper
if (symbolTablePutWithAttributes(exec->globalData(), propertyName, value, attributes))
return;
- JSValue valueBefore = getDirect(propertyName);
+ JSValue valueBefore = getDirect(exec->globalData(), propertyName);
PutPropertySlot slot;
JSVariableObject::put(exec, propertyName, value, slot);
if (!valueBefore) {
- JSValue valueAfter = getDirect(propertyName);
+ JSValue valueAfter = getDirect(exec->globalData(), propertyName);
if (valueAfter)
JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes);
}
@@ -178,46 +170,46 @@ void JSGlobalObject::reset(JSValue prototype)
// Prototypes
m_functionPrototype.set(exec->globalData(), this, new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(exec->globalData(), jsNull()))); // The real prototype will be set once ObjectPrototype is created.
- m_functionStructure = JSFunction::createStructure(exec->globalData(), m_functionPrototype.get());
- m_internalFunctionStructure = InternalFunction::createStructure(exec->globalData(), m_functionPrototype.get());
+ m_functionStructure.set(exec->globalData(), this, JSFunction::createStructure(exec->globalData(), m_functionPrototype.get()));
+ m_internalFunctionStructure.set(exec->globalData(), this, InternalFunction::createStructure(exec->globalData(), m_functionPrototype.get()));
JSFunction* callFunction = 0;
JSFunction* applyFunction = 0;
m_functionPrototype->addFunctionProperties(exec, this, m_functionStructure.get(), &callFunction, &applyFunction);
m_callFunction.set(exec->globalData(), this, callFunction);
m_applyFunction.set(exec->globalData(), this, applyFunction);
m_objectPrototype.set(exec->globalData(), this, new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(exec->globalData(), jsNull()), m_functionStructure.get()));
- m_functionPrototype->structure()->setPrototypeWithoutTransition(m_objectPrototype.get());
+ m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->globalData(), m_objectPrototype.get());
- m_emptyObjectStructure = m_objectPrototype->inheritorID(exec->globalData());
+ m_emptyObjectStructure.set(exec->globalData(), this, m_objectPrototype->inheritorID(exec->globalData()));
- m_callbackFunctionStructure = JSCallbackFunction::createStructure(exec->globalData(), m_functionPrototype.get());
- m_argumentsStructure = Arguments::createStructure(exec->globalData(), m_objectPrototype.get());
- m_callbackConstructorStructure = JSCallbackConstructor::createStructure(exec->globalData(), m_objectPrototype.get());
- m_callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(exec->globalData(), m_objectPrototype.get());
+ m_callbackFunctionStructure.set(exec->globalData(), this, JSCallbackFunction::createStructure(exec->globalData(), m_functionPrototype.get()));
+ m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), m_objectPrototype.get()));
+ m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), m_objectPrototype.get()));
+ m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSObjectWithGlobalObject>::createStructure(exec->globalData(), m_objectPrototype.get()));
m_arrayPrototype.set(exec->globalData(), this, new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
- m_arrayStructure = JSArray::createStructure(exec->globalData(), m_arrayPrototype.get());
- m_regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(exec->globalData(), m_arrayPrototype.get());
+ m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), m_arrayPrototype.get()));
+ m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), m_arrayPrototype.get()));
m_stringPrototype.set(exec->globalData(), this, new (exec) StringPrototype(exec, this, StringPrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
- m_stringObjectStructure = StringObject::createStructure(exec->globalData(), m_stringPrototype.get());
+ m_stringObjectStructure.set(exec->globalData(), this, StringObject::createStructure(exec->globalData(), m_stringPrototype.get()));
m_booleanPrototype.set(exec->globalData(), this, new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
- m_booleanObjectStructure = BooleanObject::createStructure(exec->globalData(), m_booleanPrototype.get());
+ m_booleanObjectStructure.set(exec->globalData(), this, BooleanObject::createStructure(exec->globalData(), m_booleanPrototype.get()));
m_numberPrototype.set(exec->globalData(), this, new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
- m_numberObjectStructure = NumberObject::createStructure(exec->globalData(), m_numberPrototype.get());
+ m_numberObjectStructure.set(exec->globalData(), this, NumberObject::createStructure(exec->globalData(), m_numberPrototype.get()));
m_datePrototype.set(exec->globalData(), this, new (exec) DatePrototype(exec, this, DatePrototype::createStructure(exec->globalData(), m_objectPrototype.get())));
- m_dateStructure = DateInstance::createStructure(exec->globalData(), m_datePrototype.get());
+ m_dateStructure.set(exec->globalData(), this, DateInstance::createStructure(exec->globalData(), m_datePrototype.get()));
m_regExpPrototype.set(exec->globalData(), this, new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get()));
- m_regExpStructure = RegExpObject::createStructure(exec->globalData(), m_regExpPrototype.get());
+ m_regExpStructure.set(exec->globalData(), this, RegExpObject::createStructure(exec->globalData(), m_regExpPrototype.get()));
m_methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get());
- m_errorStructure = ErrorInstance::createStructure(exec->globalData(), errorPrototype);
+ m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), errorPrototype));
// Constructors
@@ -233,8 +225,8 @@ void JSGlobalObject::reset(JSValue prototype)
m_errorConstructor.set(exec->globalData(), this, new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), errorPrototype));
- RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), errorPrototype);
- RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), m_functionPrototype.get());
+ Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), errorPrototype);
+ Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), m_functionPrototype.get());
m_evalErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"));
m_rangeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"));
m_referenceErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"));
@@ -301,18 +293,18 @@ void JSGlobalObject::reset(JSValue prototype)
putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
#endif
- resetPrototype(prototype);
+ resetPrototype(exec->globalData(), prototype);
}
// Set prototype, and also insert the object prototype at the end of the chain.
-void JSGlobalObject::resetPrototype(JSValue prototype)
+void JSGlobalObject::resetPrototype(JSGlobalData& globalData, JSValue prototype)
{
- setPrototype(prototype);
+ setPrototype(globalData, prototype);
JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
JSObject* objectPrototype = m_objectPrototype.get();
if (oldLastInPrototypeChain != objectPrototype)
- oldLastInPrototypeChain->setPrototype(objectPrototype);
+ oldLastInPrototypeChain->setPrototype(globalData, objectPrototype);
}
void JSGlobalObject::markChildren(MarkStack& markStack)
@@ -344,21 +336,21 @@ void JSGlobalObject::markChildren(MarkStack& markStack)
markIfNeeded(markStack, &m_datePrototype);
markIfNeeded(markStack, &m_regExpPrototype);
- markIfNeeded(markStack, m_argumentsStructure);
- markIfNeeded(markStack, m_arrayStructure);
- markIfNeeded(markStack, m_booleanObjectStructure);
- markIfNeeded(markStack, m_callbackConstructorStructure);
- markIfNeeded(markStack, m_callbackFunctionStructure);
- markIfNeeded(markStack, m_callbackObjectStructure);
- markIfNeeded(markStack, m_dateStructure);
- markIfNeeded(markStack, m_emptyObjectStructure);
- markIfNeeded(markStack, m_errorStructure);
- markIfNeeded(markStack, m_functionStructure);
- markIfNeeded(markStack, m_numberObjectStructure);
- markIfNeeded(markStack, m_regExpMatchesArrayStructure);
- markIfNeeded(markStack, m_regExpStructure);
- markIfNeeded(markStack, m_stringObjectStructure);
- markIfNeeded(markStack, m_internalFunctionStructure);
+ markIfNeeded(markStack, &m_argumentsStructure);
+ markIfNeeded(markStack, &m_arrayStructure);
+ markIfNeeded(markStack, &m_booleanObjectStructure);
+ markIfNeeded(markStack, &m_callbackConstructorStructure);
+ markIfNeeded(markStack, &m_callbackFunctionStructure);
+ markIfNeeded(markStack, &m_callbackObjectStructure);
+ markIfNeeded(markStack, &m_dateStructure);
+ markIfNeeded(markStack, &m_emptyObjectStructure);
+ markIfNeeded(markStack, &m_errorStructure);
+ markIfNeeded(markStack, &m_functionStructure);
+ markIfNeeded(markStack, &m_numberObjectStructure);
+ markIfNeeded(markStack, &m_regExpMatchesArrayStructure);
+ markIfNeeded(markStack, &m_regExpStructure);
+ markIfNeeded(markStack, &m_stringObjectStructure);
+ markIfNeeded(markStack, &m_internalFunctionStructure);
if (m_registerArray) {
// Outside the execution of global code, when our variables are torn off,
@@ -393,7 +385,7 @@ void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
return;
}
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData(), reinterpret_cast<WriteBarrier<Unknown>*>(registerFile.lastGlobal()), numGlobals);
+ OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData(), reinterpret_cast<WriteBarrier<Unknown>*>(registerFile.lastGlobal()), numGlobals, numGlobals);
WriteBarrier<Unknown>* registers = registerArray.get() + numGlobals;
setRegisters(registers, registerArray.release(), numGlobals);
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 04f63eb..0e36920 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -87,21 +87,21 @@ namespace JSC {
WriteBarrier<DatePrototype> m_datePrototype;
WriteBarrier<RegExpPrototype> m_regExpPrototype;
- RefPtr<Structure> m_argumentsStructure;
- RefPtr<Structure> m_arrayStructure;
- RefPtr<Structure> m_booleanObjectStructure;
- RefPtr<Structure> m_callbackConstructorStructure;
- RefPtr<Structure> m_callbackFunctionStructure;
- RefPtr<Structure> m_callbackObjectStructure;
- RefPtr<Structure> m_dateStructure;
- RefPtr<Structure> m_emptyObjectStructure;
- RefPtr<Structure> m_errorStructure;
- RefPtr<Structure> m_functionStructure;
- RefPtr<Structure> m_numberObjectStructure;
- RefPtr<Structure> m_regExpMatchesArrayStructure;
- RefPtr<Structure> m_regExpStructure;
- RefPtr<Structure> m_stringObjectStructure;
- RefPtr<Structure> m_internalFunctionStructure;
+ WriteBarrier<Structure> m_argumentsStructure;
+ WriteBarrier<Structure> m_arrayStructure;
+ WriteBarrier<Structure> m_booleanObjectStructure;
+ WriteBarrier<Structure> m_callbackConstructorStructure;
+ WriteBarrier<Structure> m_callbackFunctionStructure;
+ WriteBarrier<Structure> m_callbackObjectStructure;
+ WriteBarrier<Structure> m_dateStructure;
+ WriteBarrier<Structure> m_emptyObjectStructure;
+ WriteBarrier<Structure> m_errorStructure;
+ WriteBarrier<Structure> m_functionStructure;
+ WriteBarrier<Structure> m_numberObjectStructure;
+ WriteBarrier<Structure> m_regExpMatchesArrayStructure;
+ WriteBarrier<Structure> m_regExpStructure;
+ WriteBarrier<Structure> m_stringObjectStructure;
+ WriteBarrier<Structure> m_internalFunctionStructure;
unsigned m_profileGroup;
Debugger* m_debugger;
@@ -115,7 +115,7 @@ namespace JSC {
void* operator new(size_t, JSGlobalData*);
explicit JSGlobalObject(JSGlobalData& globalData)
- : JSVariableObject(JSGlobalObject::createStructure(globalData, jsNull()), &m_symbolTable, 0)
+ : JSVariableObject(globalData, JSGlobalObject::createStructure(globalData, jsNull()), &m_symbolTable, 0)
, m_registerArraySize(0)
, m_globalScopeChain()
, m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
@@ -125,8 +125,8 @@ namespace JSC {
init(this);
}
- explicit JSGlobalObject(NonNullPassRefPtr<Structure> structure)
- : JSVariableObject(structure, &m_symbolTable, 0)
+ explicit JSGlobalObject(JSGlobalData& globalData, Structure* structure)
+ : JSVariableObject(globalData, structure, &m_symbolTable, 0)
, m_registerArraySize(0)
, m_globalScopeChain()
, m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
@@ -137,8 +137,8 @@ namespace JSC {
}
protected:
- JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSObject* thisValue)
- : JSVariableObject(structure, &m_symbolTable, 0)
+ JSGlobalObject(JSGlobalData& globalData, Structure* structure, JSObject* thisValue)
+ : JSVariableObject(globalData, structure, &m_symbolTable, 0)
, m_registerArraySize(0)
, m_globalScopeChain()
, m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
@@ -235,11 +235,11 @@ namespace JSC {
void copyGlobalsTo(RegisterFile&);
void resizeRegisters(int oldSize, int newSize);
- void resetPrototype(JSValue prototype);
+ void resetPrototype(JSGlobalData&, JSValue prototype);
JSGlobalData& globalData() const { return *m_globalData.get(); }
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -363,7 +363,7 @@ namespace JSC {
// We cache our prototype chain so our clients can share it.
if (!isValid(exec, m_cachedPrototypeChain.get())) {
JSValue prototype = prototypeForLookup(exec);
- m_cachedPrototypeChain = StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure());
+ m_cachedPrototypeChain.set(exec->globalData(), this, StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure()));
}
return m_cachedPrototypeChain.get();
}
@@ -374,9 +374,9 @@ namespace JSC {
return false;
JSValue prototype = prototypeForLookup(exec);
- RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head();
+ WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
while(*cachedStructure && !prototype.isNull()) {
- if (asObject(prototype)->structure() != *cachedStructure)
+ if (asObject(prototype)->structure() != cachedStructure->get())
return false;
++cachedStructure;
prototype = asObject(prototype)->prototype();
@@ -407,17 +407,17 @@ namespace JSC {
inline JSArray* constructEmptyArray(ExecState* exec)
{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+ return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure());
}
inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
{
- return new (exec) JSArray(globalObject->arrayStructure());
+ return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure());
}
inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength, CreateInitialized);
+ return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), initialLength, CreateInitialized);
}
inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
diff --git a/Source/JavaScriptCore/runtime/JSImmediate.cpp b/Source/JavaScriptCore/runtime/JSImmediate.cpp
deleted file mode 100644
index 846238d..0000000
--- a/Source/JavaScriptCore/runtime/JSImmediate.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2003-2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "JSImmediate.h"
-
-namespace JSC {
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSImmediate.h b/Source/JavaScriptCore/runtime/JSImmediate.h
deleted file mode 100644
index 68ba75c..0000000
--- a/Source/JavaScriptCore/runtime/JSImmediate.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef JSImmediate_h
-#define JSImmediate_h
-
-#if USE(JSVALUE64)
-
-#include <wtf/Assertions.h>
-#include <wtf/AlwaysInline.h>
-#include <wtf/MathExtras.h>
-#include <wtf/StdLibExtras.h>
-#include "JSValue.h"
-#include <limits>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-namespace JSC {
-
- class ExecState;
- class JSCell;
- class JSGlobalData;
- class JSObject;
- class UString;
-
- inline intptr_t reinterpretDoubleToIntptr(double value)
- {
- return WTF::bitwise_cast<intptr_t>(value);
- }
-
- inline double reinterpretIntptrToDouble(intptr_t value)
- {
- return WTF::bitwise_cast<double>(value);
- }
-
- /*
- * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged
- * value masquerading as a pointer). The low two bits in a JSValue* are available for type tagging
- * because allocator alignment guarantees they will be 00 in cell pointers.
- *
- * For example, on a 32 bit system:
- *
- * JSCell*: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 00
- * [ high 30 bits: pointer address ] [ low 2 bits -- always 0 ]
- * JSImmediate: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TT
- * [ high 30 bits: 'payload' ] [ low 2 bits -- tag ]
- *
- * Where the bottom two bits are non-zero they either indicate that the immediate is a 31 bit signed
- * integer, or they mark the value as being an immediate of a type other than integer, with a secondary
- * tag used to indicate the exact type.
- *
- * Where the lowest bit is set (TT is equal to 01 or 11) the high 31 bits form a 31 bit signed int value.
- * Where TT is equal to 10 this indicates this is a type of immediate other than an integer, and the next
- * two bits will form an extended tag.
- *
- * 31 bit signed int: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X1
- * [ high 30 bits of the value ] [ high bit part of value ]
- * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY ZZ 10
- * [ extended 'payload' ] [ extended tag ] [ tag 'other' ]
- *
- * Where the first bit of the extended tag is set this flags the value as being a boolean, and the following
- * bit would flag the value as undefined. If neither bits are set, the value is null.
- *
- * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY UB 10
- * [ extended 'payload' ] [ undefined | bool ] [ tag 'other' ]
- *
- * For boolean value the lowest bit in the payload holds the value of the bool, all remaining bits are zero.
- * For undefined or null immediates the payload is zero.
- *
- * Boolean: 000000000000000000000000000V 01 10
- * [ boolean value ] [ bool ] [ tag 'other' ]
- * Undefined: 0000000000000000000000000000 10 10
- * [ zero ] [ undefined ] [ tag 'other' ]
- * Null: 0000000000000000000000000000 00 10
- * [ zero ] [ zero ] [ tag 'other' ]
- */
-
- /*
- * On 64-bit platforms, we support an alternative encoding form for immediates, if
- * USE(JSVALUE64) is defined. When this format is used, double precision
- * floating point values may also be encoded as JSImmediates.
- *
- * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
- * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
- * can encode a 51-bit payload. Hardware produced and C-library payloads typically
- * have a payload of zero. We assume that non-zero payloads are available to encode
- * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
- * all set represents a NaN with a non-zero payload, we can use this space in the NaN
- * ranges to encode other values (however there are also other ranges of NaN space that
- * could have been selected). This range of NaN space is represented by 64-bit numbers
- * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no
- * valid double-precision numbers will begin fall in these ranges.
- *
- * The scheme we have implemented encodes double precision values by adding 2^48 to the
- * 64-bit integer representation of the number. After this manipulation, no encoded
- * double-precision value will begin with the pattern 0x0000 or 0xFFFF.
- *
- * The top 16-bits denote the type of the encoded JSImmediate:
- *
- * Pointer: 0000:PPPP:PPPP:PPPP
- * 0001:****:****:****
- * Double:{ ...
- * FFFE:****:****:****
- * Integer: FFFF:0000:IIII:IIII
- *
- * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000
- * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined
- * values are encoded in the same manner as the default format.
- */
-
- class JSImmediate {
- private:
- friend class JIT;
- friend class JSValue;
- friend class JSInterfaceJIT;
- friend class SpecializedThunkJIT;
- friend JSValue jsNumber(ExecState* exec, double d);
- friend JSValue jsNumber(ExecState*, char i);
- friend JSValue jsNumber(ExecState*, unsigned char i);
- friend JSValue jsNumber(ExecState*, short i);
- friend JSValue jsNumber(ExecState*, unsigned short i);
- friend JSValue jsNumber(ExecState* exec, int i);
- friend JSValue jsNumber(ExecState* exec, unsigned i);
- friend JSValue jsNumber(ExecState* exec, long i);
- friend JSValue jsNumber(ExecState* exec, unsigned long i);
- friend JSValue jsNumber(ExecState* exec, long long i);
- friend JSValue jsNumber(ExecState* exec, unsigned long long i);
- friend JSValue jsNumber(JSGlobalData* globalData, double d);
- friend JSValue jsNumber(JSGlobalData* globalData, short i);
- friend JSValue jsNumber(JSGlobalData* globalData, unsigned short i);
- friend JSValue jsNumber(JSGlobalData* globalData, int i);
- friend JSValue jsNumber(JSGlobalData* globalData, unsigned i);
- friend JSValue jsNumber(JSGlobalData* globalData, long i);
- friend JSValue jsNumber(JSGlobalData* globalData, unsigned long i);
- friend JSValue jsNumber(JSGlobalData* globalData, long long i);
- friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
-
- // If all bits in the mask are set, this indicates an integer number,
- // if any but not all are set this value is a double precision number.
- static const intptr_t TagTypeNumber = 0xffff000000000000ll;
- // This value is 2^48, used to encode doubles such that the encoded value will begin
- // with a 16-bit pattern within the range 0x0001..0xFFFE.
- static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
- static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
- static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
-
- static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits
- static const intptr_t ExtendedTagBitBool = 0x4;
- static const intptr_t ExtendedTagBitUndefined = 0x8;
-
- static const intptr_t FullTagTypeMask = TagMask | ExtendedTagMask;
- static const intptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool;
- static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
- static const intptr_t FullTagTypeNull = TagBitTypeOther;
-
- static const int32_t IntegerPayloadShift = 0;
- static const int32_t ExtendedPayloadShift = 4;
-
- static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
-
- static const int32_t signBit = 0x80000000;
-
- static ALWAYS_INLINE bool isImmediate(JSValue v)
- {
- return rawValue(v) & TagMask;
- }
-
- static ALWAYS_INLINE bool isNumber(JSValue v)
- {
- return rawValue(v) & TagTypeNumber;
- }
-
- static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
- {
- return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
- }
-
- static ALWAYS_INLINE bool isDouble(JSValue v)
- {
- return isNumber(v) && !isIntegerNumber(v);
- }
-
- static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
- {
- // A single mask to check for the sign bit and the number tag all at once.
- return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
- }
-
- static ALWAYS_INLINE bool isBoolean(JSValue v)
- {
- return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool;
- }
-
- static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v)
- {
- // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
- return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
- }
-
- static JSValue from(char);
- static JSValue from(signed char);
- static JSValue from(unsigned char);
- static JSValue from(short);
- static JSValue from(unsigned short);
- static JSValue from(int);
- static JSValue from(unsigned);
- static JSValue from(long);
- static JSValue from(unsigned long);
- static JSValue from(long long);
- static JSValue from(unsigned long long);
- static JSValue from(double);
-
- static ALWAYS_INLINE bool isEitherImmediate(JSValue v1, JSValue v2)
- {
- return (rawValue(v1) | rawValue(v2)) & TagMask;
- }
-
- static ALWAYS_INLINE bool areBothImmediate(JSValue v1, JSValue v2)
- {
- return isImmediate(v1) & isImmediate(v2);
- }
-
- static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
- {
- return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
- }
-
- static double toDouble(JSValue);
- static bool toBoolean(JSValue);
-
- static bool getUInt32(JSValue, uint32_t&);
- static bool getTruncatedInt32(JSValue, int32_t&);
- static bool getTruncatedUInt32(JSValue, uint32_t&);
-
- static int32_t getTruncatedInt32(JSValue);
- static uint32_t getTruncatedUInt32(JSValue);
-
- static JSValue trueImmediate();
- static JSValue falseImmediate();
- static JSValue undefinedImmediate();
- static JSValue nullImmediate();
- static JSValue zeroImmediate();
- static JSValue oneImmediate();
-
- private:
- static const int minImmediateInt = ((-INT_MAX) - 1);
- static const int maxImmediateInt = INT_MAX;
- static const unsigned maxImmediateUInt = maxImmediateInt;
-
- static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
- {
- return JSValue::makeImmediate(integer);
- }
-
- // With USE(JSVALUE64) we want the argument to be zero extended, so the
- // integer doesn't interfere with the tag bits in the upper word. In the default encoding,
- // if intptr_t id larger then int32_t we sign extend the value through the upper word.
- static ALWAYS_INLINE JSValue makeInt(uint32_t value)
- {
- return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
- }
-
- static ALWAYS_INLINE JSValue makeDouble(double value)
- {
- return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
- }
-
- static ALWAYS_INLINE JSValue makeBool(bool b)
- {
- return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
- }
-
- static ALWAYS_INLINE JSValue makeUndefined()
- {
- return makeValue(FullTagTypeUndefined);
- }
-
- static ALWAYS_INLINE JSValue makeNull()
- {
- return makeValue(FullTagTypeNull);
- }
-
- template<typename T>
- static JSValue fromNumberOutsideIntegerRange(T);
-
- static ALWAYS_INLINE double doubleValue(JSValue v)
- {
- return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
- }
-
- static ALWAYS_INLINE int32_t intValue(JSValue v)
- {
- return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift);
- }
-
- static ALWAYS_INLINE uint32_t uintValue(JSValue v)
- {
- return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
- }
-
- static ALWAYS_INLINE bool boolValue(JSValue v)
- {
- return rawValue(v) & ExtendedPayloadBitBoolValue;
- }
-
- static ALWAYS_INLINE intptr_t rawValue(JSValue v)
- {
- return v.immediateValue();
- }
- };
-
- ALWAYS_INLINE JSValue JSImmediate::trueImmediate() { return makeBool(true); }
- ALWAYS_INLINE JSValue JSImmediate::falseImmediate() { return makeBool(false); }
- ALWAYS_INLINE JSValue JSImmediate::undefinedImmediate() { return makeUndefined(); }
- ALWAYS_INLINE JSValue JSImmediate::nullImmediate() { return makeNull(); }
- ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); }
- ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
-
- inline bool doubleToBoolean(double value)
- {
- return value < 0.0 || value > 0.0;
- }
-
- ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
- {
- ASSERT(isImmediate(v));
- return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
- : doubleToBoolean(doubleValue(v)) : v == trueImmediate();
- }
-
- ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
- {
- // FIXME: should probably be asserting isPositiveIntegerNumber here.
- ASSERT(isIntegerNumber(v));
- return intValue(v);
- }
-
- template<typename T>
- inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
- {
- return makeDouble(static_cast<double>(value));
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(char i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(signed char i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(unsigned char i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(short i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(unsigned short i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(int i)
- {
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(unsigned i)
- {
- if (i > maxImmediateUInt)
- return fromNumberOutsideIntegerRange(i);
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(long i)
- {
- if ((i < minImmediateInt) | (i > maxImmediateInt))
- return fromNumberOutsideIntegerRange(i);
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(unsigned long i)
- {
- if (i > maxImmediateUInt)
- return fromNumberOutsideIntegerRange(i);
- return makeInt(i);
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(long long i)
- {
- if ((i < minImmediateInt) | (i > maxImmediateInt))
- return JSValue();
- return makeInt(static_cast<intptr_t>(i));
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(unsigned long long i)
- {
- if (i > maxImmediateUInt)
- return fromNumberOutsideIntegerRange(i);
- return makeInt(static_cast<intptr_t>(i));
- }
-
- ALWAYS_INLINE JSValue JSImmediate::from(double d)
- {
- const int intVal = static_cast<int>(d);
-
- // Check for data loss from conversion to int.
- if (intVal != d || (!intVal && signbit(d)))
- return fromNumberOutsideIntegerRange(d);
-
- return from(intVal);
- }
-
- ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v)
- {
- ASSERT(isIntegerNumber(v));
- return intValue(v);
- }
-
- ALWAYS_INLINE double JSImmediate::toDouble(JSValue v)
- {
- ASSERT(isImmediate(v));
-
- if (isIntegerNumber(v))
- return intValue(v);
-
- if (isNumber(v)) {
- ASSERT(isDouble(v));
- return doubleValue(v);
- }
-
- if (rawValue(v) == FullTagTypeUndefined)
- return nonInlineNaN();
-
- ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate()));
- return rawValue(v) >> ExtendedPayloadShift;
- }
-
- ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i)
- {
- i = uintValue(v);
- return isPositiveIntegerNumber(v);
- }
-
- ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i)
- {
- i = intValue(v);
- return isIntegerNumber(v);
- }
-
- ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i)
- {
- return getUInt32(v, i);
- }
-
- inline JSValue::JSValue(JSNullTag)
- {
- *this = JSImmediate::nullImmediate();
- }
-
- inline JSValue::JSValue(JSUndefinedTag)
- {
- *this = JSImmediate::undefinedImmediate();
- }
-
- inline JSValue::JSValue(JSTrueTag)
- {
- *this = JSImmediate::trueImmediate();
- }
-
- inline JSValue::JSValue(JSFalseTag)
- {
- *this = JSImmediate::falseImmediate();
- }
-
- inline bool JSValue::isUndefinedOrNull() const
- {
- return JSImmediate::isUndefinedOrNull(asValue());
- }
-
- inline bool JSValue::isBoolean() const
- {
- return JSImmediate::isBoolean(asValue());
- }
-
- inline bool JSValue::isTrue() const
- {
- return asValue() == JSImmediate::trueImmediate();
- }
-
- inline bool JSValue::isFalse() const
- {
- return asValue() == JSImmediate::falseImmediate();
- }
-
- inline bool JSValue::getBoolean(bool& v) const
- {
- if (JSImmediate::isBoolean(asValue())) {
- v = JSImmediate::toBoolean(asValue());
- return true;
- }
-
- return false;
- }
-
- inline bool JSValue::getBoolean() const
- {
- return asValue() == jsBoolean(true);
- }
-
- inline bool JSValue::isCell() const
- {
- return !JSImmediate::isImmediate(asValue());
- }
-
- inline bool JSValue::isInt32() const
- {
- return JSImmediate::isIntegerNumber(asValue());
- }
-
- inline int32_t JSValue::asInt32() const
- {
- ASSERT(isInt32());
- return JSImmediate::getTruncatedInt32(asValue());
- }
-
- inline bool JSValue::isUInt32() const
- {
- return JSImmediate::isPositiveIntegerNumber(asValue());
- }
-
- inline uint32_t JSValue::asUInt32() const
- {
- ASSERT(isUInt32());
- return JSImmediate::getTruncatedUInt32(asValue());
- }
-
-} // namespace JSC
-
-#endif // USE(JSVALUE64)
-
-#endif // JSImmediate_h
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.h b/Source/JavaScriptCore/runtime/JSNotAnObject.h
index 75bca18..4c6806a 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.h
@@ -39,11 +39,11 @@ namespace JSC {
class JSNotAnObject : public JSNonFinalObject {
public:
JSNotAnObject(ExecState* exec)
- : JSNonFinalObject(exec->globalData().notAnObjectStructure)
+ : JSNonFinalObject(exec->globalData(), exec->globalData().notAnObjectStructure.get())
{
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/JSNumberCell.cpp b/Source/JavaScriptCore/runtime/JSNumberCell.cpp
deleted file mode 100644
index 79f2d2a..0000000
--- a/Source/JavaScriptCore/runtime/JSNumberCell.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "JSNumberCell.h"
-#include "JSObject.h"
-#include "ScopeChain.h"
-
-// Keep our exported symbols lists happy.
-namespace JSC {
-
-JSValue jsNumberCell(ExecState*, double);
-
-JSValue jsNumberCell(ExecState*, double)
-{
- ASSERT_NOT_REACHED();
- return JSValue();
-}
-
-} // namespace JSC
-
diff --git a/Source/JavaScriptCore/runtime/JSNumberCell.h b/Source/JavaScriptCore/runtime/JSNumberCell.h
deleted file mode 100644
index 1ccdf50..0000000
--- a/Source/JavaScriptCore/runtime/JSNumberCell.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef JSNumberCell_h
-#define JSNumberCell_h
-
-#include "CallFrame.h"
-#include "JSCell.h"
-#include "JSImmediate.h"
-#include "Heap.h"
-#include "UString.h"
-#include <stddef.h> // for size_t
-
-namespace JSC {
-
- extern const double NaN;
- extern const double Inf;
-
-#if USE(JSVALUE64)
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
- {
- *this = JSImmediate::fromNumberOutsideIntegerRange(d);
- }
-
- inline JSValue::JSValue(double d)
- {
- JSValue v = JSImmediate::from(d);
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(int i)
- {
- JSValue v = JSImmediate::from(i);
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(unsigned i)
- {
- JSValue v = JSImmediate::from(i);
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(long i)
- {
- JSValue v = JSImmediate::from(i);
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(unsigned long i)
- {
- JSValue v = JSImmediate::from(i);
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(long long i)
- {
- JSValue v = JSImmediate::from(static_cast<double>(i));
- ASSERT(v);
- *this = v;
- }
-
- inline JSValue::JSValue(unsigned long long i)
- {
- JSValue v = JSImmediate::from(static_cast<double>(i));
- ASSERT(v);
- *this = v;
- }
-
- inline bool JSValue::isDouble() const
- {
- return JSImmediate::isDouble(asValue());
- }
-
- inline double JSValue::asDouble() const
- {
- return JSImmediate::doubleValue(asValue());
- }
-
- inline bool JSValue::isNumber() const
- {
- return JSImmediate::isNumber(asValue());
- }
-
- inline double JSValue::uncheckedGetNumber() const
- {
- ASSERT(isNumber());
- return JSImmediate::toDouble(asValue());
- }
-
-#endif // USE(JSVALUE64)
-
-#if USE(JSVALUE64)
-
- inline JSValue::JSValue(char i)
- {
- ASSERT(JSImmediate::from(i));
- *this = JSImmediate::from(i);
- }
-
- inline JSValue::JSValue(unsigned char i)
- {
- ASSERT(JSImmediate::from(i));
- *this = JSImmediate::from(i);
- }
-
- inline JSValue::JSValue(short i)
- {
- ASSERT(JSImmediate::from(i));
- *this = JSImmediate::from(i);
- }
-
- inline JSValue::JSValue(unsigned short i)
- {
- ASSERT(JSImmediate::from(i));
- *this = JSImmediate::from(i);
- }
-
- inline JSValue jsNaN()
- {
- return jsNumber(NaN);
- }
-
- // --- JSValue inlines ----------------------------
-
- ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
- {
- return isNumber() ? asValue() : jsNumber(this->toNumber(exec));
- }
-
- inline bool JSValue::getNumber(double &result) const
- {
- if (isInt32())
- result = asInt32();
- else if (LIKELY(isDouble()))
- result = asDouble();
- else {
- ASSERT(!isNumber());
- return false;
- }
- return true;
- }
-
-#endif // USE(JSVALUE64)
-
-} // namespace JSC
-
-#endif // JSNumberCell_h
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index 8fc7ac9..27fc569 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -53,7 +53,7 @@ static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*);
namespace JSC {
-JSONObject::JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
+JSONObject::JSONObject(JSGlobalObject* globalObject, Structure* structure)
: JSObjectWithGlobalObject(globalObject, structure)
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/JSONObject.h b/Source/JavaScriptCore/runtime/JSONObject.h
index a52c543..c87c641 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.h
+++ b/Source/JavaScriptCore/runtime/JSONObject.h
@@ -34,9 +34,9 @@ namespace JSC {
class JSONObject : public JSObjectWithGlobalObject {
public:
- JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure);
+ JSONObject(JSGlobalObject*, Structure*);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index b307540..9677f23 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -109,7 +109,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
// Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
if (!value.isObject() && !value.isNull())
return;
- if (!setPrototypeWithCycleCheck(value))
+ if (!setPrototypeWithCycleCheck(exec->globalData(), value))
throwError(exec, createError(exec, "cyclic __proto__ value"));
return;
}
@@ -127,14 +127,14 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
unsigned attributes;
JSCell* specificValue;
- if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
+ if ((m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
if (slot.isStrictMode())
throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
return;
}
for (JSObject* obj = this; ; obj = asObject(prototype)) {
- if (JSValue gs = obj->getDirect(propertyName)) {
+ if (JSValue gs = obj->getDirect(exec->globalData(), propertyName)) {
if (gs.isGetterSetter()) {
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
@@ -218,10 +218,10 @@ bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
unsigned attributes;
JSCell* specificValue;
- if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
+ if (m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) {
if ((attributes & DontDelete))
return false;
- removeDirect(propertyName);
+ removeDirect(exec->globalData(), propertyName);
return true;
}
@@ -312,34 +312,33 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi
void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
{
- JSValue object = getDirect(propertyName);
+ JSValue object = getDirect(exec->globalData(), propertyName);
if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setGetter(exec->globalData(), getterFunction);
return;
}
+ JSGlobalData& globalData = exec->globalData();
PutPropertySlot slot;
GetterSetter* getterSetter = new (exec) GetterSetter(exec);
- putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, true, slot);
+ putDirectInternal(globalData, propertyName, getterSetter, attributes | Getter, true, slot);
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
if (slot.type() != PutPropertySlot::NewProperty) {
- if (!m_structure->isDictionary()) {
- RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
- setStructure(structure.release());
- }
+ if (!m_structure->isDictionary())
+ setStructure(exec->globalData(), Structure::getterSetterTransition(globalData, m_structure.get()));
}
m_structure->setHasGetterSetterProperties(true);
- getterSetter->setGetter(exec->globalData(), getterFunction);
+ getterSetter->setGetter(globalData, getterFunction);
}
void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes)
{
- JSValue object = getDirect(propertyName);
+ JSValue object = getDirect(exec->globalData(), propertyName);
if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setSetter(exec->globalData(), setterFunction);
@@ -354,21 +353,19 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
if (slot.type() != PutPropertySlot::NewProperty) {
- if (!m_structure->isDictionary()) {
- RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
- setStructure(structure.release());
- }
+ if (!m_structure->isDictionary())
+ setStructure(exec->globalData(), Structure::getterSetterTransition(exec->globalData(), m_structure.get()));
}
m_structure->setHasGetterSetterProperties(true);
getterSetter->setSetter(exec->globalData(), setterFunction);
}
-JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupGetter(ExecState* exec, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- if (JSValue value = object->getDirect(propertyName)) {
+ if (JSValue value = object->getDirect(exec->globalData(), propertyName)) {
if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->getter();
@@ -383,11 +380,11 @@ JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
}
}
-JSValue JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupSetter(ExecState* exec, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- if (JSValue value = object->getDirect(propertyName)) {
+ if (JSValue value = object->getDirect(exec->globalData(), propertyName)) {
if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->setter();
@@ -428,10 +425,10 @@ bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyN
return descriptor.enumerable();
}
-bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const
+bool JSObject::getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificValue) const
{
unsigned attributes;
- if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
+ if (m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound)
return true;
// This could be a function within the static table? - should probably
@@ -464,7 +461,7 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName
void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- m_structure->getPropertyNames(propertyNames, mode);
+ m_structure->getPropertyNames(exec->globalData(), propertyNames, mode);
getClassPropertyNames(exec, classInfo(), propertyNames, mode);
}
@@ -509,34 +506,33 @@ JSObject* JSObject::unwrappedObject()
return this;
}
-void JSObject::seal()
+void JSObject::seal(JSGlobalData& globalData)
{
- setStructure(Structure::sealTransition(m_structure));
+ setStructure(globalData, Structure::sealTransition(globalData, m_structure.get()));
}
-void JSObject::freeze()
+void JSObject::freeze(JSGlobalData& globalData)
{
- setStructure(Structure::freezeTransition(m_structure));
+ setStructure(globalData, Structure::freezeTransition(globalData, m_structure.get()));
}
-void JSObject::preventExtensions()
+void JSObject::preventExtensions(JSGlobalData& globalData)
{
if (isExtensible())
- setStructure(Structure::preventExtensionsTransition(m_structure));
+ setStructure(globalData, Structure::preventExtensionsTransition(globalData, m_structure.get()));
}
-void JSObject::removeDirect(const Identifier& propertyName)
+void JSObject::removeDirect(JSGlobalData& globalData, const Identifier& propertyName)
{
size_t offset;
if (m_structure->isUncacheableDictionary()) {
- offset = m_structure->removePropertyWithoutTransition(propertyName);
+ offset = m_structure->removePropertyWithoutTransition(globalData, propertyName);
if (offset != WTF::notFound)
putUndefinedAtDirectOffset(offset);
return;
}
- RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
- setStructure(structure.release());
+ setStructure(globalData, Structure::removePropertyTransition(globalData, m_structure.get(), propertyName, offset));
if (offset != WTF::notFound)
putUndefinedAtDirectOffset(offset);
}
@@ -574,7 +570,8 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, WriteBarr
Structure* JSObject::createInheritorID(JSGlobalData& globalData)
{
- m_inheritorID = createEmptyObjectStructure(globalData, this);
+ m_inheritorID.set(globalData, this, createEmptyObjectStructure(globalData, this));
+ ASSERT(m_inheritorID->isEmpty());
return m_inheritorID.get();
}
@@ -598,11 +595,11 @@ void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
m_propertyStorage = newPropertyStorage;
}
-bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor)
+bool JSObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
unsigned attributes = 0;
JSCell* cell = 0;
- size_t offset = m_structure->get(propertyName, attributes, cell);
+ size_t offset = m_structure->get(exec->globalData(), propertyName, attributes, cell);
if (offset == WTF::notFound)
return false;
descriptor.setDescriptor(getDirectOffset(offset), attributes);
@@ -754,7 +751,7 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
return false;
}
}
- JSValue accessor = getDirect(propertyName);
+ JSValue accessor = getDirect(exec->globalData(), propertyName);
if (!accessor)
return false;
GetterSetter* getterSetter = asGetterSetter(accessor);
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 578b3cf..80735f8 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -29,7 +29,6 @@
#include "Completion.h"
#include "CallFrame.h"
#include "JSCell.h"
-#include "JSNumberCell.h"
#include "MarkStack.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
@@ -88,10 +87,10 @@ namespace JSC {
virtual ~JSObject();
JSValue prototype() const;
- void setPrototype(JSValue prototype);
- bool setPrototypeWithCycleCheck(JSValue prototype);
+ void setPrototype(JSGlobalData&, JSValue prototype);
+ bool setPrototypeWithCycleCheck(JSGlobalData&, JSValue prototype);
- void setStructure(NonNullPassRefPtr<Structure>);
+ void setStructure(JSGlobalData&, Structure*);
Structure* inheritorID(JSGlobalData&);
virtual UString className() const;
@@ -147,22 +146,22 @@ namespace JSC {
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
// This get function only looks at the property map.
- JSValue getDirect(const Identifier& propertyName) const
+ JSValue getDirect(JSGlobalData& globalData, const Identifier& propertyName) const
{
- size_t offset = m_structure->get(propertyName);
+ size_t offset = m_structure->get(globalData, propertyName);
return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
}
- WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName)
+ WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, const Identifier& propertyName)
{
- size_t offset = m_structure->get(propertyName);
+ size_t offset = m_structure->get(globalData, propertyName);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- WriteBarrierBase<Unknown>* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes)
{
JSCell* specificFunction;
- size_t offset = m_structure->get(propertyName, attributes, specificFunction);
+ size_t offset = m_structure->get(globalData, propertyName, attributes, specificFunction);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
@@ -171,9 +170,9 @@ namespace JSC {
return location - propertyStorage();
}
- void transitionTo(Structure*);
+ void transitionTo(JSGlobalData&, Structure*);
- void removeDirect(const Identifier& propertyName);
+ void removeDirect(JSGlobalData&, const Identifier& propertyName);
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
@@ -210,17 +209,17 @@ namespace JSC {
virtual bool isStrictModeFunction() const { return false; }
virtual bool isErrorInstance() const { return false; }
- void seal();
- void freeze();
- void preventExtensions();
- bool isSealed() { return m_structure->isSealed(); }
- bool isFrozen() { return m_structure->isFrozen(); }
+ void seal(JSGlobalData&);
+ void freeze(JSGlobalData&);
+ void preventExtensions(JSGlobalData&);
+ bool isSealed(JSGlobalData& globalData) { return m_structure->isSealed(globalData); }
+ bool isFrozen(JSGlobalData& globalData) { return m_structure->isFrozen(globalData); }
bool isExtensible() { return m_structure->isExtensible(); }
virtual ComplType exceptionType() const { return Throw; }
void allocatePropertyStorage(size_t oldSize, size_t newSize);
- bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
+ bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
static const unsigned baseExternalStorageCapacity = 16;
@@ -250,7 +249,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -264,7 +263,12 @@ namespace JSC {
// To instantiate objects you likely want JSFinalObject, below.
// To create derived types you likely want JSNonFinalObject, below.
- JSObject(NonNullPassRefPtr<Structure>, PropertyStorage inlineStorage);
+ JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
+ JSObject(VPtrStealingHackType, PropertyStorage inlineStorage)
+ : JSCell(VPtrStealingHack)
+ , m_propertyStorage(inlineStorage)
+ {
+ }
private:
// Nobody should ever ask any of these questions on something already known to be a JSObject.
@@ -299,7 +303,7 @@ namespace JSC {
Structure* createInheritorID(JSGlobalData&);
PropertyStorage m_propertyStorage;
- RefPtr<Structure> m_inheritorID;
+ WriteBarrier<Structure> m_inheritorID;
};
@@ -320,14 +324,19 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- explicit JSNonFinalObject(NonNullPassRefPtr<Structure> structure)
- : JSObject(structure, m_inlineStorage)
+ explicit JSNonFinalObject(VPtrStealingHackType)
+ : JSObject(VPtrStealingHack, m_inlineStorage)
+ {
+ }
+
+ explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure)
+ : JSObject(globalData, structure, m_inlineStorage)
{
ASSERT(!(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double)));
ASSERT(this->structure()->propertyStorageCapacity() == JSNonFinalObject_inlineStorageCapacity);
@@ -343,19 +352,19 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static JSFinalObject* create(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+ static JSFinalObject* create(ExecState* exec, Structure* structure)
{
- return new (exec) JSFinalObject(structure);
+ return new (exec) JSFinalObject(exec->globalData(), structure);
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
- explicit JSFinalObject(NonNullPassRefPtr<Structure> structure)
- : JSObject(structure, m_inlineStorage)
+ explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
+ : JSObject(globalData, structure, m_inlineStorage)
{
ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double) == 0);
ASSERT(this->structure()->propertyStorageCapacity() == JSFinalObject_inlineStorageCapacity);
@@ -372,12 +381,12 @@ inline size_t JSObject::offsetOfInlineStorage()
return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
}
-inline JSObject* constructEmptyObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
{
return JSFinalObject::create(exec, structure);
}
-inline PassRefPtr<Structure> createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
+inline Structure* createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
{
return JSFinalObject::createStructure(globalData, prototype);
}
@@ -393,22 +402,22 @@ inline JSObject* asObject(JSValue value)
return asObject(value.asCell());
}
-inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure, PropertyStorage inlineStorage)
- : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
+inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, PropertyStorage inlineStorage)
+ : JSCell(globalData, structure)
, m_propertyStorage(inlineStorage)
{
ASSERT(inherits(&s_info));
ASSERT(m_structure->propertyStorageCapacity() < baseExternalStorageCapacity);
ASSERT(m_structure->isEmpty());
ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
+ ASSERT(static_cast<void*>(inlineStorage) == static_cast<void*>(this + 1));
+ ASSERT(m_structure->typeInfo().type() == ObjectType);
}
inline JSObject::~JSObject()
{
- ASSERT(m_structure);
if (!isUsingInlineStorage())
delete [] m_propertyStorage;
- m_structure->deref();
}
inline JSValue JSObject::prototype() const
@@ -416,7 +425,7 @@ inline JSValue JSObject::prototype() const
return m_structure->storedPrototype();
}
-inline bool JSObject::setPrototypeWithCycleCheck(JSValue prototype)
+inline bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
{
JSValue nextPrototypeValue = prototype;
while (nextPrototypeValue && nextPrototypeValue.isObject()) {
@@ -425,27 +434,27 @@ inline bool JSObject::setPrototypeWithCycleCheck(JSValue prototype)
return false;
nextPrototypeValue = nextPrototype->prototype();
}
- setPrototype(prototype);
+ setPrototype(globalData, prototype);
return true;
}
-inline void JSObject::setPrototype(JSValue prototype)
+inline void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
{
ASSERT(prototype);
- RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
- setStructure(newStructure.release());
+ setStructure(globalData, Structure::changePrototypeTransition(globalData, m_structure.get(), prototype));
}
-inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure)
+inline void JSObject::setStructure(JSGlobalData& globalData, Structure* structure)
{
- m_structure->deref();
- m_structure = structure.leakRef(); // ~JSObject balances this ref()
+ m_structure.set(globalData, this, structure);
}
inline Structure* JSObject::inheritorID(JSGlobalData& globalData)
{
- if (m_inheritorID)
+ if (m_inheritorID) {
+ ASSERT(m_inheritorID->isEmpty());
return m_inheritorID.get();
+ }
return createInheritorID(globalData);
}
@@ -471,7 +480,7 @@ inline bool JSValue::inherits(const ClassInfo* classInfo) const
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (WriteBarrierBase<Unknown>* location = getDirectLocation(propertyName)) {
+ if (WriteBarrierBase<Unknown>* location = getDirectLocation(exec->globalData(), propertyName)) {
if (m_structure->hasGetterSetterProperties() && location->isGetterSetter())
fillGetterPropertySlot(slot, location);
else
@@ -557,12 +566,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
if (m_structure->isDictionary()) {
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ size_t offset = m_structure->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
// If there is currently a specific function, and there now either isn't,
// or the new value is different, then despecify.
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
- m_structure->despecifyDictionaryFunction(propertyName);
+ m_structure->despecifyDictionaryFunction(globalData, propertyName);
if (checkReadOnly && currentAttributes & ReadOnly)
return false;
@@ -582,7 +591,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return false;
size_t currentCapacity = m_structure->propertyStorageCapacity();
- offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction);
+ offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
@@ -596,12 +605,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
size_t offset;
size_t currentCapacity = m_structure->propertyStorageCapacity();
- if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) {
+ if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(m_structure.get(), propertyName, attributes, specificFunction, offset)) {
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- setStructure(structure.release());
+ setStructure(globalData, structure);
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.
@@ -612,7 +621,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ offset = m_structure->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
return false;
@@ -633,7 +642,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return true;
}
// case (2) Despecify, fall through to (3).
- setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
+ setStructure(globalData, Structure::despecifyFunctionTransition(globalData, m_structure.get(), propertyName));
}
// case (3) set the slot, do the put, return.
@@ -645,13 +654,13 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
if (!isExtensible())
return false;
- RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
+ Structure* structure = Structure::addPropertyTransition(globalData, m_structure.get(), propertyName, attributes, specificFunction, offset);
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- setStructure(structure.release());
+ setStructure(globalData, structure);
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.
@@ -707,7 +716,7 @@ inline void JSObject::putDirectFunction(JSGlobalData& globalData, const Identifi
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);
+ size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, 0);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
@@ -716,17 +725,17 @@ inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const
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);
+ size_t offset = m_structure->addPropertyWithoutTransition(globalData, propertyName, attributes, value);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
putDirectOffset(globalData, offset, value);
}
-inline void JSObject::transitionTo(Structure* newStructure)
+inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure)
{
if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
- setStructure(newStructure);
+ setStructure(globalData, newStructure);
}
inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
@@ -814,13 +823,12 @@ inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
{
JSCell::markChildren(markStack);
-
- markStack.append(m_structure->storedPrototypeSlot());
- if (*m_structure->cachedPrototypeChainSlot())
- markStack.append(m_structure->cachedPrototypeChainSlot());
+
PropertyStorage storage = propertyStorage();
size_t storageSize = m_structure->propertyStorageSize();
markStack.appendValues(storage, storageSize);
+ if (m_inheritorID)
+ markStack.append(&m_inheritorID);
}
// --- JSValue inlines ----------------------------
diff --git a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
index 9370139..2b489a2 100644
--- a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp
@@ -30,8 +30,8 @@
namespace JSC {
-JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
- : JSNonFinalObject(structure)
+JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalObject* globalObject, Structure* structure)
+ : JSNonFinalObject(globalObject->globalData(), structure)
{
COMPILE_ASSERT(AnonymousSlotCount == 1, AnonymousSlotCount_must_be_one);
ASSERT(!globalObject || globalObject->isGlobalObject());
@@ -41,9 +41,15 @@ JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalObject* globalObject,
putAnonymousValue(globalObject->globalData(), GlobalObjectSlot, globalObject);
}
-JSGlobalObject* JSObjectWithGlobalObject::globalObject() const
+JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject, Structure* structure)
+ : JSNonFinalObject(globalData, structure)
{
- return asGlobalObject((getAnonymousValue(GlobalObjectSlot).asCell()));
+ COMPILE_ASSERT(AnonymousSlotCount == 1, AnonymousSlotCount_must_be_one);
+ ASSERT(!globalObject || globalObject->isGlobalObject());
+ if (!globalObject)
+ clearAnonymousValue(GlobalObjectSlot);
+ else
+ putAnonymousValue(globalData, GlobalObjectSlot, globalObject);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
index 8380514..844bcd8 100644
--- a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
@@ -26,7 +26,7 @@
#ifndef JSObjectWithGlobalObject_h
#define JSObjectWithGlobalObject_h
-#include "JSObject.h"
+#include "JSGlobalObject.h"
namespace JSC {
@@ -34,18 +34,22 @@ class JSGlobalObject;
class JSObjectWithGlobalObject : public JSNonFinalObject {
public:
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto)
{
return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- JSGlobalObject* globalObject() const;
+ JSGlobalObject* globalObject() const
+ {
+ return asGlobalObject((getAnonymousValue(GlobalObjectSlot).asCell()));
+ }
protected:
- JSObjectWithGlobalObject(JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ JSObjectWithGlobalObject(JSGlobalObject*, Structure*);
+ JSObjectWithGlobalObject(JSGlobalData&, JSGlobalObject*, Structure*);
- JSObjectWithGlobalObject(NonNullPassRefPtr<Structure> structure)
- : JSNonFinalObject(structure)
+ JSObjectWithGlobalObject(VPtrStealingHackType)
+ : JSNonFinalObject(VPtrStealingHack)
{
// Should only be used by JSFunction when we aquire the JSFunction vptr.
}
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 6f31f99..d5af044 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -35,9 +35,10 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
+const ClassInfo JSPropertyNameIterator::s_info = { "JSPropertyNameIterator", 0, 0, 0 };
+
inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
- : JSCell(exec->globalData().propertyNameIteratorStructure.get())
- , m_cachedStructure(0)
+ : JSCell(exec->globalData(), exec->globalData().propertyNameIteratorStructure.get())
, m_numCacheableSlots(numCacheableSlots)
, m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
, m_jsStrings(adoptArrayPtr(new WriteBarrier<Unknown>[m_jsStringsSize]))
@@ -71,14 +72,14 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
size_t count = normalizePrototypeChain(exec, o);
StructureChain* structureChain = o->structure()->prototypeChain(exec);
- RefPtr<Structure>* structure = structureChain->head();
+ WriteBarrier<Structure>* structure = structureChain->head();
for (size_t i = 0; i < count; ++i) {
if (structure[i]->typeInfo().overridesGetPropertyNames())
return jsPropertyNameIterator;
}
jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain);
- jsPropertyNameIterator->setCachedStructure(o->structure());
+ jsPropertyNameIterator->setCachedStructure(exec->globalData(), o->structure());
o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator);
return jsPropertyNameIterator;
}
@@ -86,7 +87,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
JSValue identifier = m_jsStrings[i].get();
- if (m_cachedStructure == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
+ if (m_cachedStructure.get() == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
return identifier;
if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
@@ -101,12 +102,4 @@ void JSPropertyNameIterator::markChildren(MarkStack& markStack)
markStack.append(&m_cachedPrototypeChain);
}
-#if !ASSERT_DISABLED
-
-JSPropertyNameIterator::~JSPropertyNameIterator()
-{
- ASSERT(!m_cachedStructure || m_cachedStructure->enumerationCache() != this);
-}
-
-#endif
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index 499396c..b857dc0 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -45,9 +45,9 @@ namespace JSC {
public:
static JSPropertyNameIterator* create(ExecState*, JSObject*);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, &s_info);
}
virtual bool isPropertyNameIterator() const { return true; }
@@ -65,11 +65,11 @@ namespace JSC {
JSValue get(ExecState*, JSObject*, size_t i);
size_t size() { return m_jsStringsSize; }
- void setCachedStructure(Structure* structure)
+ void setCachedStructure(JSGlobalData& globalData, Structure* structure)
{
ASSERT(!m_cachedStructure);
ASSERT(structure);
- m_cachedStructure = structure;
+ m_cachedStructure.set(globalData, this, structure);
}
Structure* cachedStructure() { return m_cachedStructure.get(); }
@@ -77,13 +77,10 @@ namespace JSC {
StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
private:
+ static const ClassInfo s_info;
JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
-
-#if !ASSERT_DISABLED
- virtual ~JSPropertyNameIterator();
-#endif
- RefPtr<Structure> m_cachedStructure;
+ WriteBarrier<Structure> m_cachedStructure;
WriteBarrier<StructureChain> m_cachedPrototypeChain;
uint32_t m_numCacheableSlots;
uint32_t m_jsStringsSize;
@@ -93,12 +90,7 @@ namespace JSC {
inline void Structure::setEnumerationCache(JSGlobalData& globalData, JSPropertyNameIterator* enumerationCache)
{
ASSERT(!isDictionary());
- m_enumerationCache.set(globalData, enumerationCache, 0);
- }
-
- inline void Structure::clearEnumerationCache()
- {
- m_enumerationCache.clear();
+ m_enumerationCache.set(globalData, this, enumerationCache);
}
inline JSPropertyNameIterator* Structure::enumerationCache()
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
index 3e19bbc..8c3a249 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -33,7 +33,7 @@ namespace JSC{
class JSStaticScopeObject : public JSVariableObject {
public:
JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes)
- : JSVariableObject(exec->globalData().staticScopeStructure, &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1))
+ : JSVariableObject(exec->globalData(), exec->globalData().staticScopeStructure.get(), &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1))
{
m_registerStore.set(exec->globalData(), this, value);
symbolTable().add(ident.impl(), SymbolTableEntry(-1, attributes));
@@ -47,7 +47,7 @@ namespace JSC{
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 9113d4a..3422dad 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -26,10 +26,10 @@
#include "CallFrame.h"
#include "CommonIdentifiers.h"
#include "Identifier.h"
-#include "JSNumberCell.h"
#include "PropertyDescriptor.h"
#include "PropertySlot.h"
#include "RopeImpl.h"
+#include "Structure.h"
namespace JSC {
@@ -185,7 +185,7 @@ namespace JSC {
};
ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(value.length())
, m_value(value)
, m_fiberCount(0)
@@ -196,7 +196,7 @@ namespace JSC {
enum HasOtherOwnerType { HasOtherOwner };
JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(value.length())
, m_value(value)
, m_fiberCount(0)
@@ -204,7 +204,7 @@ namespace JSC {
ASSERT(!m_value.isNull());
}
JSString(JSGlobalData* globalData, PassRefPtr<StringImpl> value, HasOtherOwnerType)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(value->length())
, m_value(value)
, m_fiberCount(0)
@@ -212,7 +212,7 @@ namespace JSC {
ASSERT(!m_value.isNull());
}
JSString(JSGlobalData* globalData, PassRefPtr<RopeImpl> rope)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(rope->length())
, m_fiberCount(1)
{
@@ -221,7 +221,7 @@ namespace JSC {
// This constructor constructs a new string by concatenating s1 & s2.
// This should only be called with fiberCount <= 3.
JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, JSString* s2)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(s1->length() + s2->length())
, m_fiberCount(fiberCount)
{
@@ -234,7 +234,7 @@ namespace JSC {
// This constructor constructs a new string by concatenating s1 & s2.
// This should only be called with fiberCount <= 3.
JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, const UString& u2)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(s1->length() + u2.length())
, m_fiberCount(fiberCount)
{
@@ -247,7 +247,7 @@ namespace JSC {
// This constructor constructs a new string by concatenating s1 & s2.
// This should only be called with fiberCount <= 3.
JSString(JSGlobalData* globalData, unsigned fiberCount, const UString& u1, JSString* s2)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(u1.length() + s2->length())
, m_fiberCount(fiberCount)
{
@@ -262,7 +262,7 @@ namespace JSC {
// value must require a fiberCount of at least one implies that the length
// for each value must be exactly 1!
JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
- : JSCell(exec->globalData().stringStructure.get())
+ : JSCell(exec->globalData(), exec->globalData().stringStructure.get())
, m_length(0)
, m_fiberCount(s_maxInternalRopeLength)
{
@@ -275,7 +275,7 @@ namespace JSC {
// This constructor constructs a new string by concatenating u1 & u2.
JSString(JSGlobalData* globalData, const UString& u1, const UString& u2)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(u1.length() + u2.length())
, m_fiberCount(2)
{
@@ -287,7 +287,7 @@ namespace JSC {
// This constructor constructs a new string by concatenating u1, u2 & u3.
JSString(JSGlobalData* globalData, const UString& u1, const UString& u2, const UString& u3)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(u1.length() + u2.length() + u3.length())
, m_fiberCount(s_maxInternalRopeLength)
{
@@ -299,7 +299,7 @@ namespace JSC {
}
JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context)
- : JSCell(globalData->stringStructure.get())
+ : JSCell(*globalData, globalData->stringStructure.get())
, m_length(value.length())
, m_value(value)
, m_fiberCount(0)
@@ -349,12 +349,11 @@ namespace JSC {
JSValue replaceCharacter(ExecState*, UChar, const UString& replacement);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
private:
- enum VPtrStealingHackType { VPtrStealingHack };
JSString(VPtrStealingHackType)
- : JSCell(0)
+ : JSCell(VPtrStealingHack)
, m_fiberCount(0)
{
}
diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h
index 882b218..dba03f6 100644
--- a/Source/JavaScriptCore/runtime/JSType.h
+++ b/Source/JavaScriptCore/runtime/JSType.h
@@ -33,10 +33,11 @@ namespace JSC {
NumberType = 3,
NullType = 4,
StringType = 5,
+ LeafType = 6,
// The CompoundType value must come before any JSType that may have children
- CompoundType = 6,
- ObjectType = 7,
- GetterSetterType = 8
+ CompoundType = 7,
+ ObjectType = 8,
+ GetterSetterType = 9
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSTypeInfo.h b/Source/JavaScriptCore/runtime/JSTypeInfo.h
index 284d2b2..acde81f 100644
--- a/Source/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/Source/JavaScriptCore/runtime/JSTypeInfo.h
@@ -54,6 +54,7 @@ namespace JSC {
{
ASSERT(flags <= 0x1FF);
ASSERT(type <= 0xFF);
+ ASSERT(type >= CompoundType || !(flags & OverridesMarkChildren));
// ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
m_flags |= ImplementsDefaultHasInstance;
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index 098123e..de50011 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -30,15 +30,18 @@
#include <wtf/Assertions.h>
#include <wtf/HashTraits.h>
#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
namespace JSC {
+ extern const double NaN;
+ extern const double Inf;
+
class ExecState;
class Identifier;
class JSCell;
class JSGlobalData;
class JSGlobalObject;
- class JSImmediate;
class JSObject;
class JSString;
class PropertySlot;
@@ -48,7 +51,6 @@ namespace JSC {
struct ClassInfo;
struct Instruction;
- template <class T> class DeprecatedPtr;
template <class T> class WriteBarrierBase;
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
@@ -61,7 +63,7 @@ namespace JSC {
#endif
union EncodedValueDescriptor {
- EncodedJSValue asEncodedJSValue;
+ int64_t asInt64;
#if USE(JSVALUE32_64)
double asDouble;
#elif USE(JSVALUE64)
@@ -95,7 +97,6 @@ namespace JSC {
}
class JSValue {
- friend class JSImmediate;
friend struct EncodedJSValueHashTraits;
friend class JIT;
friend class JITStubs;
@@ -104,14 +105,9 @@ namespace JSC {
friend class SpecializedThunkJIT;
public:
- static EncodedJSValue encode(JSValue value);
- static JSValue decode(EncodedJSValue ptr);
-#if USE(JSVALUE64)
- private:
- static JSValue makeImmediate(intptr_t value);
- intptr_t immediateValue();
- public:
-#endif
+ static EncodedJSValue encode(JSValue);
+ static JSValue decode(EncodedJSValue);
+
enum JSNullTag { JSNull };
enum JSUndefinedTag { JSUndefined };
enum JSTrueTag { JSTrue };
@@ -239,7 +235,6 @@ namespace JSC {
#endif
private:
- template <class T> JSValue(DeprecatedPtr<T>);
template <class T> JSValue(WriteBarrierBase<T>);
enum HashTableDeletedValueTag { HashTableDeletedValue };
@@ -253,24 +248,120 @@ namespace JSC {
JSObject* synthesizeObject(ExecState*) const;
#if USE(JSVALUE32_64)
- enum { NullTag = 0xffffffff };
- enum { UndefinedTag = 0xfffffffe };
- enum { Int32Tag = 0xfffffffd };
- enum { CellTag = 0xfffffffc };
- enum { TrueTag = 0xfffffffb };
- enum { FalseTag = 0xfffffffa };
- enum { EmptyValueTag = 0xfffffff9 };
- enum { DeletedValueTag = 0xfffffff8 };
-
+ /*
+ * On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
+ * form for immediates.
+ *
+ * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
+ * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
+ * can encode a 51-bit payload. Hardware produced and C-library payloads typically
+ * have a payload of zero. We assume that non-zero payloads are available to encode
+ * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
+ * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+ * ranges to encode other values (however there are also other ranges of NaN space that
+ * could have been selected).
+ *
+ * For JSValues that do not contain a double value, the high 32 bits contain the tag
+ * values listed in the enums below, which all correspond to NaN-space. In the case of
+ * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer
+ * integer or boolean value; in the case of all other tags the payload is 0.
+ */
+ enum { Int32Tag = 0xffffffff };
+ enum { BooleanTag = 0xfffffffe };
+ enum { NullTag = 0xfffffffd };
+ enum { UndefinedTag = 0xfffffffc };
+ enum { CellTag = 0xfffffffb };
+ enum { EmptyValueTag = 0xfffffffa };
+ enum { DeletedValueTag = 0xfffffff9 };
+
enum { LowestTag = DeletedValueTag };
uint32_t tag() const;
int32_t payload() const;
-
- EncodedValueDescriptor u;
#elif USE(JSVALUE64)
- JSCell* m_ptr;
+ /*
+ * On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded
+ * form for immediates.
+ *
+ * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
+ * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
+ * can encode a 51-bit payload. Hardware produced and C-library payloads typically
+ * have a payload of zero. We assume that non-zero payloads are available to encode
+ * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
+ * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+ * ranges to encode other values (however there are also other ranges of NaN space that
+ * could have been selected).
+ *
+ * This range of NaN space is represented by 64-bit numbers begining with the 16-bit
+ * hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no valid double-precision
+ * numbers will begin fall in these ranges.
+ *
+ * The top 16-bits denote the type of the encoded JSValue:
+ *
+ * Pointer { 0000:PPPP:PPPP:PPPP
+ * / 0001:****:****:****
+ * Double { ...
+ * \ FFFE:****:****:****
+ * Integer { FFFF:0000:IIII:IIII
+ *
+ * The scheme we have implemented encodes double precision values by performing a
+ * 64-bit integer addition of the value 2^48 to the number. After this manipulation
+ * no encoded double-precision value will begin with the pattern 0x0000 or 0xFFFF.
+ * Values must be decoded by reversing this operation before subsequent floating point
+ * operations my be peformed.
+ *
+ * 32-bit signed integers are marked with the 16-bit tag 0xFFFF.
+ *
+ * The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean,
+ * null and undefined values are represented by specific, invalid pointer values:
+ *
+ * False: 0x06
+ * True: 0x07
+ * Undefined: 0x0a
+ * Null: 0x02
+ *
+ * These values have the following properties:
+ * - Bit 1 (TagBitTypeOther) is set for all four values, allowing real pointers to be
+ * quickly distinguished from all immediate values, including these invalid pointers.
+ * - With bit 3 is masked out (TagBitUndefined) Undefined and Null share the
+ * same value, allowing null & undefined to be quickly detected.
+ *
+ * No valid JSValue will have the bit pattern 0x0, this is used to represent array
+ * holes, and as a C++ 'no value' result (e.g. JSValue() has an internal value of 0).
+ */
+
+ // These values are #defines since using static const integers here is a ~1% regression!
+
+ // This value is 2^48, used to encode doubles such that the encoded value will begin
+ // with a 16-bit pattern within the range 0x0001..0xFFFE.
+ #define DoubleEncodeOffset 0x1000000000000ll
+ // If all bits in the mask are set, this indicates an integer number,
+ // if any but not all are set this value is a double precision number.
+ #define TagTypeNumber 0xffff000000000000ll
+
+ // All non-numeric (bool, null, undefined) immediates have bit 2 set.
+ #define TagBitTypeOther 0x2ll
+ #define TagBitBool 0x4ll
+ #define TagBitUndefined 0x8ll
+ // Combined integer value for non-numeric immediates.
+ #define ValueFalse (TagBitTypeOther | TagBitBool | false)
+ #define ValueTrue (TagBitTypeOther | TagBitBool | true)
+ #define ValueUndefined (TagBitTypeOther | TagBitUndefined)
+ #define ValueNull (TagBitTypeOther)
+
+ // TagMask is used to check for all types of immediate values (either number or 'other').
+ #define TagMask (TagTypeNumber | TagBitTypeOther)
+
+ // These special values are never visible to JavaScript code; Empty is used to represent
+ // Array holes, and for uninitialized JSValues. Deleted is used in hash table code.
+ // These values would map to cell types in the JSValue encoding, but not valid GC cell
+ // pointer should have either of these values (Empty is null, deleted is at an invalid
+ // alignment for a GC cell, and in the zero page).
+ #define ValueEmpty 0x0ll
+ #define ValueDeleted 0x4ll
#endif
+
+ EncodedValueDescriptor u;
};
#if USE(JSVALUE32_64)
@@ -373,409 +464,7 @@ namespace JSC {
inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
- ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
- {
- if (isInt32())
- return asInt32();
- return JSC::toInt32(toNumber(exec));
- }
-
- inline uint32_t JSValue::toUInt32(ExecState* exec) const
- {
- // See comment on JSC::toUInt32, above.
- return toInt32(exec);
- }
-
-#if USE(JSVALUE32_64)
- inline JSValue jsNaN()
- {
- return JSValue(nonInlineNaN());
- }
-
- // JSValue member functions.
- inline EncodedJSValue JSValue::encode(JSValue value)
- {
- return value.u.asEncodedJSValue;
- }
-
- inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
- {
- JSValue v;
- v.u.asEncodedJSValue = encodedJSValue;
- return v;
- }
-
- inline JSValue::JSValue()
- {
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSNullTag)
- {
- u.asBits.tag = NullTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSUndefinedTag)
- {
- u.asBits.tag = UndefinedTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSTrueTag)
- {
- u.asBits.tag = TrueTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSFalseTag)
- {
- u.asBits.tag = FalseTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(HashTableDeletedValueTag)
- {
- u.asBits.tag = DeletedValueTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSCell* ptr)
- {
- if (ptr)
- u.asBits.tag = CellTag;
- else
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = reinterpret_cast<int32_t>(ptr);
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!isZombie());
-#endif
- }
-
- inline JSValue::JSValue(const JSCell* ptr)
- {
- if (ptr)
- u.asBits.tag = CellTag;
- else
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!isZombie());
-#endif
- }
-
- inline JSValue::operator bool() const
- {
- ASSERT(tag() != DeletedValueTag);
- return tag() != EmptyValueTag;
- }
-
- inline bool JSValue::operator==(const JSValue& other) const
- {
- return u.asEncodedJSValue == other.u.asEncodedJSValue;
- }
-
- inline bool JSValue::operator!=(const JSValue& other) const
- {
- return u.asEncodedJSValue != other.u.asEncodedJSValue;
- }
-
- inline bool JSValue::isUndefined() const
- {
- return tag() == UndefinedTag;
- }
-
- inline bool JSValue::isNull() const
- {
- return tag() == NullTag;
- }
-
- inline bool JSValue::isUndefinedOrNull() const
- {
- return isUndefined() || isNull();
- }
-
- inline bool JSValue::isCell() const
- {
- return tag() == CellTag;
- }
-
- inline bool JSValue::isInt32() const
- {
- return tag() == Int32Tag;
- }
-
- inline bool JSValue::isUInt32() const
- {
- return tag() == Int32Tag && asInt32() > -1;
- }
-
- inline bool JSValue::isDouble() const
- {
- return tag() < LowestTag;
- }
-
- inline bool JSValue::isTrue() const
- {
- return tag() == TrueTag;
- }
-
- inline bool JSValue::isFalse() const
- {
- return tag() == FalseTag;
- }
-
- inline uint32_t JSValue::tag() const
- {
- return u.asBits.tag;
- }
-
- inline int32_t JSValue::payload() const
- {
- return u.asBits.payload;
- }
-
- inline int32_t JSValue::asInt32() const
- {
- ASSERT(isInt32());
- return u.asBits.payload;
- }
-
- inline uint32_t JSValue::asUInt32() const
- {
- ASSERT(isUInt32());
- return u.asBits.payload;
- }
-
- inline double JSValue::asDouble() const
- {
- ASSERT(isDouble());
- return u.asDouble;
- }
-
- ALWAYS_INLINE JSCell* JSValue::asCell() const
- {
- ASSERT(isCell());
- return reinterpret_cast<JSCell*>(u.asBits.payload);
- }
-
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
- {
- u.asDouble = d;
- }
-
- inline JSValue::JSValue(double d)
- {
- const int32_t asInt32 = static_cast<int32_t>(d);
- if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
- u.asDouble = d;
- return;
- }
- *this = JSValue(static_cast<int32_t>(d));
- }
-
- inline JSValue::JSValue(char i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned char i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(short i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned short i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(int i)
- {
- u.asBits.tag = Int32Tag;
- u.asBits.payload = i;
- }
-
- inline JSValue::JSValue(unsigned i)
- {
- if (static_cast<int32_t>(i) < 0) {
- *this = JSValue(static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(long i)
- {
- if (static_cast<int32_t>(i) != i) {
- *this = JSValue(static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned long i)
- {
- if (static_cast<uint32_t>(i) != i) {
- *this = JSValue(static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<uint32_t>(i));
- }
-
- inline JSValue::JSValue(long long i)
- {
- if (static_cast<int32_t>(i) != i) {
- *this = JSValue(static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned long long i)
- {
- if (static_cast<uint32_t>(i) != i) {
- *this = JSValue(static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<uint32_t>(i));
- }
-
- inline bool JSValue::isNumber() const
- {
- return isInt32() || isDouble();
- }
-
- inline bool JSValue::isBoolean() const
- {
- return isTrue() || isFalse();
- }
-
- inline bool JSValue::getBoolean(bool& v) const
- {
- if (isTrue()) {
- v = true;
- return true;
- }
- if (isFalse()) {
- v = false;
- return true;
- }
-
- return false;
- }
-
- inline bool JSValue::getBoolean() const
- {
- ASSERT(isBoolean());
- return tag() == TrueTag;
- }
-
- inline double JSValue::uncheckedGetNumber() const
- {
- ASSERT(isNumber());
- return isInt32() ? asInt32() : asDouble();
- }
-
- ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
- {
- return isNumber() ? asValue() : jsNumber(this->toNumber(exec));
- }
-
- inline bool JSValue::getNumber(double& result) const
- {
- if (isInt32()) {
- result = asInt32();
- return true;
- }
- if (isDouble()) {
- result = asDouble();
- return true;
- }
- return false;
- }
-
-#else // USE(JSVALUE32_64)
-
- // JSValue member functions.
- inline EncodedJSValue JSValue::encode(JSValue value)
- {
- return reinterpret_cast<EncodedJSValue>(value.m_ptr);
- }
-
- inline JSValue JSValue::decode(EncodedJSValue ptr)
- {
- return JSValue(reinterpret_cast<JSCell*>(ptr));
- }
-
- inline JSValue JSValue::makeImmediate(intptr_t value)
- {
- return JSValue(reinterpret_cast<JSCell*>(value));
- }
-
- inline intptr_t JSValue::immediateValue()
- {
- return reinterpret_cast<intptr_t>(m_ptr);
- }
-
- // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
- inline JSValue::JSValue()
- : m_ptr(0)
- {
- }
-
- // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
- inline JSValue::JSValue(HashTableDeletedValueTag)
- : m_ptr(reinterpret_cast<JSCell*>(0x4))
- {
- }
-
- inline JSValue::JSValue(JSCell* ptr)
- : m_ptr(ptr)
- {
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!isZombie());
-#endif
- }
-
- inline JSValue::JSValue(const JSCell* ptr)
- : m_ptr(const_cast<JSCell*>(ptr))
- {
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!isZombie());
-#endif
- }
-
- inline JSValue::operator bool() const
- {
- return m_ptr;
- }
-
- inline bool JSValue::operator==(const JSValue& other) const
- {
- return m_ptr == other.m_ptr;
- }
-
- inline bool JSValue::operator!=(const JSValue& other) const
- {
- return m_ptr != other.m_ptr;
- }
-
- inline bool JSValue::isUndefined() const
- {
- return asValue() == jsUndefined();
- }
-
- inline bool JSValue::isNull() const
- {
- return asValue() == jsNull();
- }
-#endif // USE(JSVALUE32_64)
+ bool isZombie(const JSCell*);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
new file mode 100644
index 0000000..b4f6f80
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
@@ -0,0 +1,532 @@
+/*
+ * 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. ``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 JSValueInlineMethods_h
+#define JSValueInlineMethods_h
+
+#include "JSValue.h"
+
+namespace JSC {
+
+ ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
+ {
+ if (isInt32())
+ return asInt32();
+ return JSC::toInt32(toNumber(exec));
+ }
+
+ inline uint32_t JSValue::toUInt32(ExecState* exec) const
+ {
+ // See comment on JSC::toUInt32, above.
+ return toInt32(exec);
+ }
+
+ inline bool JSValue::isUInt32() const
+ {
+ return isInt32() && asInt32() >= 0;
+ }
+
+ inline uint32_t JSValue::asUInt32() const
+ {
+ ASSERT(isUInt32());
+ return asInt32();
+ }
+
+ inline double JSValue::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return isInt32() ? asInt32() : asDouble();
+ }
+
+ ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
+ {
+ return isNumber() ? asValue() : jsNumber(this->toNumber(exec));
+ }
+
+ inline JSValue jsNaN()
+ {
+ return JSValue(nonInlineNaN());
+ }
+
+ inline bool JSValue::getNumber(double& result) const
+ {
+ if (isInt32()) {
+ result = asInt32();
+ return true;
+ }
+ if (isDouble()) {
+ result = asDouble();
+ return true;
+ }
+ return false;
+ }
+
+ inline bool JSValue::getBoolean(bool& v) const
+ {
+ if (isTrue()) {
+ v = true;
+ return true;
+ }
+ if (isFalse()) {
+ v = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ inline JSValue::JSValue(char i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned char i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(short i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned short i)
+ {
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned i)
+ {
+ if (static_cast<int32_t>(i) < 0) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(long i)
+ {
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned long i)
+ {
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+ }
+
+ inline JSValue::JSValue(long long i)
+ {
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+ }
+
+ inline JSValue::JSValue(unsigned long long i)
+ {
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+ }
+
+ inline JSValue::JSValue(double d)
+ {
+ const int32_t asInt32 = static_cast<int32_t>(d);
+ if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
+ *this = JSValue(EncodeAsDouble, d);
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(d));
+ }
+
+#if USE(JSVALUE32_64)
+ inline EncodedJSValue JSValue::encode(JSValue value)
+ {
+ return value.u.asInt64;
+ }
+
+ inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
+ {
+ JSValue v;
+ v.u.asInt64 = encodedJSValue;
+ return v;
+ }
+
+ inline JSValue::JSValue()
+ {
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSNullTag)
+ {
+ u.asBits.tag = NullTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSUndefinedTag)
+ {
+ u.asBits.tag = UndefinedTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSTrueTag)
+ {
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 1;
+ }
+
+ inline JSValue::JSValue(JSFalseTag)
+ {
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(HashTableDeletedValueTag)
+ {
+ u.asBits.tag = DeletedValueTag;
+ u.asBits.payload = 0;
+ }
+
+ inline JSValue::JSValue(JSCell* ptr)
+ {
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(ptr);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::JSValue(const JSCell* ptr)
+ {
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::operator bool() const
+ {
+ ASSERT(tag() != DeletedValueTag);
+ return tag() != EmptyValueTag;
+ }
+
+ inline bool JSValue::operator==(const JSValue& other) const
+ {
+ return u.asInt64 == other.u.asInt64;
+ }
+
+ inline bool JSValue::operator!=(const JSValue& other) const
+ {
+ return u.asInt64 != other.u.asInt64;
+ }
+
+ inline bool JSValue::isUndefined() const
+ {
+ return tag() == UndefinedTag;
+ }
+
+ inline bool JSValue::isNull() const
+ {
+ return tag() == NullTag;
+ }
+
+ inline bool JSValue::isUndefinedOrNull() const
+ {
+ return isUndefined() || isNull();
+ }
+
+ inline bool JSValue::isCell() const
+ {
+ return tag() == CellTag;
+ }
+
+ inline bool JSValue::isInt32() const
+ {
+ return tag() == Int32Tag;
+ }
+
+ inline bool JSValue::isDouble() const
+ {
+ return tag() < LowestTag;
+ }
+
+ inline bool JSValue::isTrue() const
+ {
+ return tag() == BooleanTag && payload();
+ }
+
+ inline bool JSValue::isFalse() const
+ {
+ return tag() == BooleanTag && !payload();
+ }
+
+ inline uint32_t JSValue::tag() const
+ {
+ return u.asBits.tag;
+ }
+
+ inline int32_t JSValue::payload() const
+ {
+ return u.asBits.payload;
+ }
+
+ inline int32_t JSValue::asInt32() const
+ {
+ ASSERT(isInt32());
+ return u.asBits.payload;
+ }
+
+ inline double JSValue::asDouble() const
+ {
+ ASSERT(isDouble());
+ return u.asDouble;
+ }
+
+ ALWAYS_INLINE JSCell* JSValue::asCell() const
+ {
+ ASSERT(isCell());
+ return reinterpret_cast<JSCell*>(u.asBits.payload);
+ }
+
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+ {
+ u.asDouble = d;
+ }
+
+ inline JSValue::JSValue(int i)
+ {
+ u.asBits.tag = Int32Tag;
+ u.asBits.payload = i;
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return isInt32() || isDouble();
+ }
+
+ inline bool JSValue::isBoolean() const
+ {
+ return isTrue() || isFalse();
+ }
+
+ inline bool JSValue::getBoolean() const
+ {
+ ASSERT(isBoolean());
+ return payload();
+ }
+
+#else // USE(JSVALUE32_64)
+
+ // JSValue member functions.
+ inline EncodedJSValue JSValue::encode(JSValue value)
+ {
+ return value.u.ptr;
+ }
+
+ inline JSValue JSValue::decode(EncodedJSValue ptr)
+ {
+ return JSValue(reinterpret_cast<JSCell*>(ptr));
+ }
+
+ // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
+ inline JSValue::JSValue()
+ {
+ u.asInt64 = ValueEmpty;
+ }
+
+ // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
+ inline JSValue::JSValue(HashTableDeletedValueTag)
+ {
+ u.asInt64 = ValueDeleted;
+ }
+
+ inline JSValue::JSValue(JSCell* ptr)
+ {
+ u.ptr = ptr;
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::JSValue(const JSCell* ptr)
+ {
+ u.ptr = const_cast<JSCell*>(ptr);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
+ }
+
+ inline JSValue::operator bool() const
+ {
+ return u.ptr;
+ }
+
+ inline bool JSValue::operator==(const JSValue& other) const
+ {
+ return u.ptr == other.u.ptr;
+ }
+
+ inline bool JSValue::operator!=(const JSValue& other) const
+ {
+ return u.ptr != other.u.ptr;
+ }
+
+ inline bool JSValue::isUndefined() const
+ {
+ return asValue() == jsUndefined();
+ }
+
+ inline bool JSValue::isNull() const
+ {
+ return asValue() == jsNull();
+ }
+
+ inline bool JSValue::isTrue() const
+ {
+ return asValue() == JSValue(JSTrue);
+ }
+
+ inline bool JSValue::isFalse() const
+ {
+ return asValue() == JSValue(JSFalse);
+ }
+
+ inline bool JSValue::getBoolean() const
+ {
+ ASSERT(asValue() == jsBoolean(true) || asValue() == jsBoolean(false));
+ return asValue() == jsBoolean(true);
+ }
+
+ inline int32_t JSValue::asInt32() const
+ {
+ ASSERT(isInt32());
+ return static_cast<int32_t>(u.asInt64);
+ }
+
+ inline bool JSValue::isDouble() const
+ {
+ return isNumber() && !isInt32();
+ }
+
+ inline JSValue::JSValue(JSNullTag)
+ {
+ u.asInt64 = ValueNull;
+ }
+
+ inline JSValue::JSValue(JSUndefinedTag)
+ {
+ u.asInt64 = ValueUndefined;
+ }
+
+ inline JSValue::JSValue(JSTrueTag)
+ {
+ u.asInt64 = ValueTrue;
+ }
+
+ inline JSValue::JSValue(JSFalseTag)
+ {
+ u.asInt64 = ValueFalse;
+ }
+
+ inline bool JSValue::isUndefinedOrNull() const
+ {
+ // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
+ return (u.asInt64 & ~TagBitUndefined) == ValueNull;
+ }
+
+ inline bool JSValue::isBoolean() const
+ {
+ return (u.asInt64 & ~1) == ValueFalse;
+ }
+
+ inline bool JSValue::isCell() const
+ {
+ return !(u.asInt64 & TagMask);
+ }
+
+ inline bool JSValue::isInt32() const
+ {
+ return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
+ }
+
+ inline intptr_t reinterpretDoubleToIntptr(double value)
+ {
+ return bitwise_cast<intptr_t>(value);
+ }
+ inline double reinterpretIntptrToDouble(intptr_t value)
+ {
+ return bitwise_cast<double>(value);
+ }
+
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+ {
+ u.asInt64 = reinterpretDoubleToIntptr(d) + DoubleEncodeOffset;
+ }
+
+ inline JSValue::JSValue(int i)
+ {
+ u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
+ }
+
+ inline double JSValue::asDouble() const
+ {
+ return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return u.asInt64 & TagTypeNumber;
+ }
+
+ ALWAYS_INLINE JSCell* JSValue::asCell() const
+ {
+ ASSERT(isCell());
+ return u.ptr;
+ }
+
+#endif // USE(JSVALUE64)
+
+} // namespace JSC
+
+#endif // JSValueInlineMethods_h
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 891ada8..89bb6b0 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -58,7 +58,7 @@ namespace JSC {
WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -66,8 +66,8 @@ namespace JSC {
protected:
static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags;
- JSVariableObject(NonNullPassRefPtr<Structure> structure, SymbolTable* symbolTable, Register* registers)
- : JSNonFinalObject(structure)
+ JSVariableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable, Register* registers)
+ : JSNonFinalObject(globalData, structure)
, m_symbolTable(symbolTable)
, m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
{
@@ -75,7 +75,7 @@ namespace JSC {
COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier);
}
- PassOwnArrayPtr<WriteBarrier<Unknown> > copyRegisterArray(JSGlobalData&, WriteBarrier<Unknown>* src, size_t count);
+ PassOwnArrayPtr<WriteBarrier<Unknown> > copyRegisterArray(JSGlobalData&, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts);
void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray);
bool symbolTableGet(const Identifier&, PropertySlot&);
@@ -137,10 +137,12 @@ namespace JSC {
return true;
}
- inline PassOwnArrayPtr<WriteBarrier<Unknown> > JSVariableObject::copyRegisterArray(JSGlobalData& globalData, WriteBarrier<Unknown>* src, size_t count)
+ inline PassOwnArrayPtr<WriteBarrier<Unknown> > JSVariableObject::copyRegisterArray(JSGlobalData& globalData, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts)
{
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[count]);
- for (size_t i = 0; i < count; i++)
+ for (size_t i = 0; i < callframeStarts; i++)
+ registerArray[i].set(globalData, this, src[i].get());
+ for (size_t i = callframeStarts + RegisterFile::CallFrameHeaderSize; i < count; i++)
registerArray[i].set(globalData, this, src[i].get());
return registerArray.release();
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index 63833e9..a7dbe0d 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -30,13 +30,13 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSNonFinalObject {
protected:
- explicit JSWrapperObject(NonNullPassRefPtr<Structure>);
+ explicit JSWrapperObject(JSGlobalData&, Structure*);
public:
JSValue internalValue() const;
void setInternalValue(JSGlobalData&, JSValue);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -50,8 +50,8 @@ namespace JSC {
WriteBarrier<Unknown> m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure)
- : JSNonFinalObject(structure)
+ inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure)
+ : JSNonFinalObject(globalData, structure)
{
}
diff --git a/Source/JavaScriptCore/runtime/JSZombie.cpp b/Source/JavaScriptCore/runtime/JSZombie.cpp
index 23cf135..efabc93 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.cpp
+++ b/Source/JavaScriptCore/runtime/JSZombie.cpp
@@ -35,16 +35,6 @@ namespace JSC {
const ClassInfo JSZombie::s_info = { "Zombie", 0, 0, 0 };
-Structure* JSZombie::leakedZombieStructure() {
- static Structure* structure = 0;
- if (!structure) {
- Structure::startIgnoringLeaks();
- structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0, &s_info).leakRef();
- Structure::stopIgnoringLeaks();
- }
- return structure;
-}
-
}
#endif // ENABLE(JSC_ZOMBIES)
diff --git a/Source/JavaScriptCore/runtime/JSZombie.h b/Source/JavaScriptCore/runtime/JSZombie.h
index 179ff53..0559b96 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.h
+++ b/Source/JavaScriptCore/runtime/JSZombie.h
@@ -27,21 +27,21 @@
#define JSZombie_h
#include "JSCell.h"
+#include "Structure.h"
#if ENABLE(JSC_ZOMBIES)
namespace JSC {
class JSZombie : public JSCell {
public:
- JSZombie(const ClassInfo* oldInfo, Structure* structure)
- : JSCell(structure)
+ JSZombie(JSGlobalData& globalData, const ClassInfo* oldInfo, Structure* structure)
+ : JSCell(globalData, structure)
, m_oldInfo(oldInfo)
{
ASSERT(inherits(&s_info));
}
virtual bool isZombie() const { return true; }
- static Structure* leakedZombieStructure();
virtual bool isGetterSetter() const { ASSERT_NOT_REACHED(); return false; }
virtual bool isAPIValueWrapper() const { ASSERT_NOT_REACHED(); return false; }
@@ -66,9 +66,9 @@ public:
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(globalData, prototype, TypeInfo(ObjectType, 0), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(LeafType, 0), AnonymousSlotCount, &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/Lookup.cpp b/Source/JavaScriptCore/runtime/Lookup.cpp
index 307bceb..25b516e 100644
--- a/Source/JavaScriptCore/runtime/Lookup.cpp
+++ b/Source/JavaScriptCore/runtime/Lookup.cpp
@@ -73,7 +73,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);
- WriteBarrierBase<Unknown>* location = thisObj->getDirectLocation(propertyName);
+ WriteBarrierBase<Unknown>* location = thisObj->getDirectLocation(exec->globalData(), propertyName);
if (!location) {
JSFunction* function;
@@ -86,7 +86,7 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
function = new (exec) JSFunction(exec, globalObject, globalObject->functionStructure(), entry->functionLength(), propertyName, entry->function());
thisObj->putDirectFunction(exec->globalData(), propertyName, function, entry->attributes());
- location = thisObj->getDirectLocation(propertyName);
+ location = thisObj->getDirectLocation(exec->globalData(), propertyName);
}
slot.setValue(thisObj, location->get(), thisObj->offsetForLocation(location));
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
deleted file mode 100644
index 3e205a1..0000000
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2009 Acision BV. 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
- *
- */
-
-#include "config.h"
-#include "MachineStackMarker.h"
-
-#include "ConservativeSet.h"
-#include "Heap.h"
-#include "JSArray.h"
-#include "JSGlobalData.h"
-#include <setjmp.h>
-#include <stdlib.h>
-#include <wtf/StdLibExtras.h>
-
-#if USE(PTHREAD_BASED_QT) && !defined(WTF_USE_PTHREADS)
-#define WTF_USE_PTHREADS 1
-#endif
-
-#if OS(DARWIN)
-
-#include <mach/mach_init.h>
-#include <mach/mach_port.h>
-#include <mach/task.h>
-#include <mach/thread_act.h>
-#include <mach/vm_map.h>
-
-#elif OS(WINDOWS)
-
-#include <windows.h>
-#include <malloc.h>
-
-#elif OS(HAIKU)
-
-#include <OS.h>
-
-#elif OS(UNIX)
-
-#include <stdlib.h>
-#if !OS(HAIKU)
-#include <sys/mman.h>
-#endif
-#include <unistd.h>
-
-#if OS(SOLARIS)
-#include <thread.h>
-#else
-#include <pthread.h>
-#endif
-
-#if HAVE(PTHREAD_NP_H)
-#include <pthread_np.h>
-#endif
-
-#if OS(QNX)
-#include <fcntl.h>
-#include <sys/procfs.h>
-#include <stdio.h>
-#include <errno.h>
-#endif
-
-#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
-#include <signal.h>
-#ifndef SA_RESTART
-#error MachineThreads requires SA_RESTART
-#endif
-#endif
-
-#endif
-
-using namespace WTF;
-
-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)
-typedef mach_port_t PlatformThread;
-#elif OS(WINDOWS)
-typedef HANDLE PlatformThread;
-#elif USE(PTHREADS)
-typedef pthread_t PlatformThread;
-static const int SigThreadSuspendResume = SIGUSR2;
-
-static void pthreadSignalHandlerSuspendResume(int signo)
-{
- sigset_t signalSet;
- sigemptyset(&signalSet);
- sigaddset(&signalSet, SigThreadSuspendResume);
- sigsuspend(&signalSet);
-}
-#endif
-
-class MachineThreads::Thread {
-public:
- Thread(pthread_t pthread, const PlatformThread& platThread, void* base)
- : posixThread(pthread)
- , platformThread(platThread)
- , stackBase(base)
- {
-#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
- struct sigaction action;
- action.sa_handler = pthreadSignalHandlerSuspendResume;
- sigemptyset(&action.sa_mask);
- action.sa_flags = SA_RESTART;
- sigaction(SigThreadSuspendResume, &action, 0);
-
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, SigThreadSuspendResume);
- pthread_sigmask(SIG_UNBLOCK, &mask, 0);
-#endif
- }
-
- Thread* next;
- pthread_t posixThread;
- PlatformThread platformThread;
- void* stackBase;
-};
-
-#endif
-
-MachineThreads::MachineThreads(Heap* heap)
- : m_heap(heap)
-#if ENABLE(JSC_MULTIPLE_THREADS)
- , m_registeredThreads(0)
- , m_threadSpecific(0)
-#endif
-{
-}
-
-MachineThreads::~MachineThreads()
-{
-#if ENABLE(JSC_MULTIPLE_THREADS)
- if (m_threadSpecific) {
- int error = pthread_key_delete(m_threadSpecific);
- ASSERT_UNUSED(error, !error);
- }
-
- MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
- for (Thread* t = m_registeredThreads; t;) {
- Thread* next = t->next;
- delete t;
- t = next;
- }
-#endif
-}
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-static inline PlatformThread getCurrentPlatformThread()
-{
-#if OS(DARWIN)
- return pthread_mach_thread_np(pthread_self());
-#elif OS(WINDOWS)
- return pthread_getw32threadhandle_np(pthread_self());
-#elif USE(PTHREADS)
- return pthread_self();
-#endif
-}
-
-void MachineThreads::makeUsableFromMultipleThreads()
-{
- if (m_threadSpecific)
- return;
-
- int error = pthread_key_create(&m_threadSpecific, removeThread);
- if (error)
- CRASH();
-}
-
-void MachineThreads::addCurrentThread()
-{
- ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
-
- if (!m_threadSpecific || pthread_getspecific(m_threadSpecific))
- return;
-
- pthread_setspecific(m_threadSpecific, this);
- Thread* thread = new Thread(pthread_self(), getCurrentPlatformThread(), m_heap->globalData()->stack().origin());
-
- MutexLocker lock(m_registeredThreadsMutex);
-
- thread->next = m_registeredThreads;
- m_registeredThreads = thread;
-}
-
-void MachineThreads::removeThread(void* p)
-{
- if (p)
- static_cast<MachineThreads*>(p)->removeCurrentThread();
-}
-
-void MachineThreads::removeCurrentThread()
-{
- pthread_t currentPosixThread = pthread_self();
-
- MutexLocker lock(m_registeredThreadsMutex);
-
- if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) {
- Thread* t = m_registeredThreads;
- m_registeredThreads = m_registeredThreads->next;
- delete t;
- } else {
- Thread* last = m_registeredThreads;
- Thread* t;
- for (t = m_registeredThreads->next; t; t = t->next) {
- if (pthread_equal(t->posixThread, currentPosixThread)) {
- last->next = t->next;
- break;
- }
- last = t;
- }
- ASSERT(t); // If t is NULL, we never found ourselves in the list.
- delete t;
- }
-}
-
-#endif
-
-#if COMPILER(GCC)
-#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
-#else
-#define REGISTER_BUFFER_ALIGNMENT
-#endif
-
-void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, void* stackCurrent)
-{
- // setjmp forces volatile registers onto the stack
- jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
-#if COMPILER(MSVC)
-#pragma warning(push)
-#pragma warning(disable: 4611)
-#endif
- setjmp(registers);
-#if COMPILER(MSVC)
-#pragma warning(pop)
-#endif
-
- void* registersBegin = &registers;
- void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 1)));
- swapIfBackwards(registersBegin, registersEnd);
- conservativeRoots.add(registersBegin, registersEnd);
-
- void* stackBegin = stackCurrent;
- void* stackEnd = m_heap->globalData()->stack().origin();
- swapIfBackwards(stackBegin, stackEnd);
- conservativeRoots.add(stackBegin, stackEnd);
-}
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-static inline void suspendThread(const PlatformThread& platformThread)
-{
-#if OS(DARWIN)
- thread_suspend(platformThread);
-#elif OS(WINDOWS)
- SuspendThread(platformThread);
-#elif USE(PTHREADS)
- pthread_kill(platformThread, SigThreadSuspendResume);
-#else
-#error Need a way to suspend threads on this platform
-#endif
-}
-
-static inline void resumeThread(const PlatformThread& platformThread)
-{
-#if OS(DARWIN)
- thread_resume(platformThread);
-#elif OS(WINDOWS)
- ResumeThread(platformThread);
-#elif USE(PTHREADS)
- pthread_kill(platformThread, SigThreadSuspendResume);
-#else
-#error Need a way to resume threads on this platform
-#endif
-}
-
-typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
-
-#if OS(DARWIN)
-
-#if CPU(X86)
-typedef i386_thread_state_t PlatformThreadRegisters;
-#elif CPU(X86_64)
-typedef x86_thread_state64_t PlatformThreadRegisters;
-#elif CPU(PPC)
-typedef ppc_thread_state_t PlatformThreadRegisters;
-#elif CPU(PPC64)
-typedef ppc_thread_state64_t PlatformThreadRegisters;
-#elif CPU(ARM)
-typedef arm_thread_state_t PlatformThreadRegisters;
-#else
-#error Unknown Architecture
-#endif
-
-#elif OS(WINDOWS) && CPU(X86)
-typedef CONTEXT PlatformThreadRegisters;
-#elif USE(PTHREADS)
-typedef pthread_attr_t PlatformThreadRegisters;
-#else
-#error Need a thread register struct for this platform
-#endif
-
-static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
-{
-#if OS(DARWIN)
-
-#if CPU(X86)
- unsigned user_count = sizeof(regs)/sizeof(int);
- thread_state_flavor_t flavor = i386_THREAD_STATE;
-#elif CPU(X86_64)
- unsigned user_count = x86_THREAD_STATE64_COUNT;
- thread_state_flavor_t flavor = x86_THREAD_STATE64;
-#elif CPU(PPC)
- unsigned user_count = PPC_THREAD_STATE_COUNT;
- thread_state_flavor_t flavor = PPC_THREAD_STATE;
-#elif CPU(PPC64)
- unsigned user_count = PPC_THREAD_STATE64_COUNT;
- thread_state_flavor_t flavor = PPC_THREAD_STATE64;
-#elif CPU(ARM)
- unsigned user_count = ARM_THREAD_STATE_COUNT;
- thread_state_flavor_t flavor = ARM_THREAD_STATE;
-#else
-#error Unknown Architecture
-#endif
-
- kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)&regs, &user_count);
- if (result != KERN_SUCCESS) {
- WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION,
- "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result);
- CRASH();
- }
- return user_count * sizeof(usword_t);
-// end OS(DARWIN)
-
-#elif OS(WINDOWS) && CPU(X86)
- regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS;
- GetThreadContext(platformThread, &regs);
- return sizeof(CONTEXT);
-#elif USE(PTHREADS)
- pthread_attr_init(&regs);
-#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
- // e.g. on FreeBSD 5.4, neundorf@kde.org
- pthread_attr_get_np(platformThread, &regs);
-#else
- // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
- pthread_getattr_np(platformThread, &regs);
-#endif
- return 0;
-#else
-#error Need a way to get thread registers on this platform
-#endif
-}
-
-static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
-{
-#if OS(DARWIN)
-
-#if __DARWIN_UNIX03
-
-#if CPU(X86)
- return reinterpret_cast<void*>(regs.__esp);
-#elif CPU(X86_64)
- return reinterpret_cast<void*>(regs.__rsp);
-#elif CPU(PPC) || CPU(PPC64)
- return reinterpret_cast<void*>(regs.__r1);
-#elif CPU(ARM)
- return reinterpret_cast<void*>(regs.__sp);
-#else
-#error Unknown Architecture
-#endif
-
-#else // !__DARWIN_UNIX03
-
-#if CPU(X86)
- return reinterpret_cast<void*>(regs.esp);
-#elif CPU(X86_64)
- return reinterpret_cast<void*>(regs.rsp);
-#elif CPU(PPC) || CPU(PPC64)
- return reinterpret_cast<void*>(regs.r1);
-#else
-#error Unknown Architecture
-#endif
-
-#endif // __DARWIN_UNIX03
-
-// end OS(DARWIN)
-#elif CPU(X86) && OS(WINDOWS)
- return reinterpret_cast<void*>((uintptr_t) regs.Esp);
-#elif USE(PTHREADS)
- void* stackBase = 0;
- size_t stackSize = 0;
- int rc = pthread_attr_getstack(&regs, &stackBase, &stackSize);
- (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
- ASSERT(stackBase);
- return static_cast<char*>(stackBase) + stackSize;
-#else
-#error Need a way to get the stack pointer for another thread on this platform
-#endif
-}
-
-static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
-{
-#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
- pthread_attr_destroy(&regs);
-#else
- UNUSED_PARAM(regs);
-#endif
-}
-
-void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread)
-{
- suspendThread(thread->platformThread);
-
- PlatformThreadRegisters regs;
- size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
-
- conservativeRoots.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
-
- void* stackPointer = otherThreadStackPointer(regs);
- void* stackBase = thread->stackBase;
- swapIfBackwards(stackPointer, stackBase);
- conservativeRoots.add(stackPointer, stackBase);
-
- resumeThread(thread->platformThread);
-
- freePlatformThreadRegisters(regs);
-}
-
-#endif
-
-void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, void* stackCurrent)
-{
- gatherFromCurrentThread(conservativeRoots, stackCurrent);
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
- if (m_threadSpecific) {
-
- MutexLocker lock(m_registeredThreadsMutex);
-
-#ifndef NDEBUG
- // Forbid malloc during the gather phase. The gather phase suspends
- // threads, so a malloc during gather would risk a deadlock with a
- // thread that had been suspended while holding the malloc lock.
- fastMallocForbid();
-#endif
- // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
- // and since this is a shared heap, they are real locks.
- for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
- if (!pthread_equal(thread->posixThread, pthread_self()))
- gatherFromOtherThread(conservativeRoots, thread);
- }
-#ifndef NDEBUG
- fastMallocAllow();
-#endif
- }
-#endif
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.h b/Source/JavaScriptCore/runtime/MachineStackMarker.h
deleted file mode 100644
index c814ac5..0000000
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 MachineThreads_h
-#define MachineThreads_h
-
-#include <wtf/Noncopyable.h>
-#include <wtf/ThreadingPrimitives.h>
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-#include <pthread.h>
-#endif
-
-namespace JSC {
-
- class Heap;
- class ConservativeRoots;
-
- class MachineThreads {
- WTF_MAKE_NONCOPYABLE(MachineThreads);
- public:
- MachineThreads(Heap*);
- ~MachineThreads();
-
- void gatherConservativeRoots(ConservativeRoots&, void* stackCurrent);
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
- void makeUsableFromMultipleThreads();
- void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
-#endif
-
- private:
- void gatherFromCurrentThread(ConservativeRoots&, void* stackCurrent);
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
- class Thread;
-
- static void removeThread(void*);
- void removeCurrentThread();
-
- void gatherFromOtherThread(ConservativeRoots&, Thread*);
-#endif
-
- Heap* m_heap;
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
- Mutex m_registeredThreadsMutex;
- Thread* m_registeredThreads;
- pthread_key_t m_threadSpecific;
-#endif
- };
-
-} // namespace JSC
-
-#endif // MachineThreads_h
diff --git a/Source/JavaScriptCore/runtime/MarkStack.cpp b/Source/JavaScriptCore/runtime/MarkStack.cpp
deleted file mode 100644
index e9d1b13..0000000
--- a/Source/JavaScriptCore/runtime/MarkStack.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2009, 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. ``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 "MarkStack.h"
-
-#include "ConservativeSet.h"
-#include "Heap.h"
-#include "JSArray.h"
-#include "JSCell.h"
-#include "JSObject.h"
-#include "ScopeChain.h"
-#include "Structure.h"
-
-namespace JSC {
-
-size_t MarkStack::s_pageSize = 0;
-
-void MarkStack::compact()
-{
- ASSERT(s_pageSize);
- m_values.shrinkAllocation(s_pageSize);
- m_markSets.shrinkAllocation(s_pageSize);
-}
-
-void MarkStack::append(ConservativeRoots& conservativeRoots)
-{
- JSCell** roots = conservativeRoots.roots();
- size_t size = conservativeRoots.size();
- for (size_t i = 0; i < size; ++i)
- internalAppend(roots[i]);
-}
-
-inline void MarkStack::markChildren(JSCell* cell)
-{
- ASSERT(Heap::isMarked(cell));
- if (!cell->structure()->typeInfo().overridesMarkChildren()) {
-#ifdef NDEBUG
- asObject(cell)->markChildrenDirect(*this);
-#else
- ASSERT(!m_isCheckingForDefaultMarkViolation);
- m_isCheckingForDefaultMarkViolation = true;
- cell->markChildren(*this);
- ASSERT(m_isCheckingForDefaultMarkViolation);
- m_isCheckingForDefaultMarkViolation = false;
-#endif
- return;
- }
- if (cell->vptr() == m_jsArrayVPtr) {
- asArray(cell)->markChildrenDirect(*this);
- return;
- }
- cell->markChildren(*this);
-}
-
-void MarkStack::drain()
-{
-#if !ASSERT_DISABLED
- ASSERT(!m_isDraining);
- m_isDraining = true;
-#endif
- while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
- while (!m_markSets.isEmpty() && m_values.size() < 50) {
- ASSERT(!m_markSets.isEmpty());
- MarkSet& current = m_markSets.last();
- ASSERT(current.m_values);
- JSValue* end = current.m_end;
- ASSERT(current.m_values);
- ASSERT(current.m_values != end);
- findNextUnmarkedNullValue:
- ASSERT(current.m_values != end);
- JSValue value = *current.m_values;
- current.m_values++;
-
- JSCell* cell;
- if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (cell->structure()->typeInfo().type() < CompoundType) {
- if (current.m_values == end) {
- m_markSets.removeLast();
- continue;
- }
- goto findNextUnmarkedNullValue;
- }
-
- if (current.m_values == end)
- m_markSets.removeLast();
-
- markChildren(cell);
- }
- while (!m_values.isEmpty())
- markChildren(m_values.removeLast());
- }
-#if !ASSERT_DISABLED
- m_isDraining = false;
-#endif
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MarkStack.h b/Source/JavaScriptCore/runtime/MarkStack.h
deleted file mode 100644
index 7131917..0000000
--- a/Source/JavaScriptCore/runtime/MarkStack.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2009, 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. ``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 MarkStack_h
-#define MarkStack_h
-
-#include "JSValue.h"
-#include "Register.h"
-#include "WriteBarrier.h"
-#include <wtf/Vector.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/OSAllocator.h>
-
-namespace JSC {
-
- class ConservativeRoots;
- class JSGlobalData;
- class Register;
-
- enum MarkSetProperties { MayContainNullValues, NoNullValues };
-
- class MarkStack {
- WTF_MAKE_NONCOPYABLE(MarkStack);
- public:
- MarkStack(void* jsArrayVPtr)
- : m_jsArrayVPtr(jsArrayVPtr)
-#if !ASSERT_DISABLED
- , m_isCheckingForDefaultMarkViolation(false)
- , m_isDraining(false)
-#endif
- {
- }
-
- ~MarkStack()
- {
- ASSERT(m_markSets.isEmpty());
- ASSERT(m_values.isEmpty());
- }
-
- 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)
- {
- JSValue* values = reinterpret_cast<JSValue*>(registers);
- if (count)
- m_markSets.append(MarkSet(values, values + count, properties));
- }
-
- 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));
- }
-
- void append(ConservativeRoots&);
-
- void drain();
- void compact();
-
- private:
- friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
- void append(JSValue*);
- void append(JSValue*, size_t count);
- void append(JSCell**);
-
- void internalAppend(JSCell*);
- void internalAppend(JSValue);
- void markChildren(JSCell*);
-
- struct MarkSet {
- MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties)
- : m_values(values)
- , m_end(end)
- , m_properties(properties)
- {
- ASSERT(values);
- }
- JSValue* m_values;
- JSValue* m_end;
- MarkSetProperties m_properties;
- };
-
- static void* allocateStack(size_t size) { return OSAllocator::reserveAndCommit(size); }
- static void releaseStack(void* addr, size_t size) { OSAllocator::decommitAndRelease(addr, size); }
-
- static void initializePagesize();
- static size_t pageSize()
- {
- if (!s_pageSize)
- initializePagesize();
- return s_pageSize;
- }
-
- template <typename T> struct MarkStackArray {
- MarkStackArray()
- : m_top(0)
- , m_allocated(MarkStack::pageSize())
- , m_capacity(m_allocated / sizeof(T))
- {
- m_data = reinterpret_cast<T*>(allocateStack(m_allocated));
- }
-
- ~MarkStackArray()
- {
- releaseStack(m_data, m_allocated);
- }
-
- void expand()
- {
- size_t oldAllocation = m_allocated;
- m_allocated *= 2;
- m_capacity = m_allocated / sizeof(T);
- void* newData = allocateStack(m_allocated);
- memcpy(newData, m_data, oldAllocation);
- releaseStack(m_data, oldAllocation);
- m_data = reinterpret_cast<T*>(newData);
- }
-
- inline void append(const T& v)
- {
- if (m_top == m_capacity)
- expand();
- m_data[m_top++] = v;
- }
-
- inline T removeLast()
- {
- ASSERT(m_top);
- return m_data[--m_top];
- }
-
- inline T& last()
- {
- ASSERT(m_top);
- return m_data[m_top - 1];
- }
-
- inline bool isEmpty()
- {
- return m_top == 0;
- }
-
- inline size_t size() { return m_top; }
-
- inline void shrinkAllocation(size_t size)
- {
- ASSERT(size <= m_allocated);
- ASSERT(0 == (size % MarkStack::pageSize()));
- if (size == m_allocated)
- return;
-#if OS(WINDOWS) || OS(SYMBIAN) || PLATFORM(BREWMP)
- // We cannot release a part of a region with VirtualFree. To get around this,
- // we'll release the entire region and reallocate the size that we want.
- releaseStack(m_data, m_allocated);
- m_data = reinterpret_cast<T*>(allocateStack(size));
-#else
- releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size);
-#endif
- m_allocated = size;
- m_capacity = m_allocated / sizeof(T);
- }
-
- private:
- size_t m_top;
- size_t m_allocated;
- size_t m_capacity;
- T* m_data;
- };
-
- void* m_jsArrayVPtr;
- MarkStackArray<MarkSet> m_markSets;
- MarkStackArray<JSCell*> m_values;
- static size_t s_pageSize;
-
-#if !ASSERT_DISABLED
- public:
- bool m_isCheckingForDefaultMarkViolation;
- bool m_isDraining;
-#endif
- };
-
- inline void MarkStack::append(JSValue* slot, size_t count)
- {
- if (!count)
- return;
- m_markSets.append(MarkSet(slot, slot + count, NoNullValues));
- }
-
- template <typename T> inline void MarkStack::append(DeprecatedPtr<T>* slot)
- {
- internalAppend(*slot->slot());
- }
-
- template <typename T> inline void MarkStack::append(WriteBarrierBase<T>* slot)
- {
- internalAppend(*slot->slot());
- }
-
- 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::append(JSValue* value)
- {
- ASSERT(value);
- internalAppend(*value);
- }
-
- ALWAYS_INLINE void MarkStack::append(JSCell** 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())
- internalAppend(value.asCell());
- }
-
- // Privileged class for marking JSValues directly. It is only safe to use
- // this class to mark direct heap roots that are marked during every GC pass.
- // All other references should be wrapped in WriteBarriers and marked through
- // the MarkStack.
- class HeapRootMarker {
- private:
- friend class Heap;
- HeapRootMarker(MarkStack&);
-
- public:
- void mark(JSValue*);
- void mark(JSValue*, size_t);
- void mark(JSString**);
- void mark(JSCell**);
-
- private:
- MarkStack& m_markStack;
- };
-
- inline HeapRootMarker::HeapRootMarker(MarkStack& markStack)
- : m_markStack(markStack)
- {
- }
-
- inline void HeapRootMarker::mark(JSValue* slot)
- {
- m_markStack.append(slot);
- }
-
- inline void HeapRootMarker::mark(JSValue* slot, size_t count)
- {
- m_markStack.append(slot, count);
- }
-
- inline void HeapRootMarker::mark(JSString** slot)
- {
- m_markStack.append(reinterpret_cast<JSCell**>(slot));
- }
-
- inline void HeapRootMarker::mark(JSCell** slot)
- {
- m_markStack.append(slot);
- }
-
-} // namespace JSC
-
-#endif
diff --git a/Source/JavaScriptCore/runtime/MarkStackPosix.cpp b/Source/JavaScriptCore/runtime/MarkStackPosix.cpp
deleted file mode 100644
index 2a5b298..0000000
--- a/Source/JavaScriptCore/runtime/MarkStackPosix.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-#include "MarkStack.h"
-
-#if OS(UNIX) && !OS(SYMBIAN)
-
-#include <unistd.h>
-#include <sys/mman.h>
-
-namespace JSC {
-
-void MarkStack::initializePagesize()
-{
- MarkStack::s_pageSize = getpagesize();
-}
-
-}
-
-#endif
diff --git a/Source/JavaScriptCore/runtime/MarkStackSymbian.cpp b/Source/JavaScriptCore/runtime/MarkStackSymbian.cpp
deleted file mode 100644
index a3893d7..0000000
--- a/Source/JavaScriptCore/runtime/MarkStackSymbian.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-#include "MarkStack.h"
-
-#if OS(SYMBIAN)
-
-#include <e32hal.h>
-
-namespace JSC {
-
-void MarkStack::initializePagesize()
-{
- TInt page_size;
- UserHal::PageSizeInBytes(page_size);
- MarkStack::s_pageSize = page_size;
-}
-
-}
-
-#endif
diff --git a/Source/JavaScriptCore/runtime/MarkStackWin.cpp b/Source/JavaScriptCore/runtime/MarkStackWin.cpp
deleted file mode 100644
index 2d2a1b3..0000000
--- a/Source/JavaScriptCore/runtime/MarkStackWin.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-#include "MarkStack.h"
-
-#if OS(WINDOWS)
-
-#include "windows.h"
-
-namespace JSC {
-
-void MarkStack::initializePagesize()
-{
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- MarkStack::s_pageSize = system_info.dwPageSize;
-}
-
-}
-
-#endif
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.cpp b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
deleted file mode 100644
index cae701f..0000000
--- a/Source/JavaScriptCore/runtime/MarkedBlock.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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"
-#include "JSObject.h"
-#include "JSZombie.h"
-#include "ScopeChain.h"
-
-namespace JSC {
-
-MarkedBlock* MarkedBlock::create(JSGlobalData* globalData, size_t cellSize)
-{
- PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockSize, OSAllocator::JSGCHeapPages);
- if (!static_cast<bool>(allocation))
- CRASH();
- return new (allocation.base()) MarkedBlock(allocation, globalData, cellSize);
-}
-
-void MarkedBlock::destroy(MarkedBlock* block)
-{
- for (size_t i = block->firstAtom(); i < block->m_endAtom; i += block->m_atomsPerCell)
- reinterpret_cast<JSCell*>(&block->atoms()[i])->~JSCell();
- block->m_allocation.deallocate();
-}
-
-MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData* globalData, size_t cellSize)
- : m_nextAtom(firstAtom())
- , m_allocation(allocation)
- , m_heap(&globalData->heap)
- , m_prev(0)
- , m_next(0)
-{
- m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
- m_endAtom = atomsPerBlock - m_atomsPerCell + 1;
-
- Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get();
- for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell)
- new (&atoms()[i]) JSCell(dummyMarkableCellStructure);
-}
-
-void MarkedBlock::sweep()
-{
-#if !ENABLE(JSC_ZOMBIES)
- Structure* dummyMarkableCellStructure = m_heap->globalData()->dummyMarkableCellStructure.get();
-#endif
-
- for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
- if (m_marks.get(i))
- continue;
-
- JSCell* cell = reinterpret_cast<JSCell*>(&atoms()[i]);
-#if ENABLE(JSC_ZOMBIES)
- if (!cell->isZombie()) {
- const ClassInfo* info = cell->classInfo();
- cell->~JSCell();
- new (cell) JSZombie(info, JSZombie::leakedZombieStructure());
- m_marks.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
deleted file mode 100644
index 0e2b59c..0000000
--- a/Source/JavaScriptCore/runtime/MarkedBlock.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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/PageAllocationAligned.h>
-#include <wtf/StdLibExtras.h>
-
-namespace JSC {
-
- class Heap;
- class JSCell;
- class JSGlobalData;
-
- typedef uintptr_t Bits;
-
- static const size_t KB = 1024;
-
- class MarkedBlock {
- public:
- static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
-
- static MarkedBlock* create(JSGlobalData*, size_t cellSize);
- static void destroy(MarkedBlock*);
-
- static bool isAtomAligned(const void*);
- static MarkedBlock* blockFor(const void*);
- static size_t firstAtom();
-
- Heap* heap() const;
-
- void setPrev(MarkedBlock*);
- void setNext(MarkedBlock*);
- MarkedBlock* prev() const;
- MarkedBlock* next() const;
-
- void* allocate();
- void reset();
- void sweep();
-
- bool isEmpty();
-
- void clearMarks();
- size_t markCount();
-
- size_t cellSize();
-
- size_t size();
- size_t capacity();
-
- bool contains(const void*);
- size_t atomNumber(const void*);
- bool isMarked(const void*);
- bool testAndSetMarked(const void*);
- void setMarked(const void*);
-
- template <typename Functor> void forEach(Functor&);
-
- private:
- static const size_t blockSize = 16 * KB;
- static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
-
- static const size_t atomMask = ~(atomSize - 1); // atomSize must be a power of two.
-
- static const size_t atomsPerBlock = blockSize / atomSize;
-
- typedef char Atom[atomSize];
-
- MarkedBlock(const PageAllocationAligned&, JSGlobalData*, size_t cellSize);
- Atom* atoms();
-
- size_t m_nextAtom;
- size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom.
- size_t m_atomsPerCell;
- WTF::Bitmap<blockSize / atomSize> m_marks;
- PageAllocationAligned m_allocation;
- Heap* m_heap;
- MarkedBlock* m_prev;
- MarkedBlock* m_next;
- };
-
- inline size_t MarkedBlock::firstAtom()
- {
- return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
- }
-
- inline MarkedBlock::Atom* MarkedBlock::atoms()
- {
- return reinterpret_cast<Atom*>(this);
- }
-
- inline bool MarkedBlock::isAtomAligned(const void* p)
- {
- return !((intptr_t)(p) & ~atomMask);
- }
-
- inline MarkedBlock* MarkedBlock::blockFor(const void* p)
- {
- return reinterpret_cast<MarkedBlock*>(reinterpret_cast<uintptr_t>(p) & blockMask);
- }
-
- inline Heap* MarkedBlock::heap() const
- {
- return m_heap;
- }
-
- inline void MarkedBlock::setPrev(MarkedBlock* prev)
- {
- m_prev = prev;
- }
-
- inline void MarkedBlock::setNext(MarkedBlock* next)
- {
- m_next = next;
- }
-
- inline MarkedBlock* MarkedBlock::prev() const
- {
- return m_prev;
- }
-
- inline MarkedBlock* MarkedBlock::next() const
- {
- return m_next;
- }
-
- inline void MarkedBlock::reset()
- {
- m_nextAtom = firstAtom();
- }
-
- inline bool MarkedBlock::isEmpty()
- {
- return m_marks.isEmpty();
- }
-
- inline void MarkedBlock::clearMarks()
- {
- m_marks.clearAll();
- }
-
- inline size_t MarkedBlock::markCount()
- {
- return m_marks.count();
- }
-
- inline size_t MarkedBlock::cellSize()
- {
- return m_atomsPerCell * atomSize;
- }
-
- inline size_t MarkedBlock::size()
- {
- return markCount() * cellSize();
- }
-
- inline size_t MarkedBlock::capacity()
- {
- return m_allocation.size();
- }
-
- inline bool MarkedBlock::contains(const void* p)
- {
- // Since we mark the first atom of every cell when allocating and/or
- // marking, any pointer to a marked atom points to the head of a valid,
- // live cell. Checking the mark bit guards against reviving an object
- // in a zombie state.
-
- ASSERT(p && isAtomAligned(p));
- return isMarked(p);
- }
-
- inline size_t MarkedBlock::atomNumber(const void* p)
- {
- return (reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(this)) / atomSize;
- }
-
- inline bool MarkedBlock::isMarked(const void* p)
- {
- return m_marks.get(atomNumber(p));
- }
-
- inline bool MarkedBlock::testAndSetMarked(const void* p)
- {
- return m_marks.testAndSet(atomNumber(p));
- }
-
- inline void MarkedBlock::setMarked(const void* p)
- {
- m_marks.set(atomNumber(p));
- }
-
- template <typename Functor> inline void MarkedBlock::forEach(Functor& functor)
- {
- for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
- if (!m_marks.get(i))
- continue;
- functor(reinterpret_cast<JSCell*>(&atoms()[i]));
- }
- }
-
-} // namespace JSC
-
-#endif // MarkedSpace_h
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.cpp b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
deleted file mode 100644
index d9a1e42..0000000
--- a/Source/JavaScriptCore/runtime/MarkedSpace.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * 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
- *
- */
-
-#include "config.h"
-#include "MarkedSpace.h"
-
-#include "JSCell.h"
-#include "JSGlobalData.h"
-#include "JSLock.h"
-#include "JSObject.h"
-#include "ScopeChain.h"
-
-namespace JSC {
-
-class Structure;
-
-MarkedSpace::MarkedSpace(JSGlobalData* globalData)
- : m_waterMark(0)
- , m_highWaterMark(0)
- , m_globalData(globalData)
-{
- for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
- sizeClassFor(cellSize).cellSize = cellSize;
-
- for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
- sizeClassFor(cellSize).cellSize = cellSize;
-}
-
-void MarkedSpace::destroy()
-{
- clearMarks();
- shrink();
- ASSERT(!size());
-}
-
-MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass)
-{
- MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize);
- sizeClass.blockList.append(block);
- sizeClass.nextBlock = block;
- m_blocks.add(block);
-
- return block;
-}
-
-void MarkedSpace::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
-{
- MarkedBlock* next;
- for (MarkedBlock* block = blocks.head(); block; block = next) {
- next = block->next();
-
- blocks.remove(block);
- m_blocks.remove(block);
- MarkedBlock::destroy(block);
- }
-}
-
-void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass)
-{
- for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
- if (void* result = block->allocate())
- return result;
-
- m_waterMark += block->capacity();
- }
-
- if (m_waterMark < m_highWaterMark)
- return allocateBlock(sizeClass)->allocate();
-
- return 0;
-}
-
-void MarkedSpace::shrink()
-{
- // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
- DoublyLinkedList<MarkedBlock> empties;
-
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
- MarkedBlock* block = *it;
- if (block->isEmpty()) {
- SizeClass& sizeClass = sizeClassFor(block->cellSize());
- sizeClass.blockList.remove(block);
- sizeClass.nextBlock = sizeClass.blockList.head();
- empties.append(block);
- }
- }
-
- freeBlocks(empties);
- ASSERT(empties.isEmpty());
-}
-
-void MarkedSpace::clearMarks()
-{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->clearMarks();
-}
-
-void MarkedSpace::sweep()
-{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->sweep();
-}
-
-size_t MarkedSpace::objectCount() const
-{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->markCount();
- return result;
-}
-
-size_t MarkedSpace::size() const
-{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->size();
- return result;
-}
-
-size_t MarkedSpace::capacity() const
-{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->capacity();
- return result;
-}
-
-void MarkedSpace::reset()
-{
- m_waterMark = 0;
-
- for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
- sizeClassFor(cellSize).reset();
-
- for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
- sizeClassFor(cellSize).reset();
-
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->reset();
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.h b/Source/JavaScriptCore/runtime/MarkedSpace.h
deleted file mode 100644
index 29a8cd0..0000000
--- a/Source/JavaScriptCore/runtime/MarkedSpace.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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 MarkedSpace_h
-#define MarkedSpace_h
-
-#include "MachineStackMarker.h"
-#include "MarkedBlock.h"
-#include "PageAllocationAligned.h"
-#include <wtf/Bitmap.h>
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/FixedArray.h>
-#include <wtf/HashSet.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Vector.h>
-
-#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) < MarkedSpace::maxCellSize, class_fits_in_cell)
-
-namespace JSC {
-
- class Heap;
- class JSCell;
- class JSGlobalData;
- class LiveObjectIterator;
- class MarkStack;
- class WeakGCHandle;
-
- class MarkedSpace {
- WTF_MAKE_NONCOPYABLE(MarkedSpace);
- public:
- // Currently public for use in assertions.
- static const size_t maxCellSize = 1024;
-
- static Heap* heap(JSCell*);
-
- static bool isMarked(const JSCell*);
- static bool testAndSetMarked(const JSCell*);
- static void setMarked(const JSCell*);
-
- MarkedSpace(JSGlobalData*);
- void destroy();
-
- JSGlobalData* globalData() { return m_globalData; }
-
- 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();
-
- size_t size() const;
- size_t capacity() const;
- size_t objectCount() const;
-
- bool contains(const void*);
-
- template<typename Functor> void forEach(Functor&);
-
- private:
- // [ 8, 16... 128 )
- static const size_t preciseStep = MarkedBlock::atomSize;
- static const size_t preciseCutoff = 128;
- static const size_t preciseCount = preciseCutoff / preciseStep - 1;
-
- // [ 128, 256... 1024 )
- static const size_t impreciseStep = preciseCutoff;
- static const size_t impreciseCutoff = maxCellSize;
- static const size_t impreciseCount = impreciseCutoff / impreciseStep - 1;
-
- typedef HashSet<MarkedBlock*>::iterator BlockIterator;
-
- struct SizeClass {
- SizeClass();
- void reset();
-
- MarkedBlock* nextBlock;
- DoublyLinkedList<MarkedBlock> blockList;
- size_t cellSize;
- };
-
- MarkedBlock* allocateBlock(SizeClass&);
- void freeBlocks(DoublyLinkedList<MarkedBlock>&);
-
- SizeClass& sizeClassFor(size_t);
- void* allocateFromSizeClass(SizeClass&);
-
- void clearMarks(MarkedBlock*);
-
- SizeClass m_preciseSizeClasses[preciseCount];
- SizeClass m_impreciseSizeClasses[impreciseCount];
- HashSet<MarkedBlock*> m_blocks;
- size_t m_waterMark;
- size_t m_highWaterMark;
- JSGlobalData* m_globalData;
- };
-
- inline Heap* MarkedSpace::heap(JSCell* cell)
- {
- return MarkedBlock::blockFor(cell)->heap();
- }
-
- inline bool MarkedSpace::isMarked(const JSCell* cell)
- {
- return MarkedBlock::blockFor(cell)->isMarked(cell);
- }
-
- inline bool MarkedSpace::testAndSetMarked(const JSCell* cell)
- {
- return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
- }
-
- inline void MarkedSpace::setMarked(const JSCell* cell)
- {
- MarkedBlock::blockFor(cell)->setMarked(cell);
- }
-
- inline bool MarkedSpace::contains(const void* x)
- {
- if (!MarkedBlock::isAtomAligned(x))
- return false;
-
- MarkedBlock* block = MarkedBlock::blockFor(x);
- if (!block || !m_blocks.contains(block))
- return false;
-
- return block->contains(x);
- }
-
- template <typename Functor> inline void MarkedSpace::forEach(Functor& functor)
- {
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->forEach(functor);
- }
-
- inline MarkedSpace::SizeClass::SizeClass()
- : nextBlock(0)
- , cellSize(0)
- {
- }
-
- inline void MarkedSpace::SizeClass::reset()
- {
- nextBlock = blockList.head();
- }
-
-} // namespace JSC
-
-#endif // MarkedSpace_h
diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp
index 7b856a1..52bd76a 100644
--- a/Source/JavaScriptCore/runtime/MathObject.cpp
+++ b/Source/JavaScriptCore/runtime/MathObject.cpp
@@ -86,7 +86,7 @@ const ClassInfo MathObject::s_info = { "Math", &JSObjectWithGlobalObject::s_info
@end
*/
-MathObject::MathObject(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
+MathObject::MathObject(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: JSObjectWithGlobalObject(globalObject, structure)
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/MathObject.h b/Source/JavaScriptCore/runtime/MathObject.h
index 26eaae0..75753be 100644
--- a/Source/JavaScriptCore/runtime/MathObject.h
+++ b/Source/JavaScriptCore/runtime/MathObject.h
@@ -27,14 +27,14 @@ namespace JSC {
class MathObject : public JSObjectWithGlobalObject {
public:
- MathObject(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ MathObject(ExecState*, JSGlobalObject*, Structure*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index d8fda69..9cd5dcb 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -32,7 +32,7 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, 0 };
-NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString& nameAndMessage)
+NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const UString& nameAndMessage)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, nameAndMessage))
{
ASSERT(inherits(&s_info));
@@ -41,13 +41,23 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject*
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(exec->globalData(), prototype);
+ m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), prototype));
+ ASSERT(m_errorStructure);
+ ASSERT(m_errorStructure->typeInfo().type() == ObjectType);
+}
+
+void NativeErrorConstructor::markChildren(MarkStack& markStack)
+{
+ InternalFunction::markChildren(markStack);
+ if (m_errorStructure)
+ markStack.append(&m_errorStructure);
}
static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState* exec)
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure();
+ ASSERT(errorStructure);
return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
index 23f798e..e96daf6 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -31,11 +31,11 @@ namespace JSC {
class NativeErrorConstructor : public InternalFunction {
public:
- NativeErrorConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString&);
+ NativeErrorConstructor(ExecState*, JSGlobalObject*, Structure*, Structure* prototypeStructure, const UString&);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
@@ -43,10 +43,12 @@ namespace JSC {
Structure* errorStructure() { return m_errorStructure.get(); }
private:
+ static const unsigned StructureFlags = OverridesMarkChildren | InternalFunction::StructureFlags;
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
+ virtual void markChildren(MarkStack&);
- RefPtr<Structure> m_errorStructure;
+ WriteBarrier<Structure> m_errorStructure;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 4e10268..de27d59 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -31,7 +31,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
-NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& nameAndMessage, NativeErrorConstructor* constructor)
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& nameAndMessage, NativeErrorConstructor* constructor)
: JSObjectWithGlobalObject(globalObject, structure)
{
putDirect(exec->globalData(), exec->propertyNames().name, jsString(exec, nameAndMessage), 0);
diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.h b/Source/JavaScriptCore/runtime/NativeErrorPrototype.h
index 30690d5..e1b05ce 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.h
+++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.h
@@ -28,7 +28,7 @@ namespace JSC {
class NativeErrorPrototype : public JSObjectWithGlobalObject {
public:
- NativeErrorPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, const UString&, NativeErrorConstructor*);
+ NativeErrorPrototype(ExecState*, JSGlobalObject*, Structure*, const UString&, NativeErrorConstructor*);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index aee143a..4193f79 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -54,7 +54,7 @@ const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_i
@end
*/
-NumberConstructor::NumberConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NumberPrototype* numberPrototype)
+NumberConstructor::NumberConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, NumberPrototype* numberPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, numberPrototype->s_info.className))
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.h b/Source/JavaScriptCore/runtime/NumberConstructor.h
index ab4507e..69aa8a1 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.h
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class NumberConstructor : public InternalFunction {
public:
- NumberConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, NumberPrototype*);
+ NumberConstructor(ExecState*, JSGlobalObject*, Structure*, NumberPrototype*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
@@ -37,7 +37,7 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto)
{
return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index 74b5e98..6ee103b 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::s_info = { "Number", &JSWrapperObject::s_info, 0, 0 };
-NumberObject::NumberObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+NumberObject::NumberObject(JSGlobalData& globalData, Structure* structure)
+ : JSWrapperObject(globalData, structure)
{
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index 90d0b26..cba65dd 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -27,11 +27,11 @@ namespace JSC {
class NumberObject : public JSWrapperObject {
public:
- explicit NumberObject(JSGlobalData&, NonNullPassRefPtr<Structure>);
+ explicit NumberObject(JSGlobalData&, Structure*);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index 6c027b3..24532dd 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -45,7 +45,7 @@ static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);
// ECMA 15.7.4
-NumberPrototype::NumberPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
+NumberPrototype::NumberPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure)
: NumberObject(exec->globalData(), structure)
{
setInternalValue(exec->globalData(), jsNumber(0));
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.h b/Source/JavaScriptCore/runtime/NumberPrototype.h
index 191ab47..45bdfe7 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.h
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class NumberPrototype : public NumberObject {
public:
- NumberPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure);
+ NumberPrototype(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index c642a5b..aed5e24 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -75,7 +75,7 @@ const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_i
@end
*/
-ObjectConstructor::ObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ObjectPrototype* objectPrototype)
+ObjectConstructor::ObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, ObjectPrototype* objectPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, "Object"))
{
// ECMA 15.2.3.1
@@ -342,7 +342,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
if (!exec->argument(0).isObject() && !exec->argument(0).isNull())
return throwVMError(exec, createTypeError(exec, "Object prototype may only be an Object or null."));
JSObject* newObject = constructEmptyObject(exec);
- newObject->setPrototype(exec->argument(0));
+ newObject->setPrototype(exec->globalData(), exec->argument(0));
if (exec->argument(1).isUndefined())
return JSValue::encode(newObject);
if (!exec->argument(1).isObject())
@@ -355,7 +355,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.seal can only be called on Objects."));
- asObject(obj)->seal();
+ asObject(obj)->seal(exec->globalData());
return JSValue::encode(obj);
}
@@ -364,7 +364,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.freeze can only be called on Objects."));
- asObject(obj)->freeze();
+ asObject(obj)->freeze(exec->globalData());
return JSValue::encode(obj);
}
@@ -373,7 +373,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.preventExtensions can only be called on Objects."));
- asObject(obj)->preventExtensions();
+ asObject(obj)->preventExtensions(exec->globalData());
return JSValue::encode(obj);
}
@@ -382,7 +382,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.isSealed can only be called on Objects."));
- return JSValue::encode(jsBoolean(asObject(obj)->isSealed()));
+ return JSValue::encode(jsBoolean(asObject(obj)->isSealed(exec->globalData())));
}
EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
@@ -390,7 +390,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.isFrozen can only be called on Objects."));
- return JSValue::encode(jsBoolean(asObject(obj)->isFrozen()));
+ return JSValue::encode(jsBoolean(asObject(obj)->isFrozen(exec->globalData())));
}
EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.h b/Source/JavaScriptCore/runtime/ObjectConstructor.h
index b7bfc1d..6ebafcd 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.h
@@ -29,14 +29,14 @@ namespace JSC {
class ObjectConstructor : public InternalFunction {
public:
- ObjectConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ObjectPrototype*);
+ ObjectConstructor(ExecState*, JSGlobalObject*, Structure*, ObjectPrototype*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
index 187456f..7469172 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -40,8 +40,8 @@ static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
-ObjectPrototype::ObjectPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> stucture, Structure* functionStructure)
- : JSNonFinalObject(stucture)
+ObjectPrototype::ObjectPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* stucture, Structure* functionStructure)
+ : JSNonFinalObject(exec->globalData(), stucture)
, m_hasNoPropertiesWithUInt32Names(true)
{
putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.h b/Source/JavaScriptCore/runtime/ObjectPrototype.h
index 61c8f57..9fb7fae 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class ObjectPrototype : public JSNonFinalObject {
public:
- ObjectPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure);
+ ObjectPrototype(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure);
private:
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 181f912..c102eeb 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -24,9 +24,8 @@
#include "ExceptionHelpers.h"
#include "Interpreter.h"
-#include "JSImmediate.h"
-#include "JSNumberCell.h"
#include "JSString.h"
+#include "JSValueInlineMethods.h"
namespace JSC {
@@ -431,7 +430,7 @@ namespace JSC {
if (cell->structure()->isDictionary()) {
asObject(cell)->flattenDictionaryObject(callFrame->globalData());
if (slotBase == cell)
- slotOffset = cell->structure()->get(propertyName);
+ slotOffset = cell->structure()->get(callFrame->globalData(), propertyName);
}
++count;
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index c000dc8..fc195cd 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -22,6 +22,7 @@
#define PropertyMapHashTable_h
#include "UString.h"
+#include "WriteBarrier.h"
#include <wtf/HashTable.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
@@ -73,13 +74,13 @@ struct PropertyMapEntry {
StringImpl* key;
unsigned offset;
unsigned attributes;
- JSCell* specificValue;
+ WriteBarrier<JSCell> specificValue;
- PropertyMapEntry(StringImpl* key, unsigned offset, unsigned attributes, JSCell* specificValue)
+ PropertyMapEntry(JSGlobalData& globalData, JSCell* owner, StringImpl* key, unsigned offset, unsigned attributes, JSCell* specificValue)
: key(key)
, offset(offset)
, attributes(attributes)
- , specificValue(specificValue)
+ , specificValue(globalData, owner, specificValue)
{
}
};
@@ -141,9 +142,9 @@ public:
typedef std::pair<ValueType*, unsigned> find_iterator;
// Constructor is passed an initial capacity, a PropertyTable to copy, or both.
- PropertyTable(unsigned initialCapacity);
- PropertyTable(const PropertyTable&);
- PropertyTable(unsigned initialCapacity, const PropertyTable&);
+ explicit PropertyTable(unsigned initialCapacity);
+ PropertyTable(JSGlobalData&, JSCell*, const PropertyTable&);
+ PropertyTable(JSGlobalData&, JSCell*, unsigned initialCapacity, const PropertyTable&);
~PropertyTable();
// Ordered iteration methods.
@@ -176,7 +177,7 @@ public:
void addDeletedOffset(unsigned offset);
// Copy this PropertyTable, ensuring the copy has at least the capacity provided.
- PassOwnPtr<PropertyTable> copy(unsigned newCapacity);
+ PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
#ifndef NDEBUG
size_t sizeInMemory();
@@ -184,6 +185,7 @@ public:
#endif
private:
+ PropertyTable(const PropertyTable&);
// Used to insert a value known not to be in the table, and where we know capacity to be available.
void reinsert(const ValueType& entry);
@@ -243,7 +245,7 @@ inline PropertyTable::PropertyTable(unsigned initialCapacity)
ASSERT(isPowerOf2(m_indexSize));
}
-inline PropertyTable::PropertyTable(const PropertyTable& other)
+inline PropertyTable::PropertyTable(JSGlobalData& globalData, JSCell* owner, const PropertyTable& other)
: m_indexSize(other.m_indexSize)
, m_indexMask(other.m_indexMask)
, m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
@@ -255,8 +257,10 @@ inline PropertyTable::PropertyTable(const PropertyTable& other)
memcpy(m_index, other.m_index, dataSize());
iterator end = this->end();
- for (iterator iter = begin(); iter != end; ++iter)
+ for (iterator iter = begin(); iter != end; ++iter) {
iter->key->ref();
+ writeBarrier(globalData, owner, iter->specificValue.get());
+ }
// Copy the m_deletedOffsets vector.
Vector<unsigned>* otherDeletedOffsets = other.m_deletedOffsets.get();
@@ -264,7 +268,7 @@ inline PropertyTable::PropertyTable(const PropertyTable& other)
m_deletedOffsets.set(new Vector<unsigned>(*otherDeletedOffsets));
}
-inline PropertyTable::PropertyTable(unsigned initialCapacity, const PropertyTable& other)
+inline PropertyTable::PropertyTable(JSGlobalData& globalData, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
: m_indexSize(sizeForCapacity(initialCapacity))
, m_indexMask(m_indexSize - 1)
, m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
@@ -279,6 +283,7 @@ inline PropertyTable::PropertyTable(unsigned initialCapacity, const PropertyTabl
ASSERT(canInsert());
reinsert(*iter);
iter->key->ref();
+ writeBarrier(globalData, owner, iter->specificValue.get());
}
// Copy the m_deletedOffsets vector.
@@ -443,15 +448,15 @@ inline void PropertyTable::addDeletedOffset(unsigned offset)
m_deletedOffsets->append(offset);
}
-inline PassOwnPtr<PropertyTable> PropertyTable::copy(unsigned newCapacity)
+inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
{
ASSERT(newCapacity >= m_keyCount);
// Fast case; if the new table will be the same m_indexSize as this one, we can memcpy it,
// save rehashing all keys.
if (sizeForCapacity(newCapacity) == m_indexSize)
- return new PropertyTable(*this);
- return new PropertyTable(newCapacity, *this);
+ return new PropertyTable(globalData, owner, *this);
+ return new PropertyTable(globalData, owner, newCapacity, *this);
}
#ifndef NDEBUG
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index 19b4b36..3da0198 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -95,7 +95,7 @@ const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_i
@end
*/
-RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
+RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, RegExpPrototype* regExpPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, "RegExp"))
, d(adoptPtr(new RegExpConstructorPrivate))
{
@@ -109,7 +109,7 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObje
}
RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
- : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1, CreateInitialized)
+ : JSArray(exec->globalData(), exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1, CreateInitialized)
{
RegExpConstructorPrivate* d = new RegExpConstructorPrivate;
d->input = data->lastInput;
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h
index 5e0b2b8..548664e 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h
@@ -57,9 +57,9 @@ namespace JSC {
class RegExpConstructor : public InternalFunction {
public:
- RegExpConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, RegExpPrototype*);
+ RegExpConstructor(ExecState*, JSGlobalObject*, Structure*, RegExpPrototype*);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 4b5028b..d824ecd 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -61,7 +61,7 @@ const ClassInfo RegExpObject::s_info = { "RegExp", &JSObjectWithGlobalObject::s_
@end
*/
-RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp)
+RegExpObject::RegExpObject(JSGlobalObject* globalObject, Structure* structure, NonNullPassRefPtr<RegExp> regExp)
: JSObjectWithGlobalObject(globalObject, structure)
, d(adoptPtr(new RegExpObjectData(regExp)))
{
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index fa2024d..4274fff 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -30,7 +30,7 @@ namespace JSC {
public:
typedef JSObjectWithGlobalObject Base;
- RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>);
+ RegExpObject(JSGlobalObject*, Structure*, NonNullPassRefPtr<RegExp>);
virtual ~RegExpObject();
void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
@@ -58,7 +58,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 61747b1..5bb8ad8 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -47,7 +47,7 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
// ECMA 15.10.5
-RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
+RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure)
: RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", NoFlags))
{
putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.h b/Source/JavaScriptCore/runtime/RegExpPrototype.h
index 70d77d9..2cc5405 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.h
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.h
@@ -28,7 +28,7 @@ namespace JSC {
class RegExpPrototype : public RegExpObject {
public:
- RegExpPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure);
+ RegExpPrototype(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.cpp b/Source/JavaScriptCore/runtime/ScopeChain.cpp
index 4615f9a..026d729 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.cpp
+++ b/Source/JavaScriptCore/runtime/ScopeChain.cpp
@@ -51,6 +51,8 @@ void ScopeChainNode::print()
#endif
+const ClassInfo ScopeChainNode::s_info = { "ScopeChainNode", 0, 0, 0 };
+
int ScopeChainNode::localDepth()
{
int scopeDepth = 0;
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.h b/Source/JavaScriptCore/runtime/ScopeChain.h
index cb70a34..d0a2672 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.h
+++ b/Source/JavaScriptCore/runtime/ScopeChain.h
@@ -22,6 +22,7 @@
#define ScopeChain_h
#include "JSCell.h"
+#include "Structure.h"
#include <wtf/FastAllocBase.h>
namespace JSC {
@@ -35,7 +36,7 @@ namespace JSC {
class ScopeChainNode : public JSCell {
public:
ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
- : JSCell(globalData->scopeChainNodeStructure.get())
+ : JSCell(*globalData, globalData->scopeChainNodeStructure.get())
, globalData(globalData)
, next(*globalData, this, next)
, object(*globalData, this, object)
@@ -64,10 +65,11 @@ namespace JSC {
void print();
#endif
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, &s_info); }
virtual void markChildren(MarkStack&);
private:
static const unsigned StructureFlags = OverridesMarkChildren;
+ static const ClassInfo s_info;
};
inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
diff --git a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
index 24c501e..e666dee 100644
--- a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
+++ b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
@@ -29,7 +29,7 @@
namespace JSC {
StrictEvalActivation::StrictEvalActivation(ExecState* exec)
- : JSNonFinalObject(exec->globalData().strictEvalActivationStructure)
+ : JSNonFinalObject(exec->globalData(), exec->globalData().strictEvalActivationStructure.get())
{
}
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index ed088e4..560202a 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -48,7 +48,7 @@ static EncodedJSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec)
ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
-StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure, StringPrototype* stringPrototype)
+StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* functionStructure, StringPrototype* stringPrototype)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, stringPrototype->classInfo()->className))
{
// ECMA 15.5.3.1 String.prototype
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.h b/Source/JavaScriptCore/runtime/StringConstructor.h
index 3a42c7e..117cce8 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.h
+++ b/Source/JavaScriptCore/runtime/StringConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class StringConstructor : public InternalFunction {
public:
- StringConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* functionStructure, StringPrototype*);
+ StringConstructor(ExecState*, JSGlobalObject*, Structure*, Structure* functionStructure, StringPrototype*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index 47e5860..67dc291 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -29,22 +29,22 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0 };
-StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(structure)
+StringObject::StringObject(ExecState* exec, Structure* structure)
+ : JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsEmptyString(exec));
}
-StringObject::StringObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, JSString* string)
- : JSWrapperObject(structure)
+StringObject::StringObject(JSGlobalData& globalData, Structure* structure, JSString* string)
+ : JSWrapperObject(globalData, structure)
{
ASSERT(inherits(&s_info));
setInternalValue(globalData, string);
}
-StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
- : JSWrapperObject(structure)
+StringObject::StringObject(ExecState* exec, Structure* structure, const UString& string)
+ : JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsString(exec, string));
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index ae3376d..4c16044 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -28,8 +28,8 @@ namespace JSC {
class StringObject : public JSWrapperObject {
public:
- StringObject(ExecState*, NonNullPassRefPtr<Structure>);
- StringObject(ExecState*, NonNullPassRefPtr<Structure>, const UString&);
+ StringObject(ExecState*, Structure*);
+ StringObject(ExecState*, Structure*, const UString&);
static StringObject* create(ExecState*, JSGlobalObject*, JSString*);
@@ -45,14 +45,14 @@ namespace JSC {
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
- StringObject(JSGlobalData&, NonNullPassRefPtr<Structure>, JSString*);
+ StringObject(JSGlobalData&, Structure*, JSString*);
};
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index e4c7061..3133944 100644
--- a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -37,12 +37,12 @@ namespace JSC {
}
private:
- StringObjectThatMasqueradesAsUndefined(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
+ StringObjectThatMasqueradesAsUndefined(ExecState* exec, Structure* structure, const UString& string)
: StringObject(exec, structure, string)
{
}
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue proto)
{
return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index a6bf4e6..91112a5 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -131,7 +131,7 @@ const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0,
*/
// ECMA 15.5.4
-StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure)
+StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: StringObject(exec, structure)
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.h b/Source/JavaScriptCore/runtime/StringPrototype.h
index 57def22..6c4b475 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.h
+++ b/Source/JavaScriptCore/runtime/StringPrototype.h
@@ -29,12 +29,12 @@ namespace JSC {
class StringPrototype : public StringObject {
public:
- StringPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
+ StringPrototype(ExecState*, JSGlobalObject*, Structure*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
{
return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 829e3db..dcc8e7c 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -61,21 +61,6 @@ int numRemoves;
namespace JSC {
-#ifndef NDEBUG
-static WTF::RefCountedLeakCounter structureCounter("Structure");
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-static Mutex& ignoreSetMutex()
-{
- DEFINE_STATIC_LOCAL(Mutex, mutex, ());
- return mutex;
-}
-#endif
-
-static bool shouldIgnoreLeaks;
-static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
-#endif
-
#if DUMP_STRUCTURE_ID_STATISTICS
static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
#endif
@@ -106,41 +91,41 @@ inline void StructureTransitionTable::remove(Structure* structure)
// map mode).
// As such, the passed structure *must* be the existing transition.
ASSERT(singleTransition() == structure);
- setSingleTransition(0);
+ clearSingleTransition();
} else {
// Check whether a mapping exists for structure's key, and whether the
// entry is structure (the latter check may fail if we initially had a
// transition with a specific value, and this has been despecified).
TransitionMap::iterator entry = map()->find(make_pair(structure->m_nameInPrevious, structure->m_attributesInPrevious));
- if (entry != map()->end() && structure == entry->second)
+ if (entry != map()->end() && structure == entry.get().second)
map()->remove(entry);
}
}
-inline void StructureTransitionTable::add(Structure* structure)
+inline void StructureTransitionTable::add(JSGlobalData& globalData, Structure* structure)
{
if (isUsingSingleSlot()) {
Structure* existingTransition = singleTransition();
// This handles the first transition being added.
if (!existingTransition) {
- setSingleTransition(structure);
+ setSingleTransition(globalData, structure);
return;
}
// This handles the second transition being added
// (or the first transition being despecified!)
setMap(new TransitionMap());
- add(existingTransition);
+ add(globalData, existingTransition);
}
// Add the structure to the map.
- std::pair<TransitionMap::iterator, bool> result = map()->add(make_pair(structure->m_nameInPrevious, structure->m_attributesInPrevious), structure);
+ std::pair<TransitionMap::iterator, bool> result = map()->add(globalData, make_pair(structure->m_nameInPrevious, structure->m_attributesInPrevious), structure);
if (!result.second) {
// There already is an entry! - we should only hit this when despecifying.
- ASSERT(result.first->second->m_specificValueInPrevious);
+ ASSERT(result.first.get().second->m_specificValueInPrevious);
ASSERT(!structure->m_specificValueInPrevious);
- result.first->second = structure;
+ map()->set(result.first, structure);
}
}
@@ -189,10 +174,10 @@ void Structure::dumpStatistics()
#endif
}
-Structure::Structure(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
- : m_typeInfo(typeInfo)
- , m_prototype(prototype)
- , m_specificValueInPrevious(0)
+Structure::Structure(JSGlobalData& globalData, JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
+ : JSCell(globalData, globalData.structureStructure.get())
+ , m_typeInfo(typeInfo)
+ , m_prototype(globalData, this, prototype)
, m_classInfo(classInfo)
, m_propertyStorageCapacity(typeInfo.isFinal() ? JSFinalObject_inlineStorageCapacity : JSNonFinalObject_inlineStorageCapacity)
, m_offset(noOffset)
@@ -206,27 +191,36 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo, unsigned anony
, m_preventExtensions(false)
{
ASSERT(m_prototype);
- ASSERT(m_prototype->isObject() || m_prototype->isNull());
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
+}
-#ifndef NDEBUG
-#if ENABLE(JSC_MULTIPLE_THREADS)
- MutexLocker protect(ignoreSetMutex());
-#endif
- if (shouldIgnoreLeaks)
- ignoreSet.add(this);
- else
- structureCounter.increment();
-#endif
+const ClassInfo Structure::s_info = { "Structure", 0, 0, 0 };
-#if DUMP_STRUCTURE_ID_STATISTICS
- liveStructureSet.add(this);
-#endif
+Structure::Structure(JSGlobalData& globalData)
+ : JSCell(globalData, this)
+ , m_typeInfo(CompoundType, OverridesMarkChildren)
+ , m_prototype(globalData, this, jsNull())
+ , m_classInfo(&s_info)
+ , m_propertyStorageCapacity(0)
+ , m_offset(noOffset)
+ , m_dictionaryKind(NoneDictionaryKind)
+ , m_isPinnedPropertyTable(false)
+ , m_hasGetterSetterProperties(false)
+ , m_hasNonEnumerableProperties(false)
+ , m_attributesInPrevious(0)
+ , m_specificFunctionThrashCount(0)
+ , m_anonymousSlotCount(0)
+ , m_preventExtensions(false)
+{
+ ASSERT(m_prototype);
+ ASSERT(m_prototype.isNull());
+ ASSERT(!globalData.structureStructure);
}
-Structure::Structure(const Structure* previous)
- : m_typeInfo(previous->typeInfo())
- , m_prototype(previous->storedPrototype())
- , m_specificValueInPrevious(0)
+Structure::Structure(JSGlobalData& globalData, const Structure* previous)
+ : JSCell(globalData, globalData.structureStructure.get())
+ , m_typeInfo(previous->typeInfo())
+ , m_prototype(globalData, this, previous->storedPrototype())
, m_classInfo(previous->m_classInfo)
, m_propertyStorageCapacity(previous->m_propertyStorageCapacity)
, m_offset(noOffset)
@@ -240,61 +234,14 @@ Structure::Structure(const Structure* previous)
, m_preventExtensions(previous->m_preventExtensions)
{
ASSERT(m_prototype);
- ASSERT(m_prototype->isObject() || m_prototype->isNull());
-
-#ifndef NDEBUG
-#if ENABLE(JSC_MULTIPLE_THREADS)
- MutexLocker protect(ignoreSetMutex());
-#endif
- if (shouldIgnoreLeaks)
- ignoreSet.add(this);
- else
- structureCounter.increment();
-#endif
-
-#if DUMP_STRUCTURE_ID_STATISTICS
- liveStructureSet.add(this);
-#endif
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
}
Structure::~Structure()
{
- if (m_previous) {
- ASSERT(m_nameInPrevious);
- m_previous->m_transitionTable.remove(this);
- }
-
-#ifndef NDEBUG
-#if ENABLE(JSC_MULTIPLE_THREADS)
- MutexLocker protect(ignoreSetMutex());
-#endif
- HashSet<Structure*>::iterator it = ignoreSet.find(this);
- if (it != ignoreSet.end())
- ignoreSet.remove(it);
- else
- structureCounter.decrement();
-#endif
-
-#if DUMP_STRUCTURE_ID_STATISTICS
- liveStructureSet.remove(this);
-#endif
-}
-
-void Structure::startIgnoringLeaks()
-{
-#ifndef NDEBUG
- shouldIgnoreLeaks = true;
-#endif
}
-void Structure::stopIgnoringLeaks()
-{
-#ifndef NDEBUG
- shouldIgnoreLeaks = false;
-#endif
-}
-
-void Structure::materializePropertyMap()
+void Structure::materializePropertyMap(JSGlobalData& globalData)
{
ASSERT(!m_propertyTable);
@@ -309,7 +256,7 @@ void Structure::materializePropertyMap()
ASSERT(structure->m_propertyTable);
ASSERT(!structure->m_previous);
- m_propertyTable = structure->m_propertyTable->copy(m_offset + 1);
+ m_propertyTable = structure->m_propertyTable->copy(globalData, 0, m_offset + 1);
break;
}
@@ -321,7 +268,7 @@ void Structure::materializePropertyMap()
for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
structure = structures[i];
- PropertyMapEntry entry(structure->m_nameInPrevious.get(), m_anonymousSlotCount + structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious);
+ PropertyMapEntry entry(globalData, this, structure->m_nameInPrevious.get(), m_anonymousSlotCount + structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
m_propertyTable->add(entry);
}
}
@@ -334,27 +281,27 @@ void Structure::growPropertyStorageCapacity()
m_propertyStorageCapacity *= 2;
}
-void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
+void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, const Identifier& propertyName)
{
StringImpl* rep = propertyName.impl();
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
ASSERT(isDictionary());
ASSERT(m_propertyTable);
PropertyMapEntry* entry = m_propertyTable->find(rep).first;
ASSERT(entry);
- entry->specificValue = 0;
+ entry->specificValue.clear();
}
-PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+Structure* Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
{
ASSERT(!structure->isDictionary());
ASSERT(structure->typeInfo().type() == ObjectType);
if (Structure* existingTransition = structure->m_transitionTable.get(propertyName.impl(), attributes)) {
- JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious;
+ JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious.get();
if (specificValueInPrevious && specificValueInPrevious != specificValue)
return 0;
ASSERT(existingTransition->m_offset != noOffset);
@@ -367,7 +314,7 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
return 0;
}
-PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
{
// If we have a specific function, we may have got to this point if there is
// already a transition with the correct property name and attributes, but
@@ -387,37 +334,37 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
specificValue = 0;
if (structure->transitionCount() > s_maxTransitionLength) {
- RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
+ Structure* transition = toCacheableDictionaryTransition(globalData, structure);
ASSERT(structure != transition);
- offset = transition->put(propertyName, attributes, specificValue);
+ offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
ASSERT(offset >= structure->m_anonymousSlotCount);
ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
transition->growPropertyStorageCapacity();
- return transition.release();
+ return transition;
}
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
- transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
- transition->m_previous = structure;
+ transition->m_cachedPrototypeChain.set(globalData, transition, structure->m_cachedPrototypeChain.get());
+ transition->m_previous.set(globalData, transition, structure);
transition->m_nameInPrevious = propertyName.impl();
transition->m_attributesInPrevious = attributes;
- transition->m_specificValueInPrevious = specificValue;
+ transition->m_specificValueInPrevious.set(globalData, transition, specificValue);
if (structure->m_propertyTable) {
if (structure->m_isPinnedPropertyTable)
- transition->m_propertyTable = structure->m_propertyTable->copy(structure->m_propertyTable->size() + 1);
+ transition->m_propertyTable = structure->m_propertyTable->copy(globalData, 0, structure->m_propertyTable->size() + 1);
else
transition->m_propertyTable = structure->m_propertyTable.release();
} else {
if (structure->m_previous)
- transition->materializePropertyMap();
+ transition->materializePropertyMap(globalData);
else
transition->createPropertyMap();
}
- offset = transition->put(propertyName, attributes, specificValue);
+ offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
ASSERT(offset >= structure->m_anonymousSlotCount);
ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
@@ -425,106 +372,106 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
transition->m_offset = offset - structure->m_anonymousSlotCount;
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- structure->m_transitionTable.add(transition.get());
- return transition.release();
+ structure->m_transitionTable.add(globalData, transition);
+ return transition;
}
-PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
+Structure* Structure::removePropertyTransition(JSGlobalData& globalData, Structure* structure, const Identifier& propertyName, size_t& offset)
{
ASSERT(!structure->isUncacheableDictionary());
- RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure);
+ Structure* transition = toUncacheableDictionaryTransition(globalData, structure);
offset = transition->remove(propertyName);
ASSERT(offset >= structure->m_anonymousSlotCount);
ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount);
- return transition.release();
+ return transition;
}
-PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValue prototype)
+Structure* Structure::changePrototypeTransition(JSGlobalData& globalData, Structure* structure, JSValue prototype)
{
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
- transition->m_prototype = prototype;
+ transition->m_prototype.set(globalData, transition, prototype);
// Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary();
- transition->m_propertyTable = structure->copyPropertyTable();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTable(globalData, transition);
transition->m_isPinnedPropertyTable = true;
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- return transition.release();
+ return transition;
}
-PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
+Structure* Structure::despecifyFunctionTransition(JSGlobalData& globalData, Structure* structure, const Identifier& replaceFunction)
{
ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
++transition->m_specificFunctionThrashCount;
// Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary();
- transition->m_propertyTable = structure->copyPropertyTable();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTable(globalData, transition);
transition->m_isPinnedPropertyTable = true;
if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
- transition->despecifyAllFunctions();
+ transition->despecifyAllFunctions(globalData);
else {
- bool removed = transition->despecifyFunction(replaceFunction);
+ bool removed = transition->despecifyFunction(globalData, replaceFunction);
ASSERT_UNUSED(removed, removed);
}
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- return transition.release();
+ return transition;
}
-PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
+Structure* Structure::getterSetterTransition(JSGlobalData& globalData, Structure* structure)
{
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
// Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary();
- transition->m_propertyTable = structure->copyPropertyTable();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTable(globalData, transition);
transition->m_isPinnedPropertyTable = true;
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- return transition.release();
+ return transition;
}
-PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind)
+Structure* Structure::toDictionaryTransition(JSGlobalData& globalData, Structure* structure, DictionaryKind kind)
{
ASSERT(!structure->isUncacheableDictionary());
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
- structure->materializePropertyMapIfNecessary();
- transition->m_propertyTable = structure->copyPropertyTable();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTable(globalData, transition);
transition->m_isPinnedPropertyTable = true;
transition->m_dictionaryKind = kind;
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- return transition.release();
+ return transition;
}
-PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure)
+Structure* Structure::toCacheableDictionaryTransition(JSGlobalData& globalData, Structure* structure)
{
- return toDictionaryTransition(structure, CachedDictionaryKind);
+ return toDictionaryTransition(globalData, structure, CachedDictionaryKind);
}
-PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure)
+Structure* Structure::toUncacheableDictionaryTransition(JSGlobalData& globalData, Structure* structure)
{
- return toDictionaryTransition(structure, UncachedDictionaryKind);
+ return toDictionaryTransition(globalData, structure, UncachedDictionaryKind);
}
// In future we may want to cache this transition.
-PassRefPtr<Structure> Structure::sealTransition(Structure* structure)
+Structure* Structure::sealTransition(JSGlobalData& globalData, Structure* structure)
{
- RefPtr<Structure> transition = preventExtensionsTransition(structure);
+ Structure* transition = preventExtensionsTransition(globalData, structure);
if (transition->m_propertyTable) {
PropertyTable::iterator end = transition->m_propertyTable->end();
@@ -532,13 +479,13 @@ PassRefPtr<Structure> Structure::sealTransition(Structure* structure)
iter->attributes |= DontDelete;
}
- return transition.release();
+ return transition;
}
// In future we may want to cache this transition.
-PassRefPtr<Structure> Structure::freezeTransition(Structure* structure)
+Structure* Structure::freezeTransition(JSGlobalData& globalData, Structure* structure)
{
- RefPtr<Structure> transition = preventExtensionsTransition(structure);
+ Structure* transition = preventExtensionsTransition(globalData, structure);
if (transition->m_propertyTable) {
PropertyTable::iterator end = transition->m_propertyTable->end();
@@ -546,32 +493,32 @@ PassRefPtr<Structure> Structure::freezeTransition(Structure* structure)
iter->attributes |= (DontDelete | ReadOnly);
}
- return transition.release();
+ return transition;
}
// In future we may want to cache this transition.
-PassRefPtr<Structure> Structure::preventExtensionsTransition(Structure* structure)
+Structure* Structure::preventExtensionsTransition(JSGlobalData& globalData, Structure* structure)
{
- RefPtr<Structure> transition = create(structure);
+ Structure* transition = create(globalData, structure);
// Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary();
- transition->m_propertyTable = structure->copyPropertyTable();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTable(globalData, transition);
transition->m_isPinnedPropertyTable = true;
transition->m_preventExtensions = true;
ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
- return transition.release();
+ return transition;
}
// In future we may want to cache this property.
-bool Structure::isSealed()
+bool Structure::isSealed(JSGlobalData& globalData)
{
if (isExtensible())
return false;
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return true;
@@ -584,12 +531,12 @@ bool Structure::isSealed()
}
// In future we may want to cache this property.
-bool Structure::isFrozen()
+bool Structure::isFrozen(JSGlobalData& globalData)
{
if (isExtensible())
return false;
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return true;
@@ -601,7 +548,7 @@ bool Structure::isFrozen()
return true;
}
-PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObject* object)
+Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObject* object)
{
ASSERT(isDictionary());
if (isUncacheableDictionary()) {
@@ -630,30 +577,30 @@ PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSGlobalData& global
return this;
}
-size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
+size_t Structure::addPropertyWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
ASSERT(!m_enumerationCache);
if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
specificValue = 0;
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
m_isPinnedPropertyTable = true;
- size_t offset = put(propertyName, attributes, specificValue);
+ size_t offset = putSpecificValue(globalData, propertyName, attributes, specificValue);
ASSERT(offset >= m_anonymousSlotCount);
if (propertyStorageSize() > propertyStorageCapacity())
growPropertyStorageCapacity();
return offset;
}
-size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
+size_t Structure::removePropertyWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName)
{
ASSERT(isUncacheableDictionary());
ASSERT(!m_enumerationCache);
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
m_isPinnedPropertyTable = true;
size_t offset = remove(propertyName);
@@ -688,14 +635,14 @@ inline void Structure::checkConsistency()
#endif
-PropertyTable* Structure::copyPropertyTable()
+PropertyTable* Structure::copyPropertyTable(JSGlobalData& globalData, Structure* owner)
{
- return m_propertyTable ? new PropertyTable(*m_propertyTable) : 0;
+ return m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : 0;
}
-size_t Structure::get(StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue)
+size_t Structure::get(JSGlobalData& globalData, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue)
{
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return WTF::notFound;
@@ -704,14 +651,14 @@ size_t Structure::get(StringImpl* propertyName, unsigned& attributes, JSCell*& s
return WTF::notFound;
attributes = entry->attributes;
- specificValue = entry->specificValue;
+ specificValue = entry->specificValue.get();
ASSERT(entry->offset >= m_anonymousSlotCount);
return entry->offset;
}
-bool Structure::despecifyFunction(const Identifier& propertyName)
+bool Structure::despecifyFunction(JSGlobalData& globalData, const Identifier& propertyName)
{
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return false;
@@ -721,25 +668,25 @@ bool Structure::despecifyFunction(const Identifier& propertyName)
return false;
ASSERT(entry->specificValue);
- entry->specificValue = 0;
+ entry->specificValue.clear();
return true;
}
-void Structure::despecifyAllFunctions()
+void Structure::despecifyAllFunctions(JSGlobalData& globalData)
{
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return;
PropertyTable::iterator end = m_propertyTable->end();
for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter)
- iter->specificValue = 0;
+ iter->specificValue.clear();
}
-size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
+size_t Structure::putSpecificValue(JSGlobalData& globalData, const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
ASSERT(!propertyName.isNull());
- ASSERT(get(propertyName) == notFound);
+ ASSERT(get(globalData, propertyName) == notFound);
checkConsistency();
if (attributes & DontEnum)
@@ -758,7 +705,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel
newOffset = m_propertyTable->size() + m_anonymousSlotCount;
ASSERT(newOffset >= m_anonymousSlotCount);
- m_propertyTable->add(PropertyMapEntry(rep, newOffset, attributes, specificValue));
+ m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue));
checkConsistency();
return newOffset;
@@ -798,9 +745,9 @@ void Structure::createPropertyMap(unsigned capacity)
checkConsistency();
}
-void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMode mode)
+void Structure::getPropertyNames(JSGlobalData& globalData, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return;
@@ -818,11 +765,26 @@ void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMo
}
}
-void Structure::initializeThreading()
-{
-#if !defined(NDEBUG) && ENABLE(JSC_MULTIPLE_THREADS)
- ignoreSetMutex();
-#endif
+void Structure::markChildren(MarkStack& markStack)
+{
+ JSCell::markChildren(markStack);
+ if (m_prototype)
+ markStack.append(&m_prototype);
+ if (m_cachedPrototypeChain)
+ markStack.append(&m_cachedPrototypeChain);
+ if (m_previous)
+ markStack.append(&m_previous);
+ if (m_specificValueInPrevious)
+ markStack.append(&m_specificValueInPrevious);
+ if (m_enumerationCache)
+ markStack.append(&m_enumerationCache);
+ if (m_propertyTable) {
+ PropertyTable::iterator end = m_propertyTable->end();
+ for (PropertyTable::iterator ptr = m_propertyTable->begin(); ptr != end; ++ptr) {
+ if (ptr->specificValue)
+ markStack.append(&ptr->specificValue);
+ }
+ }
}
#if DO_PROPERTYMAP_CONSTENCY_CHECK
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index c9f900a..fe9ce6b 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -27,6 +27,7 @@
#define Structure_h
#include "Identifier.h"
+#include "JSCell.h"
#include "JSType.h"
#include "JSValue.h"
#include "PropertyMapHashTable.h"
@@ -35,7 +36,7 @@
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "UString.h"
-#include "WeakGCPtr.h"
+#include "Weak.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -54,49 +55,41 @@ namespace JSC {
IncludeDontEnumProperties
};
- class Structure : public RefCounted<Structure> {
+ class Structure : public JSCell {
public:
friend class StructureTransitionTable;
- static PassRefPtr<Structure> create(JSGlobalData&, JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
+ static Structure* create(JSGlobalData& globalData, JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
{
- return adoptRef(new Structure(prototype, typeInfo, anonymousSlotCount, classInfo));
+ ASSERT(globalData.structureStructure);
+ return new (&globalData) Structure(globalData, prototype, typeInfo, anonymousSlotCount, classInfo);
}
- enum VPtrStealingHackType { VPtrStealingHack };
- static PassRefPtr<Structure> create(VPtrStealingHackType, const ClassInfo* classInfo)
- {
- return adoptRef(new Structure(jsNull(), TypeInfo(UnspecifiedType), 0, classInfo));
- }
-
- static void startIgnoringLeaks();
- static void stopIgnoringLeaks();
-
static void dumpStatistics();
- static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
- static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
- static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset);
- static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype);
- static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&);
- static PassRefPtr<Structure> getterSetterTransition(Structure*);
- static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*);
- static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*);
- static PassRefPtr<Structure> sealTransition(Structure*);
- static PassRefPtr<Structure> freezeTransition(Structure*);
- static PassRefPtr<Structure> preventExtensionsTransition(Structure*);
-
- bool isSealed();
- bool isFrozen();
+ static Structure* addPropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ static Structure* addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ static Structure* removePropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, size_t& offset);
+ static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
+ static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, const Identifier&);
+ static Structure* getterSetterTransition(JSGlobalData&, Structure*);
+ static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*);
+ static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*);
+ static Structure* sealTransition(JSGlobalData&, Structure*);
+ static Structure* freezeTransition(JSGlobalData&, Structure*);
+ static Structure* preventExtensionsTransition(JSGlobalData&, Structure*);
+
+ bool isSealed(JSGlobalData&);
+ bool isFrozen(JSGlobalData&);
bool isExtensible() const { return !m_preventExtensions; }
- PassRefPtr<Structure> flattenDictionaryStructure(JSGlobalData&, JSObject*);
+ Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
~Structure();
// These should be used with caution.
- size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
- size_t removePropertyWithoutTransition(const Identifier& propertyName);
- void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; }
+ size_t addPropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
+ size_t removePropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName);
+ void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
@@ -104,10 +97,9 @@ namespace JSC {
const TypeInfo& typeInfo() const { return m_typeInfo; }
JSValue storedPrototype() const { return m_prototype.get(); }
- DeprecatedPtr<Unknown>* storedPrototypeSlot() { return &m_prototype; }
JSValue prototypeForLookup(ExecState*) const;
StructureChain* prototypeChain(ExecState*) const;
- DeprecatedPtr<StructureChain>* cachedPrototypeChainSlot() { return &m_cachedPrototypeChain; }
+ void markChildren(MarkStack&);
Structure* previousID() const { return m_previous.get(); }
@@ -116,12 +108,12 @@ namespace JSC {
unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->propertyStorageSize() : static_cast<unsigned>(m_offset + 1)); }
bool isUsingInlineStorage() const;
- size_t get(const Identifier& propertyName);
- size_t get(StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue);
- size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
+ size_t get(JSGlobalData&, const Identifier& propertyName);
+ size_t get(JSGlobalData&, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue);
+ size_t get(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
{
ASSERT(!propertyName.isNull());
- return get(propertyName.impl(), attributes, specificValue);
+ return get(globalData, propertyName.impl(), attributes, specificValue);
}
bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
@@ -134,18 +126,15 @@ namespace JSC {
bool isEmpty() const { return m_propertyTable ? m_propertyTable->isEmpty() : m_offset == noOffset; }
- void despecifyDictionaryFunction(const Identifier& propertyName);
+ void despecifyDictionaryFunction(JSGlobalData&, const Identifier& propertyName);
void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
- void clearEnumerationCache(); // Defined in JSPropertyNameIterator.h.
JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
- void getPropertyNames(PropertyNameArray&, EnumerationMode mode);
+ void getPropertyNames(JSGlobalData&, PropertyNameArray&, EnumerationMode mode);
const ClassInfo* classInfo() const { return m_classInfo; }
- static void initializeThreading();
-
static ptrdiff_t prototypeOffset()
{
return OBJECT_OFFSETOF(Structure, m_prototype);
@@ -161,37 +150,47 @@ namespace JSC {
return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
}
+ static Structure* createStructure(JSGlobalData& globalData)
+ {
+ ASSERT(!globalData.structureStructure);
+ return new (&globalData) Structure(globalData);
+ }
+
private:
- Structure(JSValue prototype, const TypeInfo&, unsigned anonymousSlotCount, const ClassInfo*);
- Structure(const Structure*);
+ Structure(JSGlobalData&, JSValue prototype, const TypeInfo&, unsigned anonymousSlotCount, const ClassInfo*);
+ Structure(JSGlobalData&);
+ Structure(JSGlobalData&, const Structure*);
- static PassRefPtr<Structure> create(const Structure* structure)
+ static Structure* create(JSGlobalData& globalData, const Structure* structure)
{
- return adoptRef(new Structure(structure));
+ ASSERT(globalData.structureStructure);
+ return new (&globalData) Structure(globalData, structure);
}
-
+
+ static const ClassInfo s_info;
+
typedef enum {
NoneDictionaryKind = 0,
CachedDictionaryKind = 1,
UncachedDictionaryKind = 2
} DictionaryKind;
- static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind);
+ static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind);
- size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
+ size_t putSpecificValue(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t remove(const Identifier& propertyName);
void createPropertyMap(unsigned keyCount = 0);
void checkConsistency();
- bool despecifyFunction(const Identifier&);
- void despecifyAllFunctions();
+ bool despecifyFunction(JSGlobalData&, const Identifier&);
+ void despecifyAllFunctions(JSGlobalData&);
- PropertyTable* copyPropertyTable();
- void materializePropertyMap();
- void materializePropertyMapIfNecessary()
+ PropertyTable* copyPropertyTable(JSGlobalData&, Structure* owner);
+ void materializePropertyMap(JSGlobalData&);
+ void materializePropertyMapIfNecessary(JSGlobalData& globalData)
{
if (!m_propertyTable && m_previous)
- materializePropertyMap();
+ materializePropertyMap(globalData);
}
signed char transitionCount() const
@@ -210,18 +209,18 @@ namespace JSC {
TypeInfo m_typeInfo;
- DeprecatedPtr<Unknown> m_prototype;
- mutable DeprecatedPtr<StructureChain> m_cachedPrototypeChain;
+ WriteBarrier<Unknown> m_prototype;
+ mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
- RefPtr<Structure> m_previous;
+ WriteBarrier<Structure> m_previous;
RefPtr<StringImpl> m_nameInPrevious;
- JSCell* m_specificValueInPrevious;
+ WriteBarrier<JSCell> m_specificValueInPrevious;
const ClassInfo* m_classInfo;
StructureTransitionTable m_transitionTable;
- WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
+ WriteBarrier<JSPropertyNameIterator> m_enumerationCache;
OwnPtr<PropertyTable> m_propertyTable;
@@ -248,9 +247,9 @@ namespace JSC {
// 4 free bits
};
- inline size_t Structure::get(const Identifier& propertyName)
+ inline size_t Structure::get(JSGlobalData& globalData, const Identifier& propertyName)
{
- materializePropertyMapIfNecessary();
+ materializePropertyMapIfNecessary(globalData);
if (!m_propertyTable)
return notFound;
@@ -259,6 +258,48 @@ namespace JSC {
return entry ? entry->offset : notFound;
}
+ inline bool JSCell::isObject() const
+ {
+ return m_structure->typeInfo().type() == ObjectType;
+ }
+
+ inline bool JSCell::isString() const
+ {
+ return m_structure->typeInfo().type() == StringType;
+ }
+
+ inline const ClassInfo* JSCell::classInfo() const
+ {
+ return m_structure->classInfo();
+ }
+
+ inline Structure* JSCell::createDummyStructure(JSGlobalData& globalData)
+ {
+ return Structure::create(globalData, jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
+ }
+
+ inline bool JSValue::needsThisConversion() const
+ {
+ if (UNLIKELY(!isCell()))
+ return true;
+ return asCell()->structure()->typeInfo().needsThisConversion();
+ }
+
+ ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
+ {
+ ASSERT(!m_isCheckingForDefaultMarkViolation);
+ ASSERT(cell);
+ if (Heap::testAndSetMarked(cell))
+ return;
+ if (cell->structure()->typeInfo().type() >= CompoundType)
+ m_values.append(cell);
+ }
+
+ inline StructureTransitionTable::Hash::Key StructureTransitionTable::keyForWeakGCMapFinalizer(void*, Structure* structure)
+ {
+ return Hash::Key(structure->m_nameInPrevious.get(), structure->m_attributesInPrevious);
+ }
+
} // namespace JSC
#endif // Structure_h
diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp
index 4fa4a4b..ad6abff 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp
@@ -31,20 +31,33 @@
#include <wtf/RefPtr.h>
namespace JSC {
+
+ClassInfo StructureChain::s_info = { "StructureChain", 0, 0, 0 };
-StructureChain::StructureChain(NonNullPassRefPtr<Structure> structure, Structure* head)
- : JSCell(structure.releaseRef())
+StructureChain::StructureChain(JSGlobalData& globalData, Structure* structure, Structure* head)
+ : JSCell(globalData, structure)
{
size_t size = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
++size;
- m_vector = adoptArrayPtr(new RefPtr<Structure>[size + 1]);
+ m_vector = adoptArrayPtr(new WriteBarrier<Structure>[size + 1]);
size_t i = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
- m_vector[i++] = current;
- m_vector[i] = 0;
+ m_vector[i++].set(globalData, this, current);
+ m_vector[i].clear();
+}
+
+StructureChain::~StructureChain()
+{
+}
+
+void StructureChain::markChildren(MarkStack& markStack)
+{
+ size_t i = 0;
+ while (m_vector[i])
+ markStack.append(&m_vector[i++]);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h
index 88592dc..b984be6 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.h
+++ b/Source/JavaScriptCore/runtime/StructureChain.h
@@ -27,6 +27,7 @@
#define StructureChain_h
#include "JSCell.h"
+#include "Structure.h"
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassRefPtr.h>
@@ -41,14 +42,17 @@ namespace JSC {
friend class JIT;
public:
- static StructureChain* create(JSGlobalData& globalData, Structure* head) { return new (&globalData) StructureChain(globalData.structureChainStructure, head); }
- RefPtr<Structure>* head() { return m_vector.get(); }
+ static StructureChain* create(JSGlobalData& globalData, Structure* head) { return new (&globalData) StructureChain(globalData, globalData.structureChainStructure.get(), head); }
+ WriteBarrier<Structure>* head() { return m_vector.get(); }
+ void markChildren(MarkStack&);
- static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), 0, 0); }
- private:
- StructureChain(NonNullPassRefPtr<Structure>, Structure* head);
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), 0, &s_info); }
- OwnArrayPtr<RefPtr<Structure> > m_vector;
+ private:
+ StructureChain(JSGlobalData&, Structure*, Structure* head);
+ ~StructureChain();
+ OwnArrayPtr<WriteBarrier<Structure> > m_vector;
+ static ClassInfo s_info;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index da78e1b..adebad2 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -27,8 +27,8 @@
#define StructureTransitionTable_h
#include "UString.h"
+#include "WeakGCMap.h"
#include <wtf/HashFunctions.h>
-#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
@@ -69,7 +69,21 @@ class StructureTransitionTable {
static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
};
- typedef HashMap<Hash::Key, Structure*, Hash, HashTraits> TransitionMap;
+ struct WeakGCMapFinalizerCallback {
+ static void* finalizerContextFor(Hash::Key)
+ {
+ return 0;
+ }
+
+ static inline Hash::Key keyForFinalizer(void* context, Structure* structure)
+ {
+ return keyForWeakGCMapFinalizer(context, structure);
+ }
+ };
+
+ typedef WeakGCMap<Hash::Key, Structure, WeakGCMapFinalizerCallback, Hash, HashTraits> TransitionMap;
+
+ static Hash::Key keyForWeakGCMapFinalizer(void* context, Structure*);
public:
StructureTransitionTable()
@@ -81,9 +95,11 @@ public:
{
if (!isUsingSingleSlot())
delete map();
+ else
+ clearSingleTransition();
}
- inline void add(Structure*);
+ inline void add(JSGlobalData&, Structure*);
inline void remove(Structure*);
inline bool contains(StringImpl* rep, unsigned attributes) const;
inline Structure* get(StringImpl* rep, unsigned attributes) const;
@@ -100,9 +116,18 @@ private:
return reinterpret_cast<TransitionMap*>(m_data);
}
+ HandleSlot slot() const
+ {
+ ASSERT(isUsingSingleSlot());
+ return reinterpret_cast<HandleSlot>(m_data & ~UsingSingleSlotFlag);
+ }
+
void setMap(TransitionMap* map)
{
ASSERT(isUsingSingleSlot());
+
+ if (HandleSlot slot = this->slot())
+ HandleHeap::heapFor(slot)->deallocate(slot);
// This implicitly clears the flag that indicates we're using a single transition
m_data = reinterpret_cast<intptr_t>(map);
@@ -113,13 +138,31 @@ private:
Structure* singleTransition() const
{
ASSERT(isUsingSingleSlot());
- return reinterpret_cast<Structure*>(m_data & ~UsingSingleSlotFlag);
+ if (HandleSlot slot = this->slot()) {
+ if (*slot)
+ return reinterpret_cast<Structure*>(slot->asCell());
+ }
+ return 0;
}
-
- void setSingleTransition(Structure* structure)
+
+ void clearSingleTransition()
{
ASSERT(isUsingSingleSlot());
- m_data = reinterpret_cast<intptr_t>(structure) | UsingSingleSlotFlag;
+ if (HandleSlot slot = this->slot())
+ HandleHeap::heapFor(slot)->deallocate(slot);
+ }
+
+ void setSingleTransition(JSGlobalData& globalData, Structure* structure)
+ {
+ ASSERT(isUsingSingleSlot());
+ HandleSlot slot = this->slot();
+ if (!slot) {
+ slot = globalData.allocateGlobalHandle();
+ HandleHeap::heapFor(slot)->makeWeak(slot, 0, 0);
+ m_data = reinterpret_cast<intptr_t>(slot) | UsingSingleSlotFlag;
+ }
+ HandleHeap::heapFor(slot)->writeBarrier(slot, reinterpret_cast<JSCell*>(structure));
+ *slot = reinterpret_cast<JSCell*>(structure);
}
intptr_t m_data;
diff --git a/Source/JavaScriptCore/runtime/UString.h b/Source/JavaScriptCore/runtime/UString.h
index 8f6c083..b98e7b4 100644
--- a/Source/JavaScriptCore/runtime/UString.h
+++ b/Source/JavaScriptCore/runtime/UString.h
@@ -252,10 +252,7 @@ template<> struct DefaultHash<JSC::UString> {
typedef JSC::UStringHash Hash;
};
-template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits
-{
- static const bool canInitializeWithMemset = true;
-};
+template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits { };
} // namespace WTF
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index a40e684..5ad1c62 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -34,17 +34,31 @@ namespace JSC {
// A HashMap for GC'd values that removes entries when the associated value
// dies.
-template<typename KeyType, typename MappedType> class WeakGCMap : private Finalizer {
+template <typename KeyType, typename MappedType> struct DefaultWeakGCMapFinalizerCallback {
+ static void* finalizerContextFor(KeyType key)
+ {
+ return reinterpret_cast<void*>(key);
+ }
+
+ static KeyType keyForFinalizer(void* context, typename HandleTypes<MappedType>::ExternalType)
+ {
+ return reinterpret_cast<KeyType>(context);
+ }
+};
+
+template<typename KeyType, typename MappedType, typename FinalizerCallback = DefaultWeakGCMapFinalizerCallback<KeyType, MappedType>, typename HashArg = typename DefaultHash<KeyType>::Hash, typename KeyTraitsArg = HashTraits<KeyType> >
+class WeakGCMap : private WeakHandleOwner {
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(WeakGCMap);
- typedef HashMap<KeyType, HandleSlot> MapType;
+ typedef HashMap<KeyType, HandleSlot, HashArg, KeyTraitsArg> MapType;
typedef typename HandleTypes<MappedType>::ExternalType ExternalType;
typedef typename MapType::iterator map_iterator;
public:
struct iterator {
+ friend class WeakGCMap;
iterator(map_iterator iter)
: m_iterator(iter)
{
@@ -62,7 +76,7 @@ public:
bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; }
private:
- map_iterator m_iterator;
+ map_iterator m_iterator;
};
WeakGCMap()
@@ -78,6 +92,25 @@ public:
m_map.clear();
}
+ bool contains(const KeyType& key) const
+ {
+ return m_map.contains(key);
+ }
+
+ iterator find(const KeyType& key)
+ {
+ return m_map.find(key);
+ }
+
+ void remove(iterator iter)
+ {
+ ASSERT(iter.m_iterator != m_map.end());
+ HandleSlot slot = iter.m_iterator->second;
+ ASSERT(slot);
+ HandleHeap::heapFor(slot)->deallocate(slot);
+ m_map.remove(iter.m_iterator);
+ }
+
ExternalType get(const KeyType& key) const
{
return HandleTypes<MappedType>::getFromSlot(m_map.get(key));
@@ -88,14 +121,35 @@ public:
return m_map.get(key);
}
+ pair<iterator, bool> add(JSGlobalData& globalData, const KeyType& key, ExternalType value)
+ {
+ pair<typename MapType::iterator, bool> iter = m_map.add(key, 0);
+ if (iter.second) {
+ HandleSlot slot = globalData.allocateGlobalHandle();
+ iter.first->second = slot;
+ HandleHeap::heapFor(slot)->makeWeak(slot, this, FinalizerCallback::finalizerContextFor(key));
+ HandleHeap::heapFor(slot)->writeBarrier(slot, value);
+ *slot = value;
+ }
+ return iter;
+ }
+
+ void set(iterator iter, ExternalType value)
+ {
+ HandleSlot slot = iter.m_iterator->second;
+ ASSERT(slot);
+ HandleHeap::heapFor(slot)->writeBarrier(slot, value);
+ *slot = value;
+ }
+
void set(JSGlobalData& globalData, const KeyType& key, ExternalType value)
{
pair<typename MapType::iterator, bool> iter = m_map.add(key, 0);
HandleSlot slot = iter.first->second;
if (iter.second) {
slot = globalData.allocateGlobalHandle();
- iter.first->second = slot;
HandleHeap::heapFor(slot)->makeWeak(slot, this, key);
+ iter.first->second = slot;
}
HandleHeap::heapFor(slot)->writeBarrier(slot, value);
*slot = value;
@@ -113,22 +167,6 @@ public:
size_t size() { return m_map.size(); }
- bool deprecatedRemove(const KeyType& key, ExternalType value)
- {
- // This only exists in order to allow some semblance of correctness to
- // the JSWeakObjectMapClear API
- typename MapType::iterator iter = m_map.find(key);
- if (iter == m_map.end())
- return false;
- HandleSlot slot = iter->second;
- ExternalType inmap = HandleTypes<MappedType>::getFromSlot(slot);
- if (inmap && inmap != value)
- return false;
- m_map.remove(iter);
- HandleHeap::heapFor(slot)->deallocate(slot);
- return true;
- }
-
iterator begin() { return iterator(m_map.begin()); }
iterator end() { return iterator(m_map.end()); }
@@ -138,9 +176,9 @@ public:
}
private:
- virtual void finalize(Handle<Unknown>, void* key)
+ virtual void finalize(Handle<Unknown> handle, void* context)
{
- HandleSlot slot = m_map.take(static_cast<KeyType>(key));
+ HandleSlot slot = m_map.take(FinalizerCallback::keyForFinalizer(context, HandleTypes<MappedType>::getFromSlot(handle.slot())));
ASSERT(slot);
HandleHeap::heapFor(slot)->deallocate(slot);
}
diff --git a/Source/JavaScriptCore/runtime/WeakGCPtr.h b/Source/JavaScriptCore/runtime/WeakGCPtr.h
deleted file mode 100644
index 3f87b83..0000000
--- a/Source/JavaScriptCore/runtime/WeakGCPtr.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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. 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 WeakGCPtr_h
-#define WeakGCPtr_h
-
-#include "Global.h"
-#include "Heap.h"
-
-namespace JSC {
-// A smart pointer whose get() function returns 0 for cells that have died
-
-template <typename T> class WeakGCPtr : public HandleConverter<WeakGCPtr<T>, T> {
- WTF_MAKE_NONCOPYABLE(WeakGCPtr);
-
-public:
- typedef typename HandleTypes<T>::ExternalType ExternalType;
-
- WeakGCPtr()
- : m_slot(0)
- {
- }
-
- WeakGCPtr(JSGlobalData& globalData, Finalizer* finalizer = 0, void* context = 0)
- : m_slot(globalData.allocateGlobalHandle())
- {
- HandleHeap::heapFor(m_slot)->makeWeak(m_slot, finalizer, context);
- }
-
- WeakGCPtr(JSGlobalData& globalData, ExternalType value, Finalizer* finalizer = 0, void* context = 0)
- : m_slot(globalData.allocateGlobalHandle())
- {
- HandleHeap::heapFor(m_slot)->makeWeak(m_slot, finalizer, context);
- internalSet(value);
- }
-
- ExternalType get() const { return HandleTypes<T>::getFromSlot(m_slot); }
-
- void clear()
- {
- if (m_slot)
- internalSet(ExternalType());
- }
-
- bool operator!() const { return !m_slot || !*m_slot; }
-
- // This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef ExternalType (WeakGCPtr::*UnspecifiedBoolType);
- operator UnspecifiedBoolType*() const { return !*this ? 0 : reinterpret_cast<UnspecifiedBoolType*>(1); }
-
- ~WeakGCPtr()
- {
- if (!m_slot)
- return;
- HandleHeap::heapFor(m_slot)->deallocate(m_slot);
- }
-
- void set(JSGlobalData& globalData, ExternalType value, Finalizer* finalizer)
- {
- if (!this->m_slot) {
- this->m_slot = globalData.allocateGlobalHandle();
- HandleHeap::heapFor(this->m_slot)->makeWeak(this->m_slot, finalizer, 0);
- } else
- ASSERT(HandleHeap::heapFor(this->m_slot)->getFinalizer(this->m_slot) == finalizer);
- this->internalSet(value);
- }
-
-private:
- void internalSet(ExternalType value)
- {
- ASSERT(m_slot);
- JSValue newValue(HandleTypes<T>::toJSValue(value));
- HandleHeap::heapFor(m_slot)->writeBarrier(m_slot, newValue);
- *m_slot = newValue;
- }
-
- HandleSlot m_slot;
-};
-
-} // namespace JSC
-
-#endif // WeakGCPtr_h
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index af018a8..32cb968 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -32,54 +32,17 @@ namespace JSC {
class JSCell;
class JSGlobalData;
-typedef enum { } Unknown;
-typedef JSValue* HandleSlot;
-
-// FIXME: Remove all uses of this class.
-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;
-};
-
-// FIXME: Remove all uses of this class.
-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;
-};
+inline void writeBarrier(JSGlobalData&, const JSCell*, JSValue)
+{
+}
-template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
+inline void writeBarrier(JSGlobalData&, const JSCell*, JSCell*)
{
- return lhs.get() == rhs.get();
}
+typedef enum { } Unknown;
+typedef JSValue* HandleSlot;
+
template <typename T> struct JSValueChecker {
static const bool IsJSValue = false;
};
@@ -92,11 +55,36 @@ template <> struct JSValueChecker<JSValue> {
template <typename T> class WriteBarrierBase {
public:
COMPILE_ASSERT(!JSValueChecker<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
- void set(JSGlobalData&, const JSCell*, T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
+ void set(JSGlobalData& globalData, const JSCell* owner, T* value)
+ {
+ this->m_cell = reinterpret_cast<JSCell*>(value);
+ writeBarrier(globalData, owner, this->m_cell);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie(owner));
+ ASSERT(!isZombie(m_cell));
+#endif
+ }
- 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); }
+ T* get() const
+ {
+ return reinterpret_cast<T*>(m_cell);
+ }
+
+ T* operator*() const
+ {
+ ASSERT(m_cell);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie(m_cell));
+#endif
+ return static_cast<T*>(m_cell);
+ }
+
+ T* operator->() const
+ {
+ ASSERT(m_cell);
+ return static_cast<T*>(m_cell);
+ }
+
void clear() { m_cell = 0; }
JSCell** slot() { return &m_cell; }
@@ -106,7 +94,13 @@ public:
bool operator!() const { return !m_cell; }
- void setWithoutWriteBarrier(T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
+ void setWithoutWriteBarrier(T* value)
+ {
+ this->m_cell = reinterpret_cast<JSCell*>(value);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!m_cell || !isZombie(m_cell));
+#endif
+ }
private:
JSCell* m_cell;
@@ -114,12 +108,32 @@ private:
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 set(JSGlobalData& globalData, const JSCell* owner, JSValue value)
+ {
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie(owner));
+ ASSERT(!value.isZombie());
+#endif
+ m_value = JSValue::encode(value);
+ writeBarrier(globalData, owner, value);
+ }
+ void setWithoutWriteBarrier(JSValue value)
+ {
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!value.isZombie());
+#endif
+ 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 isObject() const { return get().isObject(); }
+ bool isNull() const { return get().isNull(); }
bool isGetterSetter() const { return get().isGetterSetter(); }
JSValue* slot()