summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.h2
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h14
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp106
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp6
-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/Completion.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.cpp25
-rw-r--r--Source/JavaScriptCore/runtime/ConservativeSet.h57
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/DateConversion.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.h8
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.h6
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.h4
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp68
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h77
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h4
-rw-r--r--Source/JavaScriptCore/runtime/Heap.cpp66
-rw-r--r--Source/JavaScriptCore/runtime/Heap.h21
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSAPIValueWrapper.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp59
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h31
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h93
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp16
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h75
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp40
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp82
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h17
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp317
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h270
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSNumberCell.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp125
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h44
-rw-r--r--Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSTypeInfo.h11
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h51
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h47
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h19
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/JSZombie.h4
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.cpp80
-rw-r--r--Source/JavaScriptCore/runtime/MachineStackMarker.h31
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.cpp89
-rw-r--r--Source/JavaScriptCore/runtime/MarkStack.h127
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/MarkedBlock.h12
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/MarkedSpace.h17
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h9
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/PropertyMapHashTable.h2
-rw-r--r--Source/JavaScriptCore/runtime/PropertyNameArray.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/PutPropertySlot.h9
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp49
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.h18
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.h6
-rw-r--r--Source/JavaScriptCore/runtime/RegExpKey.h49
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp44
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h32
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp20
-rw-r--r--Source/JavaScriptCore/runtime/ScopeChain.h15
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.cpp35
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.h20
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h10
-rw-r--r--Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h6
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp19
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.h10
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h29
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.h9
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h54
114 files changed, 1638 insertions, 1286 deletions
diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp
index 25a8916..f46d108 100644
--- a/Source/JavaScriptCore/runtime/ArgList.cpp
+++ b/Source/JavaScriptCore/runtime/ArgList.cpp
@@ -23,6 +23,7 @@
#include "JSValue.h"
#include "JSCell.h"
+#include "JSObject.h"
#include "ScopeChain.h"
using std::min;
@@ -38,12 +39,12 @@ void ArgList::getSlice(int startIndex, ArgList& result) const
result = ArgList(m_args + startIndex, m_argCount - startIndex);
}
-void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet)
+void MarkedArgumentBuffer::markLists(HeapRootMarker& heapRootMarker, ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
MarkedArgumentBuffer* list = *it;
- markStack.deprecatedAppendValues(list->m_buffer, list->m_size);
+ heapRootMarker.mark(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size);
}
}
@@ -55,8 +56,8 @@ void MarkedArgumentBuffer::slowAppend(JSValue v)
// our Vector's inline capacity, though, our values move to the
// heap, where they do need explicit marking.
if (!m_markSet) {
- // We can only register for explicit marking once we know which heap
- // is the current one, i.e., when a non-immediate value is appended.
+ // FIXME: Even if v is not a JSCell*, if previous values in the buffer
+ // are, then they won't be marked!
if (Heap* heap = Heap::heap(v)) {
ListSet& markSet = heap->markListSet();
markSet.add(this);
diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h
index 5564d5b..a794a04 100644
--- a/Source/JavaScriptCore/runtime/ArgList.h
+++ b/Source/JavaScriptCore/runtime/ArgList.h
@@ -141,7 +141,7 @@ namespace JSC {
const_iterator begin() const { return m_buffer; }
const_iterator end() const { return m_buffer + m_size; }
- static void markLists(MarkStack&, ListSet&);
+ static void markLists(HeapRootMarker&, ListSet&);
private:
void slowAppend(JSValue);
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 007e0f1..950bb4e 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -92,9 +92,9 @@ namespace JSC {
d->registers = &activation->registerAt(0);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
@@ -237,19 +237,17 @@ namespace JSC {
// This JSActivation function is defined here so it can get at Arguments::setRegisters.
inline void JSActivation::copyRegisters(JSGlobalData& globalData)
{
- ASSERT(!d()->registerArray);
+ ASSERT(!m_registerArray);
- size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
- size_t numVars = d()->functionExecutable->capturedVariableCount();
- size_t numLocals = numVars + numParametersMinusThis;
+ size_t numLocals = m_numCapturedVars + m_numParametersMinusThis;
if (!numLocals)
return;
- int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
+ int registerOffset = m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, d()->registers - registerOffset, registerArraySize);
+ OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, m_registers - registerOffset, registerArraySize);
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 af2afc6..e0f4b23 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -52,16 +52,18 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject
static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
{
+ JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
+
// a single numeric argument denotes the array size (!)
if (args.size() == 1 && args.at(0).isNumber()) {
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(exec->lexicalGlobalObject()->arrayStructure(), n, CreateInitialized);
+ return new (exec) JSArray(globalObject->arrayStructure(), n, CreateInitialized);
}
// otherwise the array is constructed with the arguments in it
- return new (exec) JSArray(exec->globalData(), exec->lexicalGlobalObject()->arrayStructure(), args);
+ return new (exec) JSArray(exec->globalData(), globalObject->arrayStructure(), args);
}
static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 488effd..fdbcd95 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -165,16 +165,20 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
bool isRealArray = isJSArray(&exec->globalData(), thisValue);
if (!isRealArray && !thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSArray* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
#if OS(SYMBIAN)
// Symbian has very limited stack size available.
@@ -225,16 +229,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (!thisValue.inherits(&JSArray::s_info))
return throwVMTypeError(exec);
JSObject* thisObj = asArray(thisValue);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
return earlyReturnValue;
JSStringBuilder strBuffer;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -260,6 +268,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
StringRecursionChecker checker(exec, thisObj);
if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
@@ -271,7 +282,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
if (!exec->argument(0).isUndefined())
separator = exec->argument(0).toString(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (isJSArray(&exec->globalData(), thisObj)) {
JSArray* array = asArray(thisObj);
@@ -355,12 +365,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue))
return JSValue::encode(asArray(thisValue)->pop());
JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ JSValue result;
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -375,6 +389,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
+
if (isJSArray(&exec->globalData(), thisValue) && exec->argumentCount() == 1) {
JSArray* array = asArray(thisValue);
array->push(exec, exec->argument(0));
@@ -383,6 +398,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
JSObject* thisObj = thisValue.toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
for (unsigned n = 0; n < exec->argumentCount(); n++)
thisObj->put(exec, length + n, exec->argument(n));
length += exec->argumentCount();
@@ -394,8 +412,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned middle = length / 2;
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned middle = length / 2;
for (unsigned k = 0; k < middle; k++) {
unsigned lk1 = length - k - 1;
JSValue obj2 = getProperty(exec, thisObj, lk1);
@@ -420,6 +440,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
JSValue result;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length));
result = jsUndefined();
@@ -451,6 +474,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
JSValue result = resObj;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
@@ -466,6 +492,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length || exec->hadException())
+ return JSValue::encode(thisObj);
JSValue function = exec->argument(0);
CallData callData;
@@ -481,11 +510,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
return JSValue::encode(thisObj);
}
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
- if (!length)
- return JSValue::encode(thisObj);
-
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
@@ -523,14 +547,16 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.12
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
if (!exec->argumentCount())
return JSValue::encode(constructEmptyArray(exec));
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned deleteCount = length - begin;
@@ -589,10 +615,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
{
- JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
// 15.4.4.13
+
+ JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
unsigned nrArgs = exec->argumentCount();
if ((nrArgs) && (length)) {
if (isJSArray(&exec->globalData(), thisObj))
@@ -616,6 +645,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -627,7 +659,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -674,6 +705,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -683,8 +717,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-
JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
@@ -731,6 +763,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -742,7 +777,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
JSValue result = jsBoolean(true);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -787,6 +821,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -796,7 +833,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -832,6 +868,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue function = exec->argument(0);
CallData callData;
@@ -843,7 +882,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
JSValue result = jsBoolean(false);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
JSFunction* f = asFunction(function);
@@ -885,7 +923,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -894,9 +935,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -955,7 +996,10 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
{
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
JSValue function = exec->argument(0);
CallData callData;
CallType callType = getCallData(function, callData);
@@ -964,9 +1008,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
unsigned i = 0;
JSValue rv;
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && exec->argumentCount() == 1)
return throwVMTypeError(exec);
+
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
@@ -1023,13 +1067,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
{
- // JavaScript 1.5 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
+ // 15.4.4.14
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
JSValue searchElement = exec->argument(0);
for (; index < length; ++index) {
JSValue e = getProperty(exec, thisObj, index);
@@ -1044,10 +1088,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec)
EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec)
{
- // JavaScript 1.6 Extension by Mozilla
- // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
+ // 15.4.4.15
JSObject* thisObj = exec->hostThisValue().toThisObject(exec);
-
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length)
return JSValue::encode(jsNumber(-1));
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h
index e41d8ca..96641bd 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h
@@ -35,9 +35,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 21ef5bb..e5b0f3d 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -40,7 +40,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalOb
// ECMA 15.6.2
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure());
obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -69,9 +69,9 @@ CallType BooleanConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue)
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSGlobalObject* globalObject, JSValue immediateBooleanValue)
{
- BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), exec->lexicalGlobalObject()->booleanObjectStructure());
+ BooleanObject* obj = new (exec) BooleanObject(exec->globalData(), globalObject->booleanObjectStructure());
obj->setInternalValue(exec->globalData(), immediateBooleanValue);
return obj;
}
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h
index 0f3efa7..2550b3b 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue);
+ JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSGlobalObject*, JSValue);
JSObject* constructBoolean(ExecState*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index 16c4669..2945c0e 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& globalData, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(globalData, structure)
+BooleanObject::BooleanObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index e2af0c2..ef2d403 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -31,9 +31,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
};
diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp
index 83d8bd8..ac19705 100644
--- a/Source/JavaScriptCore/runtime/Completion.cpp
+++ b/Source/JavaScriptCore/runtime/Completion.cpp
@@ -39,7 +39,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
- RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
+ ProgramExecutable* program = ProgramExecutable::create(exec, source);
JSObject* error = program->checkSyntax(exec);
if (error)
return Completion(Throw, error);
@@ -52,14 +52,16 @@ Completion evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCod
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
- RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
- JSObject* error = program->compile(exec, scopeChain);
- if (error)
- return Completion(Throw, error);
+ ProgramExecutable* program = ProgramExecutable::create(exec, source);
+ if (!program) {
+ JSValue exception = exec->globalData().exception;
+ exec->globalData().exception = JSValue();
+ return Completion(Throw, exception);
+ }
JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain, thisObj);
+ JSValue result = exec->interpreter()->execute(program, exec, scopeChain, thisObj);
if (exec->hadException()) {
JSValue exception = exec->exception();
diff --git a/Source/JavaScriptCore/runtime/ConservativeSet.cpp b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
index bc8bd6d..8872023 100644
--- a/Source/JavaScriptCore/runtime/ConservativeSet.cpp
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.cpp
@@ -33,33 +33,26 @@ inline bool isPointerAligned(void* p)
return !((intptr_t)(p) & (sizeof(char*) - 1));
}
-void ConservativeSet::grow()
+void ConservativeRoots::grow()
{
size_t newCapacity = m_capacity == inlineCapacity ? nonInlineCapacity : m_capacity * 2;
- DeprecatedPtr<JSCell>* newSet = static_cast<DeprecatedPtr<JSCell>*>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));
- memcpy(newSet, m_set, m_size * sizeof(JSCell*));
- if (m_set != m_inlineSet)
- OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(JSCell*));
+ 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_set = newSet;
+ m_roots = newRoots;
}
-void ConservativeSet::add(void* begin, void* end)
+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) {
- if (!m_heap->contains(*it))
- continue;
-
- if (m_size == m_capacity)
- grow();
-
- m_set[m_size++] = reinterpret_cast<JSCell*>(*it);
- }
+ 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
index e7c2c4a..d078606 100644
--- a/Source/JavaScriptCore/runtime/ConservativeSet.h
+++ b/Source/JavaScriptCore/runtime/ConservativeSet.h
@@ -23,24 +23,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ConservativeSet_h
-#define ConservativeSet_h
+#ifndef ConservativeRoots_h
+#define ConservativeRoots_h
#include "Heap.h"
-#include "MarkStack.h"
+#include <wtf/OSAllocator.h>
#include <wtf/Vector.h>
namespace JSC {
class JSCell;
+class Heap;
-class ConservativeSet {
+// May contain duplicates.
+
+class ConservativeRoots {
public:
- ConservativeSet(Heap*);
- ~ConservativeSet();
+ ConservativeRoots(Heap*);
+ ~ConservativeRoots();
+ void add(void*);
void add(void* begin, void* end);
- void mark(MarkStack&);
+
+ size_t size();
+ JSCell** roots();
private:
static const size_t inlineCapacity = 128;
@@ -49,32 +55,47 @@ private:
void grow();
Heap* m_heap;
- DeprecatedPtr<JSCell>* m_set;
+ JSCell** m_roots;
size_t m_size;
size_t m_capacity;
- DeprecatedPtr<JSCell> m_inlineSet[inlineCapacity];
+ JSCell* m_inlineRoots[inlineCapacity];
};
-inline ConservativeSet::ConservativeSet(Heap* heap)
+inline ConservativeRoots::ConservativeRoots(Heap* heap)
: m_heap(heap)
- , m_set(m_inlineSet)
+ , m_roots(m_inlineRoots)
, m_size(0)
, m_capacity(inlineCapacity)
{
}
-inline ConservativeSet::~ConservativeSet()
+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()
{
- if (m_set != m_inlineSet)
- OSAllocator::decommitAndRelease(m_set, m_capacity * sizeof(DeprecatedPtr<JSCell>*));
+ return m_size;
}
-inline void ConservativeSet::mark(MarkStack& markStack)
+inline JSCell** ConservativeRoots::roots()
{
- for (size_t i = 0; i < m_size; ++i)
- markStack.append(&m_set[i]);
+ return m_roots;
}
} // namespace JSC
-#endif // ConservativeSet_h
+#endif // ConservativeRoots_h
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index efaeb0f..0a06148 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -70,7 +70,7 @@ DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject,
}
// ECMA 15.9.3
-JSObject* constructDate(ExecState* exec, const ArgList& args)
+JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
int numArgs = args.size();
@@ -121,13 +121,13 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
}
}
- return new (exec) DateInstance(exec, value);
+ return new (exec) DateInstance(exec, globalObject->dateStructure(), value);
}
static EncodedJSValue JSC_HOST_CALL constructWithDateConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructDate(exec, args));
+ return JSValue::encode(constructDate(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType DateConstructor::getConstructData(ConstructData& constructData)
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.h b/Source/JavaScriptCore/runtime/DateConstructor.h
index 2adcd08..bd529f1 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.h
+++ b/Source/JavaScriptCore/runtime/DateConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructDate(ExecState*, const ArgList&);
+ JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp
index 597f1e9..1418876 100644
--- a/Source/JavaScriptCore/runtime/DateConversion.cpp
+++ b/Source/JavaScriptCore/runtime/DateConversion.cpp
@@ -44,6 +44,7 @@
#include "DateConversion.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include "UString.h"
#include <wtf/DateMath.h>
diff --git a/Source/JavaScriptCore/runtime/DateInstance.cpp b/Source/JavaScriptCore/runtime/DateInstance.cpp
index 95d5dc2..74adda4 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.cpp
+++ b/Source/JavaScriptCore/runtime/DateInstance.cpp
@@ -35,21 +35,14 @@ namespace JSC {
const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, 0};
DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsNaN());
}
DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure, double time)
- : JSWrapperObject(exec->globalData(), structure)
-{
- ASSERT(inherits(&s_info));
- setInternalValue(exec->globalData(), jsNumber(timeClip(time)));
-}
-
-DateInstance::DateInstance(ExecState* exec, double time)
- : JSWrapperObject(exec->globalData(), exec->lexicalGlobalObject()->dateStructure())
+ : JSWrapperObject(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 627b9e7..d0dcf0b 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.h
+++ b/Source/JavaScriptCore/runtime/DateInstance.h
@@ -31,7 +31,6 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
public:
- DateInstance(ExecState*, double);
DateInstance(ExecState*, NonNullPassRefPtr<Structure>, double);
explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>);
@@ -53,14 +52,11 @@ namespace JSC {
return calculateGregorianDateTimeUTC(exec);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- protected:
- static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
-
private:
const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.h b/Source/JavaScriptCore/runtime/DatePrototype.h
index dca90e3..0ebbedc 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.h
+++ b/Source/JavaScriptCore/runtime/DatePrototype.h
@@ -36,14 +36,16 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
+ COMPILE_ASSERT(!DateInstance::AnonymousSlotCount, DatePrototype_stomps_on_your_anonymous_slot);
+ static const unsigned AnonymousSlotCount = 1;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index 2e53b95..7f4f82c 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -42,7 +42,7 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject
static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState* exec)
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
- Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
@@ -55,7 +55,7 @@ ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec)
{
JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined();
- Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
+ Structure* errorStructure = asInternalFunction(exec->callee())->globalObject()->errorStructure();
return JSValue::encode(ErrorInstance::create(exec, errorStructure, message));
}
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index c1beef7..82dbf0f 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -29,9 +29,9 @@ namespace JSC {
public:
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static ErrorInstance* create(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&);
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 607a2c2..a059ed2 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -33,6 +33,11 @@
#include "UStringBuilder.h"
#include "Vector.h"
+#if ENABLE(DFG_JIT)
+#include "DFGByteCodeParser.h"
+#include "DFGJITCompiler.h"
+#endif
+
namespace JSC {
NativeExecutable::~NativeExecutable()
@@ -44,7 +49,7 @@ VPtrHackExecutable::~VPtrHackExecutable()
}
EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
- : ScriptExecutable(exec, source, inStrictContext)
+ : ScriptExecutable(exec->globalData().evalExecutableStructure.get(), exec, source, inStrictContext)
{
}
@@ -53,7 +58,7 @@ EvalExecutable::~EvalExecutable()
}
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source, false)
+ : ScriptExecutable(exec->globalData().programExecutableStructure.get(), exec, source, false)
{
}
@@ -62,7 +67,7 @@ ProgramExecutable::~ProgramExecutable()
}
FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
- : ScriptExecutable(globalData, source, inStrictContext)
+ : ScriptExecutable(globalData->functionExecutableStructure.get(), globalData, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -74,7 +79,7 @@ FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifie
}
FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
- : ScriptExecutable(exec, source, inStrictContext)
+ : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -85,9 +90,6 @@ FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name,
m_lastLine = lastLine;
}
-FunctionExecutable::~FunctionExecutable()
-{
-}
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
@@ -127,6 +129,13 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
return 0;
}
+void EvalExecutable::markChildren(MarkStack& markStack)
+{
+ ScriptExecutable::markChildren(markStack);
+ if (m_evalCodeBlock)
+ m_evalCodeBlock->markAggregate(markStack);
+}
+
JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
{
JSObject* exception = 0;
@@ -178,6 +187,41 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
return 0;
}
+#if ENABLE(JIT)
+static bool tryDFGCompile(JSGlobalData* globalData, CodeBlock* codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck)
+{
+#if ENABLE(DFG_JIT)
+#if ENABLE(DFG_JIT_RESTRICTIONS)
+ // FIXME: No flow control yet supported, don't bother scanning the bytecode if there are any jump targets.
+ // FIXME: temporarily disable property accesses until we fix regressions.
+ if (codeBlock->numberOfJumpTargets() || codeBlock->numberOfStructureStubInfos())
+ return false;
+#endif
+
+ DFG::Graph dfg;
+ if (!parse(dfg, globalData, codeBlock))
+ return false;
+
+ DFG::JITCompiler dataFlowJIT(globalData, dfg, codeBlock);
+ dataFlowJIT.compileFunction(jitCode, jitCodeWithArityCheck);
+ return true;
+#else
+ UNUSED_PARAM(globalData);
+ UNUSED_PARAM(codeBlock);
+ UNUSED_PARAM(jitCode);
+ UNUSED_PARAM(jitCodeWithArityCheck);
+ return false;
+#endif
+}
+#endif
+
+void ProgramExecutable::markChildren(MarkStack& markStack)
+{
+ ScriptExecutable::markChildren(markStack);
+ if (m_programCodeBlock)
+ m_programCodeBlock->markAggregate(markStack);
+}
+
JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
JSObject* exception = 0;
@@ -212,7 +256,10 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
#if ENABLE(JIT)
if (exec->globalData().canUseJIT()) {
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+ bool dfgCompiled = tryDFGCompile(&exec->globalData(), m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
+ if (!dfgCompiled)
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+
#if !ENABLE(OPCODE_SAMPLING)
if (!BytecodeGenerator::dumpsGeneratedCode())
m_codeBlockForCall->discardBytecode();
@@ -268,8 +315,9 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
return 0;
}
-void FunctionExecutable::markAggregate(MarkStack& markStack)
+void FunctionExecutable::markChildren(MarkStack& markStack)
{
+ ScriptExecutable::markChildren(markStack);
if (m_codeBlockForCall)
m_codeBlockForCall->markAggregate(markStack);
if (m_codeBlockForConstruct)
@@ -288,7 +336,7 @@ void FunctionExecutable::discardCode()
#endif
}
-PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
+FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception);
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index b2565a0..f15df07 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -44,7 +44,7 @@ namespace JSC {
struct ExceptionInfo;
- class ExecutableBase : public RefCounted<ExecutableBase> {
+ class ExecutableBase : public JSCell {
friend class JIT;
protected:
@@ -52,21 +52,23 @@ namespace JSC {
static const int NUM_PARAMETERS_NOT_COMPILED = -1;
public:
- ExecutableBase(int numParameters)
- : m_numParametersForCall(numParameters)
+ ExecutableBase(Structure* structure, int numParameters)
+ : JSCell(structure)
+ , m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
}
- virtual ~ExecutableBase() {}
-
bool isHostFunction() const
{
ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
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); }
+
protected:
+ static const unsigned StructureFlags = 0;
int m_numParametersForCall;
int m_numParametersForConstruct;
@@ -96,16 +98,16 @@ namespace JSC {
friend class JIT;
public:
#if ENABLE(JIT)
- static PassRefPtr<NativeExecutable> create(MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
+ static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
{
if (!callThunk)
- return adoptRef(new NativeExecutable(JITCode(), function, JITCode(), constructor));
- return adoptRef(new NativeExecutable(JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor));
+ return new (&globalData) NativeExecutable(globalData, JITCode(), function, JITCode(), constructor);
+ return new (&globalData) NativeExecutable(globalData, JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor);
}
#else
- static PassRefPtr<NativeExecutable> create(NativeFunction function, NativeFunction constructor)
+ static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
{
- return adoptRef(new NativeExecutable(function, constructor));
+ return new (&globalData) NativeExecutable(globalData, function, constructor);
}
#endif
@@ -115,8 +117,8 @@ namespace JSC {
private:
#if ENABLE(JIT)
- NativeExecutable(JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(JSGlobalData& globalData, JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
+ : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -126,8 +128,8 @@ namespace JSC {
m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall();
}
#else
- NativeExecutable(NativeFunction function, NativeFunction constructor)
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
+ : ExecutableBase(globalData.executableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -142,8 +144,8 @@ namespace JSC {
class VPtrHackExecutable : public ExecutableBase {
public:
- VPtrHackExecutable()
- : ExecutableBase(NUM_PARAMETERS_IS_HOST)
+ VPtrHackExecutable(Structure* structure)
+ : ExecutableBase(structure, NUM_PARAMETERS_IS_HOST)
{
}
@@ -152,8 +154,8 @@ namespace JSC {
class ScriptExecutable : public ExecutableBase {
public:
- ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -166,8 +168,8 @@ namespace JSC {
#endif
}
- ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
{
@@ -214,6 +216,7 @@ namespace JSC {
JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_evalCodeBlock)
error = compileInternal(exec, scopeChainNode);
@@ -227,7 +230,7 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); }
+ static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return new (exec) EvalExecutable(exec, source, isInStrictContext); }
#if ENABLE(JIT)
JITCode& generatedJITCode()
@@ -235,26 +238,30 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
EvalExecutable(ExecState*, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
+ virtual void markChildren(MarkStack&);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
class ProgramExecutable : public ScriptExecutable {
public:
- static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
+ static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
{
- return adoptRef(new ProgramExecutable(exec, source));
+ return new (exec) ProgramExecutable(exec, source);
}
~ProgramExecutable();
JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_programCodeBlock)
error = compileInternal(exec, scopeChainNode);
@@ -276,11 +283,15 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
+
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
private:
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
ProgramExecutable(ExecState*, const SourceCode&);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
+ virtual void markChildren(MarkStack&);
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
@@ -288,18 +299,16 @@ namespace JSC {
class FunctionExecutable : public ScriptExecutable {
friend class JIT;
public:
- static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
+ return new (exec) FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine);
}
- static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
+ return new (globalData) FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine);
}
- ~FunctionExecutable();
-
JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
{
return new (exec) JSFunction(exec, this, scopeChain);
@@ -318,6 +327,7 @@ namespace JSC {
JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForCall)
error = compileForCallInternal(exec, scopeChainNode);
@@ -338,6 +348,7 @@ namespace JSC {
JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ ASSERT(exec->globalData().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForConstruct)
error = compileForConstructInternal(exec, scopeChainNode);
@@ -363,8 +374,9 @@ namespace JSC {
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
void discardCode();
- void markAggregate(MarkStack&);
- static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+ 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); }
private:
FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
@@ -372,7 +384,8 @@ namespace JSC {
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
-
+
+ static const unsigned StructureFlags = OverridesMarkChildren | ScriptExecutable::StructureFlags;
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index e642594..a9f0a06 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -49,7 +49,7 @@ FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* global
static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructFunction(exec, args));
+ return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
@@ -61,7 +61,7 @@ ConstructType FunctionConstructor::getConstructData(ConstructData& constructData
static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructFunction(exec, args));
+ return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
// ECMA 15.3.1 The Function Constructor Called as a Function
@@ -72,7 +72,7 @@ CallType FunctionConstructor::getCallData(CallData& callData)
}
// ECMA 15.3.2 The Function Constructor
-JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
+JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
// Functions need to have a space following the opening { due to for web compatibility
// see https://bugs.webkit.org/show_bug.cgi?id=24350
@@ -96,11 +96,10 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
program = builder.toUString();
}
- JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSGlobalData& globalData = globalObject->globalData();
SourceCode source = makeSource(program, sourceURL, lineNumber);
JSObject* exception = 0;
- RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
+ FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
if (!function) {
ASSERT(exception);
return throwError(exec, exception);
@@ -111,9 +110,9 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
}
// ECMA 15.3.2 The Function Constructor
-JSObject* constructFunction(ExecState* exec, const ArgList& args)
+JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
- return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
+ return constructFunction(exec, globalObject, args, Identifier(exec, "anonymous"), UString(), 1);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h
index 6af4861..7f21b20 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h
@@ -36,8 +36,8 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
- JSObject* constructFunction(ExecState*, const ArgList&);
+ JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+ JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.h b/Source/JavaScriptCore/runtime/FunctionPrototype.h
index fb0bb48..447f00b 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.h
@@ -30,9 +30,9 @@ namespace JSC {
FunctionPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>);
void addFunctionProperties(ExecState*, JSGlobalObject*, Structure* functionStructure, JSFunction** callFunction, JSFunction** applyFunction);
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
index a941cfa..2e878bf 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
@@ -33,6 +33,7 @@
#include "Heap.h"
#include "JSGlobalData.h"
#include "JSLock.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include <wtf/RetainPtr.h>
#include <wtf/WTFThreadData.h>
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index 68a8c70..8241275 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -47,9 +47,9 @@ 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(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount, 0);
}
private:
virtual bool isGetterSetter() const;
diff --git a/Source/JavaScriptCore/runtime/Heap.cpp b/Source/JavaScriptCore/runtime/Heap.cpp
index c52bcfe..e3ef8bb 100644
--- a/Source/JavaScriptCore/runtime/Heap.cpp
+++ b/Source/JavaScriptCore/runtime/Heap.cpp
@@ -46,7 +46,7 @@ Heap::Heap(JSGlobalData* globalData)
, m_markListSet(0)
, m_activityCallback(DefaultGCActivityCallback::create(this))
, m_globalData(globalData)
- , m_machineStackMarker(this)
+ , m_machineThreads(this)
, m_markStack(globalData->jsArrayVPtr)
, m_handleHeap(globalData)
, m_extraCost(0)
@@ -75,6 +75,10 @@ void Heap::destroy()
// (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();
@@ -97,7 +101,7 @@ void Heap::reportExtraMemoryCostSlowCase(size_t cost)
// if a large value survives one garbage collection, there is not much point to
// collecting more frequently as long as it stays alive.
- if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.capacity() / 2)
+ if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.highWaterMark() / 2)
collectAllGarbage();
m_extraCost += cost;
}
@@ -147,11 +151,11 @@ bool Heap::unprotect(JSValue k)
return m_protectedValues.remove(k.asCell());
}
-void Heap::markProtectedObjects(MarkStack& markStack)
+void Heap::markProtectedObjects(HeapRootMarker& heapRootMarker)
{
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- markStack.deprecatedAppend(&it->first);
+ heapRootMarker.mark(&it->first);
}
void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
@@ -165,7 +169,7 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
m_tempSortingVectors.removeLast();
}
-void Heap::markTempSortVectors(MarkStack& markStack)
+void Heap::markTempSortVectors(HeapRootMarker& heapRootMarker)
{
typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
@@ -176,7 +180,7 @@ void Heap::markTempSortVectors(MarkStack& markStack)
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
if (vectorIt->first)
- markStack.deprecatedAppend(&vectorIt->first);
+ heapRootMarker.mark(&vectorIt->first);
}
}
}
@@ -195,52 +199,52 @@ void Heap::markRoots()
}
#endif
+ void* dummy;
+
ASSERT(m_operationInProgress == NoOperation);
if (m_operationInProgress != NoOperation)
CRASH();
m_operationInProgress = Collection;
- // We gather the conservative set before clearing mark bits, because
+ 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.
- ConservativeSet conservativeSet(this);
- m_machineStackMarker.markMachineStackConservatively(conservativeSet);
- conservativeSet.add(registerFile().start(), registerFile().end());
+ ConservativeRoots machineThreadRoots(this);
+ m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
+
+ ConservativeRoots registerFileRoots(this);
+ registerFile().gatherConservativeRoots(registerFileRoots);
m_markedSpace.clearMarks();
- MarkStack& markStack = m_markStack;
- conservativeSet.mark(markStack);
+ markStack.append(machineThreadRoots);
markStack.drain();
- // Mark explicitly registered roots.
- markProtectedObjects(markStack);
+ markStack.append(registerFileRoots);
markStack.drain();
-
- // Mark temporary vector for Array sorting
- markTempSortVectors(markStack);
+
+ markProtectedObjects(heapRootMarker);
markStack.drain();
- HashSet<GlobalCodeBlock*>::const_iterator end = m_codeBlocks.end();
- for (HashSet<GlobalCodeBlock*>::const_iterator it = m_codeBlocks.begin(); it != end; ++it)
- (*it)->markAggregate(markStack);
+ markTempSortVectors(heapRootMarker);
markStack.drain();
- // Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
- MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
+ MarkedArgumentBuffer::markLists(heapRootMarker, *m_markListSet);
if (m_globalData->exception)
- markStack.append(&m_globalData->exception);
- if (m_globalData->firstStringifierToMark)
- JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
+ heapRootMarker.mark(&m_globalData->exception);
markStack.drain();
- m_handleHeap.markStrongHandles(markStack);
+ 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(markStack);
+ m_globalData->smallStrings.markChildren(heapRootMarker);
markStack.drain();
markStack.compact();
@@ -371,7 +375,7 @@ void Heap::reset(SweepToggle sweepToggle)
m_extraCost = 0;
#if ENABLE(JSC_ZOMBIES)
- sweep();
+ sweepToggle = DoSweep;
#endif
if (sweepToggle == DoSweep) {
@@ -379,7 +383,11 @@ void Heap::reset(SweepToggle sweepToggle)
m_markedSpace.shrink();
}
- size_t proportionalBytes = static_cast<size_t>(1.5 * m_markedSpace.size());
+ // 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();
diff --git a/Source/JavaScriptCore/runtime/Heap.h b/Source/JavaScriptCore/runtime/Heap.h
index eb8af70..c2d3bac 100644
--- a/Source/JavaScriptCore/runtime/Heap.h
+++ b/Source/JavaScriptCore/runtime/Heap.h
@@ -23,6 +23,7 @@
#define Heap_h
#include "HandleHeap.h"
+#include "HandleStack.h"
#include "MarkStack.h"
#include "MarkedSpace.h"
#include <wtf/Forward.h>
@@ -33,6 +34,7 @@ namespace JSC {
class GCActivityCallback;
class GlobalCodeBlock;
+ class HeapRootMarker;
class JSCell;
class JSGlobalData;
class JSValue;
@@ -65,7 +67,7 @@ namespace JSC {
JSGlobalData* globalData() const { return m_globalData; }
MarkedSpace& markedSpace() { return m_markedSpace; }
- MachineStackMarker& machineStackMarker() { return m_machineStackMarker; }
+ MachineThreads& machineThreads() { return m_machineThreads; }
GCActivityCallback* activityCallback();
void setActivityCallback(PassOwnPtr<GCActivityCallback>);
@@ -92,14 +94,15 @@ namespace JSC {
void pushTempSortVector(Vector<ValueStringPair>*);
void popTempSortVector(Vector<ValueStringPair>*);
-
- HashSet<GlobalCodeBlock*>& codeBlocks() { return m_codeBlocks; }
-
+
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
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;
@@ -111,8 +114,8 @@ namespace JSC {
void reportExtraMemoryCostSlowCase(size_t);
void markRoots();
- void markProtectedObjects(MarkStack&);
- void markTempSortVectors(MarkStack&);
+ void markProtectedObjects(HeapRootMarker&);
+ void markTempSortVectors(HeapRootMarker&);
enum SweepToggle { DoNotSweep, DoSweep };
void reset(SweepToggle);
@@ -124,7 +127,6 @@ namespace JSC {
ProtectCountSet m_protectedValues;
Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
- HashSet<GlobalCodeBlock*> m_codeBlocks;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
@@ -132,10 +134,11 @@ namespace JSC {
JSGlobalData* m_globalData;
- MachineStackMarker m_machineStackMarker;
+ MachineThreads m_machineThreads;
MarkStack m_markStack;
HandleHeap m_handleHeap;
-
+ HandleStack m_handleStack;
+
size_t m_extraCost;
};
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 3992418..4a99b19 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -22,6 +22,7 @@
#include "Identifier.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "NumericStrings.h"
#include "ScopeChain.h"
#include <new> // for placement new
@@ -90,7 +91,7 @@ bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
struct IdentifierCStringTranslator {
static unsigned hash(const char* c)
{
- return WTF::StringHasher::createHash<char>(c);
+ return StringHasher::computeHash<char>(c);
}
static bool equal(StringImpl* r, const char* s)
@@ -150,7 +151,7 @@ struct UCharBuffer {
struct IdentifierUCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
- return WTF::StringHasher::createHash<UChar>(buf.s, buf.length);
+ return StringHasher::computeHash<UChar>(buf.s, buf.length);
}
static bool equal(StringImpl* str, const UCharBuffer& buf)
@@ -216,7 +217,7 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const UChar* s,
{
if (length == 1) {
UChar c = s[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
}
if (!length)
@@ -243,7 +244,7 @@ PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringI
if (r->length() == 1) {
UChar c = r->characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
r = globalData->smallStrings.singleCharacterStringRep(c);
if (r->isIdentifier())
return r;
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index 8427b8c..08c98a5 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -39,9 +39,9 @@ namespace JSC {
const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 43dd0d3..54fe909 100644
--- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -35,9 +35,9 @@ namespace JSC {
virtual bool isAPIValueWrapper() const { return true; }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount, 0);
}
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index eb9c7c1..d0c50dd 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -39,15 +39,23 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0 };
-JSActivation::JSActivation(CallFrame* callFrame, NonNullPassRefPtr<FunctionExecutable> functionExecutable)
- : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers()))
+JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
+ : Base(callFrame->globalData().activationStructure, functionExecutable->symbolTable(), callFrame->registers())
+ , m_numParametersMinusThis(static_cast<int>(functionExecutable->parameterCount()))
+ , m_numCapturedVars(functionExecutable->capturedVariableCount())
+ , m_requiresDynamicChecks(functionExecutable->usesEval())
+ , m_argumentsRegister(functionExecutable->generatedBytecode().argumentsRegister())
{
ASSERT(inherits(&s_info));
+
+ // We have to manually ref and deref the symbol table as JSVariableObject
+ // doesn't know about SharedSymbolTable
+ static_cast<SharedSymbolTable*>(m_symbolTable)->ref();
}
JSActivation::~JSActivation()
{
- delete d();
+ static_cast<SharedSymbolTable*>(m_symbolTable)->deref();
}
void JSActivation::markChildren(MarkStack& markStack)
@@ -55,30 +63,26 @@ void JSActivation::markChildren(MarkStack& markStack)
Base::markChildren(markStack);
// No need to mark our registers if they're still in the RegisterFile.
- WriteBarrier<Unknown>* registerArray = d()->registerArray.get();
+ WriteBarrier<Unknown>* registerArray = m_registerArray.get();
if (!registerArray)
return;
- size_t numParametersMinusThis = d()->functionExecutable->parameterCount();
-
- size_t count = numParametersMinusThis;
- markStack.appendValues(registerArray, count);
-
- size_t numVars = d()->functionExecutable->capturedVariableCount();
+ markStack.appendValues(registerArray, m_numParametersMinusThis);
// Skip the call frame, which sits between the parameters and vars.
- markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
+ markStack.appendValues(registerArray + m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize, m_numCapturedVars, MayContainNullValues);
}
inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
{
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
- if (!entry.isNull()) {
- ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
- slot.setValue(registerAt(entry.getIndex()).get());
- return true;
- }
- return false;
+ if (entry.isNull())
+ return false;
+ if (entry.getIndex() >= m_numCapturedVars)
+ return false;
+
+ slot.setValue(registerAt(entry.getIndex()).get());
+ return true;
}
inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
@@ -90,7 +94,9 @@ inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identif
return false;
if (entry.isReadOnly())
return true;
- ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
+ if (entry.getIndex() >= m_numCapturedVars)
+ return false;
+
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
}
@@ -99,9 +105,11 @@ void JSActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& prope
{
SymbolTable::const_iterator end = symbolTable().end();
for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
- ASSERT(it->second.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount()));
- if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
- propertyNames.add(Identifier(exec, it->first.get()));
+ if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
+ continue;
+ if (it->second.getIndex() >= m_numCapturedVars)
+ continue;
+ propertyNames.add(Identifier(exec, it->first.get()));
}
// Skip the JSVariableObject implementation of getOwnPropertyNames
JSObject::getOwnPropertyNames(exec, propertyNames, mode);
@@ -116,8 +124,9 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
return false;
SymbolTableEntry& entry = iter->second;
ASSERT(!entry.isNull());
- if (entry.getIndex() >= static_cast<int>(d()->functionExecutable->capturedVariableCount()))
+ if (entry.getIndex() >= m_numCapturedVars)
return false;
+
entry.setAttributes(attributes);
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
@@ -195,15 +204,15 @@ JSValue JSActivation::toStrictThisObject(ExecState*) const
bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
- requiresDynamicChecks = d()->functionExecutable->usesEval();
+ requiresDynamicChecks = m_requiresDynamicChecks;
return false;
}
JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identifier&)
{
JSActivation* activation = asActivation(slotBase);
- CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->d()->registers));
- int argumentsRegister = activation->d()->functionExecutable->generatedBytecode().argumentsRegister();
+ CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
+ int argumentsRegister = activation->m_argumentsRegister;
if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue())
return arguments;
int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 6e04041..7463f47 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -42,7 +42,7 @@ namespace JSC {
class JSActivation : public JSVariableObject {
typedef JSVariableObject Base;
public:
- JSActivation(CallFrame*, NonNullPassRefPtr<FunctionExecutable>);
+ JSActivation(CallFrame*, FunctionExecutable*);
virtual ~JSActivation();
virtual void markChildren(MarkStack&);
@@ -66,29 +66,12 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static PassRefPtr<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;
private:
- struct JSActivationData : public JSVariableObjectData {
- JSActivationData(NonNullPassRefPtr<FunctionExecutable> _functionExecutable, Register* registers)
- : JSVariableObjectData(_functionExecutable->symbolTable(), registers)
- , functionExecutable(_functionExecutable)
- {
- // We have to manually ref and deref the symbol table as JSVariableObjectData
- // doesn't know about SharedSymbolTable
- functionExecutable->symbolTable()->ref();
- }
- ~JSActivationData()
- {
- static_cast<SharedSymbolTable*>(symbolTable)->deref();
- }
-
- RefPtr<FunctionExecutable> functionExecutable;
- };
-
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertyDescriptor&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
@@ -98,7 +81,10 @@ namespace JSC {
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
- JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
+ int m_numParametersMinusThis;
+ int m_numCapturedVars : 31;
+ bool m_requiresDynamicChecks : 1;
+ int m_argumentsRegister;
};
JSActivation* asActivation(JSValue);
@@ -108,6 +94,11 @@ namespace JSC {
ASSERT(asObject(value)->inherits(&JSActivation::s_info));
return static_cast<JSActivation*>(asObject(value));
}
+
+ ALWAYS_INLINE JSActivation* Register::activation() const
+ {
+ return asActivation(jsValue());
+ }
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 822b84c..1d621fe 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -127,7 +127,7 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
#endif
JSArray::JSArray(VPtrStealingHackType)
- : JSNonFinalObject(createStructure(jsNull()))
+ : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
{
ASSERT(inherits(&s_info));
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index ede3c61..1a6eba8 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -58,7 +58,6 @@ namespace JSC {
enum ArrayCreationMode { CreateCompact, CreateInitialized };
class JSArray : public JSNonFinalObject {
- friend class JIT;
friend class Walker;
public:
@@ -125,13 +124,23 @@ namespace JSC {
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToRegisters(ExecState*, Register*, uint32_t);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
inline void markChildrenDirect(MarkStack& markStack);
+ static ptrdiff_t storageOffset()
+ {
+ return OBJECT_OFFSETOF(JSArray, m_storage);
+ }
+
+ static ptrdiff_t vectorLengthOffset()
+ {
+ return OBJECT_OFFSETOF(JSArray, m_vectorLength);
+ }
+
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -142,7 +151,7 @@ namespace JSC {
void* subclassData() const;
void setSubclassData(void*);
-
+
private:
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putSlowCase(ExecState*, unsigned propertyName, JSValue);
@@ -174,11 +183,8 @@ namespace JSC {
return asArray(value.asCell());
}
- inline bool isJSArray(JSGlobalData* globalData, JSValue v)
- {
- return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr;
- }
inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; }
+ inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && isJSArray(globalData, v.asCell()); }
inline void JSArray::markChildrenDirect(MarkStack& markStack)
{
@@ -196,77 +202,6 @@ namespace JSC {
}
}
- 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);
- }
-
- inline 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
- }
-
// Rule from ECMA 15.2 about what an array index is.
// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
inline unsigned Identifier::toArrayIndex(bool& ok) const
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.cpp b/Source/JavaScriptCore/runtime/JSByteArray.cpp
index ae735dc..fbaea1d 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSByteArray.cpp
@@ -50,9 +50,9 @@ JSByteArray::~JSByteArray()
#endif
-PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype, const JSC::ClassInfo* classInfo)
+PassRefPtr<Structure> JSByteArray::createStructure(JSGlobalData& globalData, JSValue prototype, const JSC::ClassInfo* classInfo)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, classInfo);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, classInfo);
}
bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.h b/Source/JavaScriptCore/runtime/JSByteArray.h
index 6e91594..e674958 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.h
+++ b/Source/JavaScriptCore/runtime/JSByteArray.h
@@ -76,7 +76,7 @@ namespace JSC {
}
JSByteArray(ExecState*, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage);
- static PassRefPtr<Structure> createStructure(JSValue prototype, const JSC::ClassInfo* = &s_defaultInfo);
+ static PassRefPtr<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&);
@@ -102,7 +102,7 @@ namespace JSC {
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSByteArray(VPtrStealingHackType)
- : JSNonFinalObject(createStructure(jsNull()))
+ : JSNonFinalObject(Structure::create(Structure::VPtrStealingHack, &s_info))
{
}
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index 9acb777..ce7fe22 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -119,7 +119,7 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, P
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
- JSObject* object = toObject(exec);
+ JSObject* object = toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
@@ -131,7 +131,7 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
- JSObject* object = toObject(exec);
+ JSObject* object = toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
@@ -140,27 +140,27 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot)
{
- toObject(exec)->put(exec, identifier, value, slot);
+ toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value, slot);
}
void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
{
- toObject(exec)->put(exec, identifier, value);
+ toObject(exec, exec->lexicalGlobalObject())->put(exec, identifier, value);
}
bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier);
+ return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier);
}
bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier);
+ return toObject(exec, exec->lexicalGlobalObject())->deleteProperty(exec, identifier);
}
JSObject* JSCell::toThisObject(ExecState* exec) const
{
- return toObject(exec);
+ return toObject(exec, exec->lexicalGlobalObject());
}
JSValue JSCell::getJSNumber()
@@ -203,7 +203,7 @@ UString JSCell::toString(ExecState*) const
return UString();
}
-JSObject* JSCell::toObject(ExecState*) const
+JSObject* JSCell::toObject(ExecState*, JSGlobalObject*) const
{
ASSERT_NOT_REACHED();
return 0;
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 7313d52..ab0e237 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -35,6 +35,8 @@
namespace JSC {
+ class JSGlobalObject;
+
#if COMPILER(MSVC)
// If WTF_MAKE_NONCOPYABLE is applied to JSCell we end up with a bunch of
// undefined references to the JSCell copy constructor and assignment operator
@@ -53,10 +55,9 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(JSCell);
#endif
+ friend class ExecutableBase;
friend class GetterSetter;
friend class Heap;
- friend class JIT;
- friend class JSNumberCell;
friend class JSObject;
friend class JSPropertyNameIterator;
friend class JSString;
@@ -67,15 +68,16 @@ namespace JSC {
friend class MarkedSpace;
friend class MarkedBlock;
friend class ScopeChainNode;
+ friend class StructureChain;
private:
explicit JSCell(Structure*);
virtual ~JSCell();
public:
- static PassRefPtr<Structure> createDummyStructure()
+ static PassRefPtr<Structure> createDummyStructure(JSGlobalData& globalData)
{
- return Structure::create(jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
+ return Structure::create(globalData, jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount, 0);
}
// Querying the type.
@@ -107,7 +109,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
// Garbage collection.
void* operator new(size_t, ExecState*);
@@ -137,6 +139,16 @@ namespace JSC {
// property names, we want a similar interface with appropriate optimizations.)
bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+ static ptrdiff_t structureOffset()
+ {
+ return OBJECT_OFFSETOF(JSCell, m_structure);
+ }
+
+ Structure* const * addressOfStructure() const
+ {
+ return &m_structure;
+ }
+
protected:
static const unsigned AnonymousSlotCount = 0;
@@ -203,6 +215,11 @@ namespace JSC {
return isCell() ? asCell()->getString(exec) : UString();
}
+ template <typename Base> UString HandleConverter<Base, Unknown>::getString(ExecState* exec) const
+ {
+ return jsValue().getString(exec);
+ }
+
inline JSObject* JSValue::getObject() const
{
return isCell() ? asCell()->getObject() : 0;
@@ -322,24 +339,19 @@ namespace JSC {
inline JSObject* JSValue::toObject(ExecState* exec) const
{
- return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
+ return isCell() ? asCell()->toObject(exec, exec->lexicalGlobalObject()) : toObjectSlowCase(exec, exec->lexicalGlobalObject());
}
- inline JSObject* JSValue::toThisObject(ExecState* exec) const
+ inline JSObject* JSValue::toObject(ExecState* exec, JSGlobalObject* globalObject) const
{
- return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
+ return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
}
-
- template <typename T> void MarkStack::append(DeprecatedPtr<T>* slot)
+
+ inline JSObject* JSValue::toThisObject(ExecState* exec) const
{
- internalAppend(slot->get());
+ return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
}
- template <typename T> void MarkStack::append(WriteBarrierBase<T>* slot)
- {
- internalAppend(slot->get());
- }
-
ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
{
ASSERT(!m_isCheckingForDefaultMarkViolation);
@@ -350,31 +362,6 @@ namespace JSC {
m_values.append(cell);
}
- ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
- {
- ASSERT(value);
- internalAppend(*value);
- }
-
- ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
- {
- ASSERT(value);
- internalAppend(*value);
- }
-
- ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value)
- {
- ASSERT(value);
- internalAppend(value->jsValue());
- }
-
- ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
- {
- ASSERT(value);
- if (value.isCell())
- internalAppend(value.asCell());
- }
-
inline Heap* Heap::heap(JSValue v)
{
if (!v.isCell())
@@ -411,8 +398,10 @@ namespace JSC {
inline MarkedSpace::SizeClass& MarkedSpace::sizeClassFor(size_t bytes)
{
- ASSERT(bytes && bytes <= preciseCutoff);
- return m_preciseSizeClasses[(bytes - 1) / preciseStep];
+ ASSERT(bytes && bytes < maxCellSize);
+ if (bytes < preciseCutoff)
+ return m_preciseSizeClasses[(bytes - 1) / preciseStep];
+ return m_impreciseSizeClasses[(bytes - 1) / impreciseStep];
}
inline void* MarkedSpace::allocate(size_t bytes)
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 2ade441..dbfc606 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -56,16 +56,16 @@ bool JSFunction::isHostFunctionNonInline() const
return isHostFunction();
}
-JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
+JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure, VPtrHackExecutable* executable)
: Base(structure)
- , m_executable(adoptRef(new VPtrHackExecutable()))
{
ASSERT(inherits(&s_info));
+ m_executable.setWithoutWriteBarrier(executable);
}
-JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, PassRefPtr<NativeExecutable> thunk)
+JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeExecutable* thunk)
: Base(globalObject, structure)
- , m_executable(thunk)
+ , m_executable(exec->globalData(), this, thunk)
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
@@ -75,17 +75,20 @@ JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPas
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(globalObject, structure)
- , m_executable(exec->globalData().getHostFunction(func))
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
+ // We separate out intialisation from setting the executable
+ // as getHostFunction may perform a GC allocation, so we have to be able to
+ // mark ourselves safely
+ m_executable.set(exec->globalData(), this, exec->globalData().getHostFunction(func));
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
-JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
+JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode)
: Base(scopeChainNode->globalObject.get(), scopeChainNode->globalObject->functionStructure())
- , m_executable(executable)
+ , m_executable(exec->globalData(), this, executable)
, m_scopeChain(exec->globalData(), this, scopeChainNode)
{
ASSERT(inherits(&s_info));
@@ -96,19 +99,6 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> ex
JSFunction::~JSFunction()
{
ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
-
- // JIT code for other functions may have had calls linked directly to the code for this function; these links
- // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
- // this memory is freed and may be reused (potentially for another, different JSFunction).
- if (!isHostFunction()) {
-#if ENABLE(JIT_OPTIMIZE_CALL)
- ASSERT(m_executable);
- if (jsExecutable()->isGeneratedForCall())
- jsExecutable()->generatedBytecodeForCall().unlinkCallers();
- if (jsExecutable()->isGeneratedForConstruct())
- jsExecutable()->generatedBytecodeForConstruct().unlinkCallers();
-#endif
- }
}
static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
@@ -148,9 +138,13 @@ const UString JSFunction::calculatedDisplayName(ExecState* exec)
void JSFunction::markChildren(MarkStack& markStack)
{
Base::markChildren(markStack);
- if (!isHostFunction()) {
- jsExecutable()->markAggregate(markStack);
- markStack.append(&m_scopeChain);
+
+ markStack.append(&m_scopeChain);
+ if (m_executable) {
+ // Delightful race condition: m_executable may not have been initialised
+ // if this is a host function, as the executable isn't necessarily created
+ // until after the function has been allocated.
+ markStack.append(&m_executable);
}
}
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 089f42e..505b9de 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -34,6 +34,7 @@ namespace JSC {
class JSActivation;
class JSGlobalObject;
class NativeExecutable;
+ class VPtrHackExecutable;
EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
@@ -45,8 +46,8 @@ namespace JSC {
public:
JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
- JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, PassRefPtr<NativeExecutable>);
- JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
+ JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeExecutable*);
+ JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
virtual ~JSFunction();
const UString& name(ExecState*);
@@ -72,9 +73,9 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
NativeFunction nativeFunction();
@@ -86,7 +87,7 @@ namespace JSC {
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
private:
- JSFunction(NonNullPassRefPtr<Structure>);
+ JSFunction(NonNullPassRefPtr<Structure>, VPtrHackExecutable*);
bool isHostFunctionNonInline() const;
@@ -102,7 +103,7 @@ namespace JSC {
static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
- RefPtr<ExecutableBase> m_executable;
+ WriteBarrier<ExecutableBase> m_executable;
WriteBarrier<ScopeChainNode> m_scopeChain;
};
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index e25040c..ee1829b 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -68,6 +68,27 @@
using namespace WTF;
+namespace {
+
+using namespace JSC;
+
+class Recompiler {
+public:
+ void operator()(JSCell*);
+};
+
+inline void Recompiler::operator()(JSCell* cell)
+{
+ if (!cell->inherits(&JSFunction::s_info))
+ return;
+ JSFunction* function = asFunction(cell);
+ if (function->executable()->isHostFunction())
+ return;
+ function->jsExecutable()->discardCode();
+}
+
+} // namespace
+
namespace JSC {
extern JSC_CONST_HASHTABLE HashTable arrayTable;
@@ -107,8 +128,12 @@ void JSGlobalData::storeVPtrs()
jsString->~JSCell();
COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(storage), sizeof_JSFunction_must_be_less_than_storage);
- JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
+ 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));
JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
+ executable->~JSCell();
jsFunction->~JSCell();
}
@@ -124,18 +149,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, regExpTable(fastNew<HashTable>(JSC::regExpTable))
, regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
, stringTable(fastNew<HashTable>(JSC::stringTable))
- , activationStructure(JSActivation::createStructure(jsNull()))
- , interruptedExecutionErrorStructure(JSNonFinalObject::createStructure(jsNull()))
- , terminatedExecutionErrorStructure(JSNonFinalObject::createStructure(jsNull()))
- , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
- , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull()))
- , stringStructure(JSString::createStructure(jsNull()))
- , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
- , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
- , getterSetterStructure(GetterSetter::createStructure(jsNull()))
- , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
- , scopeChainNodeStructure(ScopeChainNode::createStructure(jsNull()))
- , dummyMarkableCellStructure(JSCell::createDummyStructure())
, identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
@@ -145,7 +158,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, heap(this)
, globalObjectCount(0)
, dynamicGlobalObject(0)
- , firstStringifierToMark(0)
, cachedUTCOffset(NaN)
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
, m_regExpCache(new RegExpCache(this))
@@ -156,6 +168,24 @@ 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();
@@ -282,18 +312,18 @@ JSGlobalData*& JSGlobalData::sharedInstanceInternal()
}
#if ENABLE(JIT)
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
{
return jitStubs->hostFunctionStub(this, function);
}
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
{
return jitStubs->hostFunctionStub(this, function, generator);
}
#else
-PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
+NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
{
- return NativeExecutable::create(function, callHostFunctionAsConstructor);
+ return NativeExecutable::create(*this, function, callHostFunctionAsConstructor);
}
#endif
@@ -325,22 +355,6 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
-class Recompiler {
-public:
- void operator()(JSCell*);
-};
-
-inline void Recompiler::operator()(JSCell* cell)
-{
- if (!cell->inherits(&JSFunction::s_info))
- return;
- JSFunction* function = asFunction(cell);
- if (function->executable()->isHostFunction())
- return;
- function->jsExecutable()->discardCode();
-}
-
-
void JSGlobalData::recompileAllJSFunctions()
{
// If JavaScript is running, it's not safe to recompile, since we'll end
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index ee3e067..34ea75d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -57,6 +57,7 @@ namespace JSC {
class CodeBlock;
class CommonIdentifiers;
+ class HandleStack;
class IdentifierTable;
class Interpreter;
class JSGlobalObject;
@@ -128,7 +129,7 @@ namespace JSC {
#if ENABLE(JSC_MULTIPLE_THREADS)
// Will start tracking threads that use the heap, which is resource-heavy.
- void makeUsableFromMultipleThreads() { heap.machineStackMarker().makeUsableFromMultipleThreads(); }
+ void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
#endif
GlobalDataType globalDataType;
@@ -155,7 +156,12 @@ namespace JSC {
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;
static void storeVPtrs();
static JS_EXPORTDATA void* jsArrayVPtr;
@@ -199,15 +205,15 @@ namespace JSC {
{
return jitStubs->ctiStub(this, generator);
}
- PassRefPtr<NativeExecutable> getHostFunction(NativeFunction, ThunkGenerator);
+ NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
#endif
- PassRefPtr<NativeExecutable> getHostFunction(NativeFunction);
+ NativeExecutable* getHostFunction(NativeFunction);
TimeoutChecker timeoutChecker;
Terminator terminator;
Heap heap;
- DeprecatedPtr<Unknown> exception;
+ JSValue exception;
#if ENABLE(JIT)
ReturnAddressPtr exceptionLocation;
#endif
@@ -219,8 +225,6 @@ namespace JSC {
HashSet<JSObject*> stringRecursionCheckVisitedObjects;
- Stringifier* firstStringifierToMark;
-
double cachedUTCOffset;
DSTOffsetCache dstOffsetCache;
@@ -255,6 +259,7 @@ namespace JSC {
#endif
void dumpRegExpTrace();
HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
+ HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
private:
JSGlobalData(GlobalDataType, ThreadStackType);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 28fc07d..a2bbfbd 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -88,21 +88,21 @@ 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());
- if (d()->debugger)
- d()->debugger->detach(this);
+ if (m_debugger)
+ m_debugger->detach(this);
Profiler** profiler = Profiler::enabledProfilerReference();
if (UNLIKELY(*profiler != 0)) {
- (*profiler)->stopProfiling(globalExec(), UString());
+ (*profiler)->stopProfiling(this);
}
-
- d()->destructor(d());
}
void JSGlobalObject::init(JSObject* thisValue)
@@ -111,14 +111,14 @@ void JSGlobalObject::init(JSObject* thisValue)
structure()->disableSpecificFunctionTracking();
- d()->globalData = Heap::heap(this)->globalData();
- d()->globalScopeChain.set(*d()->globalData, this, new (d()->globalData.get()) ScopeChainNode(0, this, d()->globalData.get(), this, thisValue));
+ m_globalData = Heap::heap(this)->globalData();
+ m_globalScopeChain.set(*m_globalData, this, new (m_globalData.get()) ScopeChainNode(0, this, m_globalData.get(), this, thisValue));
- JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
+ JSGlobalObject::globalExec()->init(0, 0, m_globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
- d()->debugger = 0;
+ m_debugger = 0;
- d()->profileGroup = 0;
+ m_profileGroup = 0;
reset(prototype());
}
@@ -177,80 +177,80 @@ void JSGlobalObject::reset(JSValue prototype)
// Prototypes
- d()->functionPrototype.set(exec->globalData(), this, new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull()))); // The real prototype will be set once ObjectPrototype is created.
- d()->functionStructure = JSFunction::createStructure(d()->functionPrototype.get());
- d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype.get());
+ 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());
JSFunction* callFunction = 0;
JSFunction* applyFunction = 0;
- d()->functionPrototype->addFunctionProperties(exec, this, d()->functionStructure.get(), &callFunction, &applyFunction);
- d()->callFunction.set(exec->globalData(), this, callFunction);
- d()->applyFunction.set(exec->globalData(), this, applyFunction);
- d()->objectPrototype.set(exec->globalData(), this, new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(jsNull()), d()->functionStructure.get()));
- d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype.get());
+ 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());
- d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
+ m_emptyObjectStructure = m_objectPrototype->inheritorID(exec->globalData());
- d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype.get());
- d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype.get());
- d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype.get());
- d()->callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(d()->objectPrototype.get());
+ 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());
- d()->arrayPrototype.set(exec->globalData(), this, new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(d()->objectPrototype.get())));
- d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype.get());
- d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype.get());
+ 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());
- d()->stringPrototype.set(exec->globalData(), this, new (exec) StringPrototype(exec, this, StringPrototype::createStructure(d()->objectPrototype.get())));
- d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype.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());
- d()->booleanPrototype.set(exec->globalData(), this, new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype.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());
- d()->numberPrototype.set(exec->globalData(), this, new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype.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());
- d()->datePrototype.set(exec->globalData(), this, new (exec) DatePrototype(exec, this, DatePrototype::createStructure(d()->objectPrototype.get())));
- d()->dateStructure = DateInstance::createStructure(d()->datePrototype.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());
- d()->regExpPrototype.set(exec->globalData(), this, new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get()));
- d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype.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());
- d()->methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
+ m_methodCallDummy.set(exec->globalData(), this, constructEmptyObject(exec));
- ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(d()->objectPrototype.get()), d()->functionStructure.get());
- d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
+ ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(exec->globalData(), m_objectPrototype.get()), m_functionStructure.get());
+ m_errorStructure = ErrorInstance::createStructure(exec->globalData(), errorPrototype);
// Constructors
- JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(d()->functionPrototype.get()), d()->objectPrototype.get());
- JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(d()->functionPrototype.get()), d()->functionPrototype.get());
- JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(d()->functionPrototype.get()), d()->arrayPrototype.get(), d()->functionStructure.get());
- JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(d()->functionPrototype.get()), d()->functionStructure.get(), d()->stringPrototype.get());
- JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(d()->functionPrototype.get()), d()->booleanPrototype.get());
- JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(d()->functionPrototype.get()), d()->numberPrototype.get());
- JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(d()->functionPrototype.get()), d()->functionStructure.get(), d()->datePrototype.get());
-
- d()->regExpConstructor.set(exec->globalData(), this, new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(d()->functionPrototype.get()), d()->regExpPrototype.get()));
-
- d()->errorConstructor.set(exec->globalData(), this, new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(d()->functionPrototype.get()), errorPrototype));
-
- RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
- RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype.get());
- d()->evalErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"));
- d()->rangeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"));
- d()->referenceErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"));
- d()->syntaxErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"));
- d()->typeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"));
- d()->URIErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"));
-
- d()->objectPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
- d()->functionPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
- d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
- d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
- d()->stringPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
- d()->numberPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
- d()->datePrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
- d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->regExpConstructor.get(), DontEnum);
- errorPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, d()->errorConstructor.get(), DontEnum);
+ JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_objectPrototype.get());
+ JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionPrototype.get());
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_arrayPrototype.get(), m_functionStructure.get());
+ JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionStructure.get(), m_stringPrototype.get());
+ JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_booleanPrototype.get());
+ JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_numberPrototype.get());
+ JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_functionStructure.get(), m_datePrototype.get());
+
+ m_regExpConstructor.set(exec->globalData(), this, new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(exec->globalData(), m_functionPrototype.get()), m_regExpPrototype.get()));
+
+ 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());
+ 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"));
+ m_syntaxErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"));
+ m_typeErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"));
+ m_URIErrorConstructor.set(exec->globalData(), this, new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"));
+
+ m_objectPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
+ m_functionPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
+ m_arrayPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
+ m_booleanPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
+ m_stringPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
+ m_numberPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
+ m_datePrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
+ m_regExpPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum);
+ errorPrototype->putDirectFunctionWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum);
// Set global constructors
@@ -263,42 +263,42 @@ void JSGlobalObject::reset(JSValue prototype)
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "String"), stringConstructor, DontEnum);
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Number"), numberConstructor, DontEnum);
putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Date"), dateConstructor, DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), d()->regExpConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Error"), d()->errorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), d()->evalErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), d()->rangeErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), d()->typeErrorConstructor.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), d()->URIErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), m_regExpConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "Error"), m_errorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), m_evalErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), m_rangeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), m_referenceErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), m_syntaxErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), m_typeErrorConstructor.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum);
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete),
GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(d()->objectPrototype.get())), DontEnum | DontDelete)
+ GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(exec->globalData(), m_objectPrototype.get())), DontEnum | DontDelete)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
// Set global functions.
- d()->evalFunction.set(exec->globalData(), this, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, exec->propertyNames().eval, globalFuncEval));
- putDirectFunctionWithoutTransition(exec, d()->evalFunction.get(), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+ m_evalFunction.set(exec->globalData(), this, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, exec->propertyNames().eval, globalFuncEval));
+ putDirectFunctionWithoutTransition(exec, m_evalFunction.get(), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
#ifndef NDEBUG
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, d()->functionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, this, m_functionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
#endif
resetPrototype(prototype);
@@ -310,7 +310,7 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
setPrototype(prototype);
JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
- JSObject* objectPrototype = d()->objectPrototype.get();
+ JSObject* objectPrototype = m_objectPrototype.get();
if (oldLastInPrototypeChain != objectPrototype)
oldLastInPrototypeChain->setPrototype(objectPrototype);
}
@@ -318,67 +318,63 @@ void JSGlobalObject::resetPrototype(JSValue prototype)
void JSGlobalObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
-
- markIfNeeded(markStack, &d()->globalScopeChain);
-
- markIfNeeded(markStack, &d()->regExpConstructor);
- markIfNeeded(markStack, &d()->errorConstructor);
- markIfNeeded(markStack, &d()->evalErrorConstructor);
- markIfNeeded(markStack, &d()->rangeErrorConstructor);
- markIfNeeded(markStack, &d()->referenceErrorConstructor);
- markIfNeeded(markStack, &d()->syntaxErrorConstructor);
- markIfNeeded(markStack, &d()->typeErrorConstructor);
- markIfNeeded(markStack, &d()->URIErrorConstructor);
-
- markIfNeeded(markStack, &d()->evalFunction);
- markIfNeeded(markStack, &d()->callFunction);
- markIfNeeded(markStack, &d()->applyFunction);
-
- markIfNeeded(markStack, &d()->objectPrototype);
- markIfNeeded(markStack, &d()->functionPrototype);
- markIfNeeded(markStack, &d()->arrayPrototype);
- markIfNeeded(markStack, &d()->booleanPrototype);
- markIfNeeded(markStack, &d()->stringPrototype);
- markIfNeeded(markStack, &d()->numberPrototype);
- markIfNeeded(markStack, &d()->datePrototype);
- markIfNeeded(markStack, &d()->regExpPrototype);
-
- markIfNeeded(markStack, &d()->methodCallDummy);
-
- markIfNeeded(markStack, d()->errorStructure);
- markIfNeeded(markStack, d()->argumentsStructure);
- markIfNeeded(markStack, d()->arrayStructure);
- markIfNeeded(markStack, d()->booleanObjectStructure);
- markIfNeeded(markStack, d()->callbackConstructorStructure);
- markIfNeeded(markStack, d()->callbackFunctionStructure);
- markIfNeeded(markStack, d()->callbackObjectStructure);
- markIfNeeded(markStack, d()->dateStructure);
- markIfNeeded(markStack, d()->emptyObjectStructure);
- markIfNeeded(markStack, d()->errorStructure);
- markIfNeeded(markStack, d()->functionStructure);
- markIfNeeded(markStack, d()->numberObjectStructure);
- markIfNeeded(markStack, d()->regExpMatchesArrayStructure);
- markIfNeeded(markStack, d()->regExpStructure);
- markIfNeeded(markStack, d()->stringObjectStructure);
-
- // No need to mark the other structures, because their prototypes are all
- // guaranteed to be referenced elsewhere.
-
- if (d()->registerArray) {
+
+ markIfNeeded(markStack, &m_globalScopeChain);
+ markIfNeeded(markStack, &m_methodCallDummy);
+
+ markIfNeeded(markStack, &m_regExpConstructor);
+ markIfNeeded(markStack, &m_errorConstructor);
+ markIfNeeded(markStack, &m_evalErrorConstructor);
+ markIfNeeded(markStack, &m_rangeErrorConstructor);
+ markIfNeeded(markStack, &m_referenceErrorConstructor);
+ markIfNeeded(markStack, &m_syntaxErrorConstructor);
+ markIfNeeded(markStack, &m_typeErrorConstructor);
+ markIfNeeded(markStack, &m_URIErrorConstructor);
+
+ markIfNeeded(markStack, &m_evalFunction);
+ markIfNeeded(markStack, &m_callFunction);
+ markIfNeeded(markStack, &m_applyFunction);
+
+ markIfNeeded(markStack, &m_objectPrototype);
+ markIfNeeded(markStack, &m_functionPrototype);
+ markIfNeeded(markStack, &m_arrayPrototype);
+ markIfNeeded(markStack, &m_booleanPrototype);
+ markIfNeeded(markStack, &m_stringPrototype);
+ markIfNeeded(markStack, &m_numberPrototype);
+ 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);
+
+ if (m_registerArray) {
// Outside the execution of global code, when our variables are torn off,
// we can mark the torn-off array.
- markStack.appendValues(d()->registerArray.get(), d()->registerArraySize);
- } else if (d()->registers) {
+ markStack.appendValues(m_registerArray.get(), m_registerArraySize);
+ } else if (m_registers) {
// During execution of global code, when our variables are in the register file,
// the symbol table tells us how many variables there are, and registers
// points to where they end, and the registers used for execution begin.
- markStack.appendValues(d()->registers - symbolTable().size(), symbolTable().size());
+ markStack.appendValues(m_registers - symbolTable().size(), symbolTable().size());
}
}
ExecState* JSGlobalObject::globalExec()
{
- return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
+ return CallFrame::create(m_globalCallFrame + RegisterFile::CallFrameHeaderSize);
}
bool JSGlobalObject::isDynamicScope(bool&) const
@@ -388,12 +384,12 @@ bool JSGlobalObject::isDynamicScope(bool&) const
void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
{
- ASSERT(!d()->registerArray);
- ASSERT(!d()->registerArraySize);
+ ASSERT(!m_registerArray);
+ ASSERT(!m_registerArraySize);
int numGlobals = registerFile.numGlobals();
if (!numGlobals) {
- d()->registers = 0;
+ m_registers = 0;
return;
}
@@ -411,24 +407,24 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
registerFile.setGlobalObject(this);
registerFile.setNumGlobals(symbolTable().size());
- if (d()->registerArray) {
+ if (m_registerArray) {
// The register file is always a gc root so no barrier is needed here
- memcpy(registerFile.start() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(WriteBarrier<Unknown>));
+ memcpy(registerFile.start() - m_registerArraySize, m_registerArray.get(), m_registerArraySize * sizeof(WriteBarrier<Unknown>));
setRegisters(reinterpret_cast<WriteBarrier<Unknown>*>(registerFile.start()), nullptr, 0);
}
}
void JSGlobalObject::resizeRegisters(int oldSize, int newSize)
{
- ASSERT(symbolTable().size() == newSize);
+ ASSERT(oldSize <= newSize);
if (newSize == oldSize)
return;
ASSERT(newSize && newSize > oldSize);
- if (d()->registerArray || !d()->registers) {
- ASSERT(static_cast<size_t>(oldSize) == d()->registerArraySize);
+ if (m_registerArray || !m_registers) {
+ ASSERT(static_cast<size_t>(oldSize) == m_registerArraySize);
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[newSize]);
for (int i = 0; i < oldSize; i++)
- registerArray[newSize - oldSize + i].set(globalData(), this, d()->registerArray[i].get());
+ registerArray[newSize - oldSize + i].set(globalData(), this, m_registerArray[i].get());
WriteBarrier<Unknown>* registers = registerArray.get() + newSize;
setRegisters(registers, registerArray.release(), newSize);
} else {
@@ -437,7 +433,7 @@ void JSGlobalObject::resizeRegisters(int oldSize, int newSize)
}
for (int i = -newSize; i < -oldSize; ++i)
- d()->registers[i].setUndefined();
+ m_registers[i].setUndefined();
}
void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
@@ -445,26 +441,21 @@ void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
return globalData->heap.allocate(size);
}
-void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData)
-{
- delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData);
-}
-
-DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
- : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+DynamicGlobalObjectScope::DynamicGlobalObjectScope(JSGlobalData& globalData, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(globalData.dynamicGlobalObject)
, m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
{
if (!m_dynamicGlobalObjectSlot) {
#if ENABLE(ASSEMBLER)
if (ExecutableAllocator::underMemoryPressure())
- callFrame->globalData().recompileAllJSFunctions();
+ globalData.recompileAllJSFunctions();
#endif
m_dynamicGlobalObjectSlot = dynamicGlobalObject;
// Reset the date cache between JS invocations to force the VM
// to observe time zone changes.
- callFrame->globalData().resetDateCache();
+ globalData.resetDateCache();
}
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 03b39fc..04f63eb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -28,6 +28,7 @@
#include "JSWeakObjectMapRefInternal.h"
#include "NumberPrototype.h"
#include "StringPrototype.h"
+#include "StructureChain.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/RandomNumber.h>
@@ -54,92 +55,70 @@ namespace JSC {
class JSGlobalObject : public JSVariableObject {
protected:
- using JSVariableObject::JSVariableObjectData;
typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
- struct JSGlobalObjectData : public JSVariableObjectData {
- // We use an explicit destructor function pointer instead of a
- // virtual destructor because we want to avoid adding a vtable
- // pointer to this struct. Adding a vtable pointer would force the
- // compiler to emit costly pointer fixup code when casting from
- // JSVariableObjectData* to JSGlobalObjectData*.
- typedef void (*Destructor)(void*);
-
- JSGlobalObjectData(Destructor destructor)
- : JSVariableObjectData(&symbolTable, 0)
- , destructor(destructor)
- , registerArraySize(0)
- , globalScopeChain()
- , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
- {
- }
-
- Destructor destructor;
-
- size_t registerArraySize;
-
- JSGlobalObject* next;
- JSGlobalObject* prev;
-
- Debugger* debugger;
-
- WriteBarrier<ScopeChainNode> globalScopeChain;
- Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
-
- WriteBarrier<RegExpConstructor> regExpConstructor;
- WriteBarrier<ErrorConstructor> errorConstructor;
- WriteBarrier<NativeErrorConstructor> evalErrorConstructor;
- WriteBarrier<NativeErrorConstructor> rangeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> referenceErrorConstructor;
- WriteBarrier<NativeErrorConstructor> syntaxErrorConstructor;
- WriteBarrier<NativeErrorConstructor> typeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> URIErrorConstructor;
-
- WriteBarrier<JSFunction> evalFunction;
- WriteBarrier<JSFunction> callFunction;
- WriteBarrier<JSFunction> applyFunction;
-
- WriteBarrier<ObjectPrototype> objectPrototype;
- WriteBarrier<FunctionPrototype> functionPrototype;
- WriteBarrier<ArrayPrototype> arrayPrototype;
- WriteBarrier<BooleanPrototype> booleanPrototype;
- WriteBarrier<StringPrototype> stringPrototype;
- WriteBarrier<NumberPrototype> numberPrototype;
- WriteBarrier<DatePrototype> datePrototype;
- WriteBarrier<RegExpPrototype> regExpPrototype;
-
- WriteBarrier<JSObject> methodCallDummy;
-
- RefPtr<Structure> argumentsStructure;
- RefPtr<Structure> arrayStructure;
- RefPtr<Structure> booleanObjectStructure;
- RefPtr<Structure> callbackConstructorStructure;
- RefPtr<Structure> callbackFunctionStructure;
- RefPtr<Structure> callbackObjectStructure;
- RefPtr<Structure> dateStructure;
- RefPtr<Structure> emptyObjectStructure;
- RefPtr<Structure> errorStructure;
- RefPtr<Structure> functionStructure;
- RefPtr<Structure> numberObjectStructure;
- RefPtr<Structure> regExpMatchesArrayStructure;
- RefPtr<Structure> regExpStructure;
- RefPtr<Structure> stringObjectStructure;
- RefPtr<Structure> internalFunctionStructure;
-
- SymbolTable symbolTable;
- unsigned profileGroup;
-
- RefPtr<JSGlobalData> globalData;
-
- WeakMapSet weakMaps;
- WeakRandom weakRandom;
- };
+ RefPtr<JSGlobalData> m_globalData;
+
+ size_t m_registerArraySize;
+ Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
+
+ WriteBarrier<ScopeChainNode> m_globalScopeChain;
+ WriteBarrier<JSObject> m_methodCallDummy;
+
+ WriteBarrier<RegExpConstructor> m_regExpConstructor;
+ WriteBarrier<ErrorConstructor> m_errorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
+
+ WriteBarrier<JSFunction> m_evalFunction;
+ WriteBarrier<JSFunction> m_callFunction;
+ WriteBarrier<JSFunction> m_applyFunction;
+
+ WriteBarrier<ObjectPrototype> m_objectPrototype;
+ WriteBarrier<FunctionPrototype> m_functionPrototype;
+ WriteBarrier<ArrayPrototype> m_arrayPrototype;
+ WriteBarrier<BooleanPrototype> m_booleanPrototype;
+ WriteBarrier<StringPrototype> m_stringPrototype;
+ WriteBarrier<NumberPrototype> m_numberPrototype;
+ 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;
+
+ unsigned m_profileGroup;
+ Debugger* m_debugger;
+
+ WeakMapSet m_weakMaps;
+ WeakRandom m_weakRandom;
+
+ SymbolTable m_symbolTable;
public:
void* operator new(size_t, JSGlobalData*);
- explicit JSGlobalObject()
- : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
+ explicit JSGlobalObject(JSGlobalData& globalData)
+ : JSVariableObject(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)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -147,7 +126,10 @@ namespace JSC {
}
explicit JSGlobalObject(NonNullPassRefPtr<Structure> structure)
- : JSVariableObject(structure, new JSGlobalObjectData(destroyJSGlobalObjectData))
+ : JSVariableObject(structure, &m_symbolTable, 0)
+ , m_registerArraySize(0)
+ , m_globalScopeChain()
+ , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -155,8 +137,11 @@ namespace JSC {
}
protected:
- JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
- : JSVariableObject(structure, data)
+ JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSObject* thisValue)
+ : JSVariableObject(structure, &m_symbolTable, 0)
+ , m_registerArraySize(0)
+ , m_globalScopeChain()
+ , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
@@ -184,55 +169,57 @@ namespace JSC {
// The following accessors return pristine values, even if a script
// replaces the global object's associated property.
- RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor.get(); }
-
- ErrorConstructor* errorConstructor() const { return d()->errorConstructor.get(); }
- NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor.get(); }
- NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor.get(); }
- NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor.get(); }
- NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor.get(); }
- NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor.get(); }
- NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor.get(); }
-
- JSFunction* evalFunction() const { return d()->evalFunction.get(); }
-
- ObjectPrototype* objectPrototype() const { return d()->objectPrototype.get(); }
- FunctionPrototype* functionPrototype() const { return d()->functionPrototype.get(); }
- ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype.get(); }
- BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype.get(); }
- StringPrototype* stringPrototype() const { return d()->stringPrototype.get(); }
- NumberPrototype* numberPrototype() const { return d()->numberPrototype.get(); }
- DatePrototype* datePrototype() const { return d()->datePrototype.get(); }
- RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype.get(); }
-
- JSObject* methodCallDummy() const { return d()->methodCallDummy.get(); }
-
- Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
- Structure* arrayStructure() const { return d()->arrayStructure.get(); }
- Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
- Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
- Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
- Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
- Structure* dateStructure() const { return d()->dateStructure.get(); }
- Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
- Structure* errorStructure() const { return d()->errorStructure.get(); }
- Structure* functionStructure() const { return d()->functionStructure.get(); }
- Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
- Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); }
- Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
- Structure* regExpStructure() const { return d()->regExpStructure.get(); }
- Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
-
- void setProfileGroup(unsigned value) { d()->profileGroup = value; }
- unsigned profileGroup() const { return d()->profileGroup; }
-
- Debugger* debugger() const { return d()->debugger; }
- void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
+ RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
+
+ ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
+ NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
+ NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
+ NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
+ NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
+ NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
+ NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
+
+ JSFunction* evalFunction() const { return m_evalFunction.get(); }
+ JSFunction* callFunction() const { return m_callFunction.get(); }
+ JSFunction* applyFunction() const { return m_applyFunction.get(); }
+
+ ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
+ FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
+ ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
+ BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
+ StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
+ NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
+ DatePrototype* datePrototype() const { return m_datePrototype.get(); }
+ RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
+
+ JSObject* methodCallDummy() const { return m_methodCallDummy.get(); }
+
+ Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+ Structure* arrayStructure() const { return m_arrayStructure.get(); }
+ Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
+ Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
+ Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
+ Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
+ Structure* dateStructure() const { return m_dateStructure.get(); }
+ Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); }
+ Structure* errorStructure() const { return m_errorStructure.get(); }
+ Structure* functionStructure() const { return m_functionStructure.get(); }
+ Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
+ Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
+ Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
+ Structure* regExpStructure() const { return m_regExpStructure.get(); }
+ Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+
+ void setProfileGroup(unsigned value) { m_profileGroup = value; }
+ unsigned profileGroup() const { return m_profileGroup; }
+
+ Debugger* debugger() const { return m_debugger; }
+ void setDebugger(Debugger* debugger) { m_debugger = debugger; }
virtual bool supportsProfiling() const { return false; }
virtual bool supportsRichSourceInfo() const { return true; }
- ScopeChainNode* globalScopeChain() { return d()->globalScopeChain.get(); }
+ ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
virtual bool isGlobalObject() const { return true; }
@@ -250,25 +237,24 @@ namespace JSC {
void resetPrototype(JSValue prototype);
- JSGlobalData& globalData() const { return *d()->globalData.get(); }
- JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
+ JSGlobalData& globalData() const { return *m_globalData.get(); }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
void registerWeakMap(OpaqueJSWeakObjectMap* map)
{
- d()->weakMaps.add(map);
+ m_weakMaps.add(map);
}
void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
{
- d()->weakMaps.remove(map);
+ m_weakMaps.remove(map);
}
- double weakRandomNumber() { return d()->weakRandom.get(); }
+ double weakRandomNumber() { return m_weakRandom.get(); }
protected:
static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1;
@@ -289,8 +275,6 @@ namespace JSC {
void addStaticGlobals(GlobalPropertyInfo*, int count);
private:
- static void destroyJSGlobalObjectData(void*);
-
// FIXME: Fold reset into init.
void init(JSObject* thisValue);
void reset(JSValue prototype);
@@ -311,17 +295,17 @@ namespace JSC {
inline void JSGlobalObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count)
{
JSVariableObject::setRegisters(registers, registerArray);
- d()->registerArraySize = count;
+ m_registerArraySize = count;
}
inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
{
- size_t oldSize = d()->registerArraySize;
+ size_t oldSize = m_registerArraySize;
size_t newSize = oldSize + count;
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[newSize]);
- if (d()->registerArray) {
+ if (m_registerArray) {
// memcpy is safe here as we're copying barriers we already own from the existing array
- memcpy(registerArray.get() + count, d()->registerArray.get(), oldSize * sizeof(Register));
+ memcpy(registerArray.get() + count, m_registerArray.get(), oldSize * sizeof(Register));
}
WriteBarrier<Unknown>* registers = registerArray.get() + newSize;
@@ -379,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(prototype.isNull() ? 0 : asObject(prototype)->structure());
+ m_cachedPrototypeChain = StructureChain::create(exec->globalData(), prototype.isNull() ? 0 : asObject(prototype)->structure());
}
return m_cachedPrototypeChain.get();
}
@@ -451,7 +435,7 @@ namespace JSC {
class DynamicGlobalObjectScope {
WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
public:
- DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject);
+ DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
~DynamicGlobalObjectScope()
{
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index de1300a..f0da773 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -449,12 +449,12 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
if (JSValue parsedObject = preparser.tryLiteralParse())
return JSValue::encode(parsedObject);
- RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false);
+ EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false);
JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain());
if (error)
return throwVMError(exec, error);
- return JSValue::encode(exec->interpreter()->execute(eval.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain()));
+ return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain()));
}
EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp
index 64dcb08..fc543f0 100644
--- a/Source/JavaScriptCore/runtime/JSLock.cpp
+++ b/Source/JavaScriptCore/runtime/JSLock.cpp
@@ -23,6 +23,7 @@
#include "Heap.h"
#include "CallFrame.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#if USE(PTHREADS)
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
index e01b401..1115dc0 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -67,7 +67,7 @@ UString JSNotAnObject::toString(ExecState* exec) const
return "";
}
-JSObject* JSNotAnObject::toObject(ExecState* exec) const
+JSObject* JSNotAnObject::toObject(ExecState* exec, JSGlobalObject*) const
{
ASSERT_UNUSED(exec, exec->hadException());
return const_cast<JSNotAnObject*>(this);
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.h b/Source/JavaScriptCore/runtime/JSNotAnObject.h
index 7e70a98..75bca18 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.h
@@ -43,9 +43,9 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
@@ -58,7 +58,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
// JSObject methods
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
diff --git a/Source/JavaScriptCore/runtime/JSNumberCell.cpp b/Source/JavaScriptCore/runtime/JSNumberCell.cpp
index 3172cc9..79f2d2a 100644
--- a/Source/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "JSNumberCell.h"
+#include "JSObject.h"
#include "ScopeChain.h"
// Keep our exported symbols lists happy.
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index 7d18e08..8fc7ac9 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -32,6 +32,8 @@
#include "JSArray.h"
#include "JSGlobalObject.h"
#include "LiteralParser.h"
+#include "Local.h"
+#include "LocalScope.h"
#include "Lookup.h"
#include "PropertyNameArray.h"
#include "UStringBuilder.h"
@@ -74,24 +76,22 @@ private:
class Stringifier {
WTF_MAKE_NONCOPYABLE(Stringifier);
public:
- Stringifier(ExecState*, JSValue replacer, JSValue space);
- ~Stringifier();
- JSValue stringify(JSValue);
+ Stringifier(ExecState*, const Local<Unknown>& replacer, const Local<Unknown>& space);
+ Local<Unknown> stringify(Handle<Unknown>);
void markAggregate(MarkStack&);
private:
class Holder {
public:
- Holder(JSObject*);
+ Holder(JSGlobalData&, JSObject*);
JSObject* object() const { return m_object.get(); }
- DeprecatedPtr<JSObject>* objectSlot() { return &m_object; }
bool appendNextProperty(Stringifier&, UStringBuilder&);
private:
- DeprecatedPtr<JSObject> m_object;
+ Local<JSObject> m_object;
const bool m_isArray;
bool m_isJSArray;
unsigned m_index;
@@ -113,16 +113,14 @@ private:
void unindent();
void startNewLine(UStringBuilder&) const;
- Stringifier* const m_nextStringifierToMark;
ExecState* const m_exec;
- const JSValue m_replacer;
+ const Local<Unknown> m_replacer;
bool m_usingArrayReplacer;
PropertyNameArray m_arrayReplacerPropertyNames;
CallType m_replacerCallType;
CallData m_replacerCallData;
const UString m_gap;
- HashSet<JSObject*> m_holderCycleDetector;
Vector<Holder, 16> m_holderStack;
UString m_repeatedGap;
UString m_indent;
@@ -199,23 +197,20 @@ JSValue PropertyNameForFunctionCall::value(ExecState* exec) const
// ------------------------------ Stringifier --------------------------------
-Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
- : m_nextStringifierToMark(exec->globalData().firstStringifierToMark)
- , m_exec(exec)
+Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const Local<Unknown>& space)
+ : m_exec(exec)
, m_replacer(replacer)
, m_usingArrayReplacer(false)
, m_arrayReplacerPropertyNames(exec)
, m_replacerCallType(CallTypeNone)
- , m_gap(gap(exec, space))
+ , m_gap(gap(exec, space.get()))
{
- exec->globalData().firstStringifierToMark = this;
-
if (!m_replacer.isObject())
return;
- if (asObject(m_replacer)->inherits(&JSArray::s_info)) {
+ if (m_replacer.asObject()->inherits(&JSArray::s_info)) {
m_usingArrayReplacer = true;
- JSObject* array = asObject(m_replacer);
+ Handle<JSObject> array = m_replacer.asObject();
unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
for (unsigned i = 0; i < length; ++i) {
JSValue name = array->get(exec, i);
@@ -246,40 +241,25 @@ Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
return;
}
- m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData);
-}
-
-Stringifier::~Stringifier()
-{
- ASSERT(m_exec->globalData().firstStringifierToMark == this);
- m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark;
-}
-
-void Stringifier::markAggregate(MarkStack& markStack)
-{
- for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) {
- size_t size = m_holderStack.size();
- for (size_t i = 0; i < size; ++i)
- markStack.append(m_holderStack[i].objectSlot());
- }
+ m_replacerCallType = m_replacer.asObject()->getCallData(m_replacerCallData);
}
-JSValue Stringifier::stringify(JSValue value)
+Local<Unknown> Stringifier::stringify(Handle<Unknown> value)
{
JSObject* object = constructEmptyObject(m_exec);
if (m_exec->hadException())
- return jsNull();
+ return Local<Unknown>(m_exec->globalData(), jsNull());
PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
- object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value);
+ object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get());
UStringBuilder result;
- if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
- return jsUndefined();
+ if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded)
+ return Local<Unknown>(m_exec->globalData(), jsUndefined());
if (m_exec->hadException())
- return jsNull();
+ return Local<Unknown>(m_exec->globalData(), jsNull());
- return jsString(m_exec, result.toUString());
+ return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toUString()));
}
void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value)
@@ -372,7 +352,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
if (m_replacerCallType != CallTypeNone) {
JSValue list[] = { propertyName.value(m_exec), value };
ArgList args(list, WTF_ARRAY_LENGTH(list));
- value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder, args);
+ value = call(m_exec, m_replacer.get(), m_replacerCallType, m_replacerCallData, holder, args);
if (m_exec->hadException())
return StringifyFailed;
}
@@ -425,12 +405,14 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
}
// Handle cycle detection, and put the holder on the stack.
- if (!m_holderCycleDetector.add(object).second) {
- throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures."));
- return StringifyFailed;
+ for (unsigned i = 0; i < m_holderStack.size(); i++) {
+ if (m_holderStack[i].object() == object) {
+ throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures."));
+ return StringifyFailed;
+ }
}
bool holderStackWasEmpty = m_holderStack.isEmpty();
- m_holderStack.append(object);
+ m_holderStack.append(Holder(m_exec->globalData(), object));
if (!holderStackWasEmpty)
return StringifySucceeded;
@@ -450,7 +432,6 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder&
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
}
- m_holderCycleDetector.remove(m_holderStack.last().object());
m_holderStack.removeLast();
} while (!m_holderStack.isEmpty());
return StringifySucceeded;
@@ -485,8 +466,8 @@ inline void Stringifier::startNewLine(UStringBuilder& builder) const
builder.append(m_indent);
}
-inline Stringifier::Holder::Holder(JSObject* object)
- : m_object(object)
+inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object)
+ : m_object(globalData, object)
, m_isArray(object->inherits(&JSArray::s_info))
, m_index(0)
{
@@ -623,16 +604,11 @@ bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& pro
return getStaticFunctionDescriptor<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, descriptor);
}
-void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier)
-{
- stringifier->markAggregate(markStack);
-}
-
class Walker {
public:
- Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData)
+ Walker(ExecState* exec, Handle<JSObject> function, CallType callType, CallData callData)
: m_exec(exec)
- , m_function(function)
+ , m_function(exec->globalData(), function)
, m_callType(callType)
, m_callData(callData)
{
@@ -649,7 +625,7 @@ private:
friend class Holder;
ExecState* m_exec;
- DeprecatedPtr<JSObject> m_function;
+ Local<JSObject> m_function;
CallType m_callType;
CallData m_callData;
};
@@ -663,8 +639,8 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
{
Vector<PropertyNameArray, 16> propertyStack;
Vector<uint32_t, 16> indexStack;
- Vector<JSObject*, 16> objectStack;
- Vector<JSArray*, 16> arrayStack;
+ LocalStack<JSObject, 16> objectStack(m_exec->globalData());
+ LocalStack<JSArray, 16> arrayStack(m_exec->globalData());
Vector<WalkerState, 16> stateStack;
WalkerState state = StateUnknown;
@@ -684,7 +660,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
return throwError(m_exec, createStackOverflowError(m_exec));
JSArray* array = asArray(inValue);
- arrayStack.append(array);
+ arrayStack.push(array);
indexStack.append(0);
// fallthrough
}
@@ -696,11 +672,11 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
- JSArray* array = arrayStack.last();
+ JSArray* array = arrayStack.peek();
uint32_t index = indexStack.last();
if (index == array->length()) {
outValue = array;
- arrayStack.removeLast();
+ arrayStack.pop();
indexStack.removeLast();
break;
}
@@ -722,7 +698,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
// fallthrough
}
case ArrayEndVisitMember: {
- JSArray* array = arrayStack.last();
+ JSArray* array = arrayStack.peek();
JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue);
if (filteredValue.isUndefined())
array->deleteProperty(m_exec, indexStack.last());
@@ -745,7 +721,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
return throwError(m_exec, createStackOverflowError(m_exec));
JSObject* object = asObject(inValue);
- objectStack.append(object);
+ objectStack.push(object);
indexStack.append(0);
propertyStack.append(PropertyNameArray(m_exec));
object->getOwnPropertyNames(m_exec, propertyStack.last());
@@ -759,12 +735,12 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
tickCount = localTimeoutChecker.ticksUntilNextCheck();
}
- JSObject* object = objectStack.last();
+ JSObject* object = objectStack.peek();
uint32_t index = indexStack.last();
PropertyNameArray& properties = propertyStack.last();
if (index == properties.size()) {
outValue = object;
- objectStack.removeLast();
+ objectStack.pop();
indexStack.removeLast();
propertyStack.removeLast();
break;
@@ -787,7 +763,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
// fallthrough
}
case ObjectEndVisitMember: {
- JSObject* object = objectStack.last();
+ JSObject* object = objectStack.peek();
Identifier prop = propertyStack.last()[indexStack.last()];
PutPropertySlot slot;
JSValue filteredValue = callReviver(object, jsString(m_exec, prop.ustring()), outValue);
@@ -838,7 +814,8 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
UString source = value.toString(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
-
+
+ LocalScope scope(exec->globalData());
LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON);
JSValue unfiltered = jsonParser.tryLiteralParse();
if (!unfiltered)
@@ -852,7 +829,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
CallType callType = getCallData(function, callData);
if (callType == CallTypeNone)
return JSValue::encode(unfiltered);
- return JSValue::encode(Walker(exec, asObject(function), callType, callData).walk(unfiltered));
+ return JSValue::encode(Walker(exec, Local<JSObject>(exec->globalData(), asObject(function)), callType, callData).walk(unfiltered));
}
// ECMA-262 v5 15.12.3
@@ -860,15 +837,17 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec)
{
if (!exec->argumentCount())
return throwVMError(exec, createError(exec, "No input to stringify"));
- JSValue value = exec->argument(0);
- JSValue replacer = exec->argument(1);
- JSValue space = exec->argument(2);
- return JSValue::encode(Stringifier(exec, replacer, space).stringify(value));
+ LocalScope scope(exec->globalData());
+ Local<Unknown> value(exec->globalData(), exec->argument(0));
+ Local<Unknown> replacer(exec->globalData(), exec->argument(1));
+ Local<Unknown> space(exec->globalData(), exec->argument(2));
+ return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get());
}
UString JSONStringify(ExecState* exec, JSValue value, unsigned indent)
{
- JSValue result = Stringifier(exec, jsNull(), jsNumber(indent)).stringify(value);
+ LocalScope scope(exec->globalData());
+ Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->globalData(), jsNull()), Local<Unknown>(exec->globalData(), jsNumber(indent))).stringify(Local<Unknown>(exec->globalData(), value));
if (result.isUndefinedOrNull())
return UString();
return result.getString(exec);
diff --git a/Source/JavaScriptCore/runtime/JSONObject.h b/Source/JavaScriptCore/runtime/JSONObject.h
index acffeca..a52c543 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.h
+++ b/Source/JavaScriptCore/runtime/JSONObject.h
@@ -36,13 +36,11 @@ namespace JSC {
public:
JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- static void markStringifiers(MarkStack&, Stringifier*);
-
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 87fbb67..b307540 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -43,7 +43,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSObject);
ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
-ASSERT_CLASS_FILLS_CELL(JSFinalObject);
+ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
@@ -489,7 +489,7 @@ UString JSObject::toString(ExecState* exec) const
return primitive.toString(exec);
}
-JSObject* JSObject::toObject(ExecState*) const
+JSObject* JSObject::toObject(ExecState*, JSGlobalObject*) const
{
return const_cast<JSObject*>(this);
}
@@ -572,9 +572,9 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, WriteBarr
slot.setUndefined();
}
-Structure* JSObject::createInheritorID()
+Structure* JSObject::createInheritorID(JSGlobalData& globalData)
{
- m_inheritorID = createEmptyObjectStructure(this);
+ m_inheritorID = createEmptyObjectStructure(globalData, this);
return m_inheritorID.get();
}
@@ -743,12 +743,12 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
// Changing the accessor functions of an existing accessor property
ASSERT(descriptor.isAccessorDescriptor());
if (!current.configurable()) {
- if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
+ if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
if (throwException)
throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property."));
return false;
}
- if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
+ if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
if (throwException)
throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property."));
return false;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 2b4db43..578b3cf 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -92,7 +92,7 @@ namespace JSC {
bool setPrototypeWithCycleCheck(JSValue prototype);
void setStructure(NonNullPassRefPtr<Structure>);
- Structure* inheritorID();
+ Structure* inheritorID(JSGlobalData&);
virtual UString className() const;
@@ -138,7 +138,7 @@ namespace JSC {
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
virtual JSObject* toThisObject(ExecState*) const;
virtual JSValue toStrictThisObject(ExecState*) const;
@@ -250,9 +250,9 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const unsigned StructureFlags = 0;
@@ -296,7 +296,7 @@ namespace JSC {
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
- Structure* createInheritorID();
+ Structure* createInheritorID(JSGlobalData&);
PropertyStorage m_propertyStorage;
RefPtr<Structure> m_inheritorID;
@@ -320,9 +320,9 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
friend class JSObject;
public:
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
@@ -348,9 +348,9 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
return new (exec) JSFinalObject(structure);
}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
private:
@@ -377,9 +377,9 @@ inline JSObject* constructEmptyObject(ExecState* exec, NonNullPassRefPtr<Structu
return JSFinalObject::create(exec, structure);
}
-inline PassRefPtr<Structure> createEmptyObjectStructure(JSValue prototype)
+inline PassRefPtr<Structure> createEmptyObjectStructure(JSGlobalData& globalData, JSValue prototype)
{
- return JSFinalObject::createStructure(prototype);
+ return JSFinalObject::createStructure(globalData, prototype);
}
inline JSObject* asObject(JSCell* cell)
@@ -442,11 +442,11 @@ inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure)
m_structure = structure.leakRef(); // ~JSObject balances this ref()
}
-inline Structure* JSObject::inheritorID()
+inline Structure* JSObject::inheritorID(JSGlobalData& globalData)
{
if (m_inheritorID)
return m_inheritorID.get();
- return createInheritorID();
+ return createInheritorID(globalData);
}
inline bool Structure::isUsingInlineStorage() const
@@ -814,8 +814,10 @@ 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);
@@ -840,6 +842,20 @@ inline JSValue JSValue::toStrictThisObject(ExecState* exec) const
return asObject(asCell())->toStrictThisObject(exec);
}
+ALWAYS_INLINE JSObject* Register::function() const
+{
+ if (!jsValue())
+ return 0;
+ return asObject(jsValue());
+}
+
+ALWAYS_INLINE Register Register::withCallee(JSObject* callee)
+{
+ Register r;
+ r = JSValue(callee);
+ return r;
+}
+
} // namespace JSC
#endif // JSObject_h
diff --git a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
index c5e3047..8380514 100644
--- a/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h
@@ -34,9 +34,9 @@ class JSGlobalObject;
class JSObjectWithGlobalObject : public JSNonFinalObject {
public:
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
JSGlobalObject* globalObject() const;
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 0d759cf..6f31f99 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -77,7 +77,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
return jsPropertyNameIterator;
}
- jsPropertyNameIterator->setCachedPrototypeChain(structureChain);
+ jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain);
jsPropertyNameIterator->setCachedStructure(o->structure());
o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator);
return jsPropertyNameIterator;
@@ -86,7 +86,7 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
JSValue identifier = m_jsStrings[i].get();
- if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
+ if (m_cachedStructure == base->structure() && m_cachedPrototypeChain.get() == base->structure()->prototypeChain(exec))
return identifier;
if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
@@ -97,6 +97,8 @@ JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
void JSPropertyNameIterator::markChildren(MarkStack& markStack)
{
markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
+ if (m_cachedPrototypeChain)
+ markStack.append(&m_cachedPrototypeChain);
}
#if !ASSERT_DISABLED
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index d51cba8..499396c 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(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, 0);
+ return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount, 0);
}
virtual bool isPropertyNameIterator() const { return true; }
@@ -73,7 +73,7 @@ namespace JSC {
}
Structure* cachedStructure() { return m_cachedStructure.get(); }
- void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ void setCachedPrototypeChain(JSGlobalData& globalData, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(globalData, this, cachedPrototypeChain); }
StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
private:
@@ -84,7 +84,7 @@ namespace JSC {
#endif
RefPtr<Structure> m_cachedStructure;
- RefPtr<StructureChain> m_cachedPrototypeChain;
+ WriteBarrier<StructureChain> m_cachedPrototypeChain;
uint32_t m_numCacheableSlots;
uint32_t m_jsStringsSize;
OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
@@ -106,6 +106,11 @@ namespace JSC {
return m_enumerationCache.get();
}
+ ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
+ {
+ return static_cast<JSPropertyNameIterator*>(jsValue().asCell());
+ }
+
} // namespace JSC
#endif // JSPropertyNameIterator_h
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index 727ac28..3d4dc7c 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -28,13 +28,12 @@
#include "JSStaticScopeObject.h"
namespace JSC {
-
ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
void JSStaticScopeObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
- markStack.deprecatedAppend(&d()->registerStore);
+ markStack.append(&m_registerStore);
}
JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
@@ -68,12 +67,6 @@ bool JSStaticScopeObject::isDynamicScope(bool&) const
return false;
}
-JSStaticScopeObject::~JSStaticScopeObject()
-{
- ASSERT(d());
- delete d();
-}
-
bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot)
{
return symbolTableGet(propertyName, slot);
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
index b3c0695..3e19bbc 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -31,25 +31,14 @@
namespace JSC{
class JSStaticScopeObject : public JSVariableObject {
- protected:
- using JSVariableObject::JSVariableObjectData;
- struct JSStaticScopeObjectData : public JSVariableObjectData {
- JSStaticScopeObjectData()
- : JSVariableObjectData(&symbolTable, &registerStore + 1)
- {
- }
- SymbolTable symbolTable;
- Register registerStore;
- };
-
public:
JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes)
- : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData())
+ : JSVariableObject(exec->globalData().staticScopeStructure, &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1))
{
- d()->registerStore = value;
+ m_registerStore.set(exec->globalData(), this, value);
symbolTable().add(ident.impl(), SymbolTableEntry(-1, attributes));
}
- virtual ~JSStaticScopeObject();
+
virtual void markChildren(MarkStack&);
bool isDynamicScope(bool& requiresDynamicChecks) const;
virtual JSObject* toThisObject(ExecState*) const;
@@ -58,13 +47,14 @@ namespace JSC{
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); }
+ static PassRefPtr<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;
private:
- JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
+ SymbolTable m_symbolTable;
+ WriteBarrier<Unknown> m_registerStore;
};
}
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index 848c431..d9c4d46 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -152,7 +152,7 @@ JSString* JSString::substringFromRope(ExecState* exec, unsigned substringStart,
if (substringLength == 1) {
ASSERT(substringFiberCount == 1);
UChar c = substringFibers[0].characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
if (substringFiberCount == 1)
@@ -253,19 +253,19 @@ UString JSString::toString(ExecState* exec) const
return value(exec);
}
-inline StringObject* StringObject::create(ExecState* exec, JSString* string)
+inline StringObject* StringObject::create(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
{
- return new (exec) StringObject(exec->globalData(), exec->lexicalGlobalObject()->stringObjectStructure(), string);
+ return new (exec) StringObject(exec->globalData(), globalObject->stringObjectStructure(), string);
}
-JSObject* JSString::toObject(ExecState* exec) const
+JSObject* JSString::toObject(ExecState* exec, JSGlobalObject* globalObject) const
{
- return StringObject::create(exec, const_cast<JSString*>(this));
+ return StringObject::create(exec, globalObject, const_cast<JSString*>(this));
}
JSObject* JSString::toThisObject(ExecState* exec) const
{
- return StringObject::create(exec, const_cast<JSString*>(this));
+ return StringObject::create(exec, exec->lexicalGlobalObject(), const_cast<JSString*>(this));
}
bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 3672300..9113d4a 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -349,7 +349,7 @@ namespace JSC {
JSValue replaceCharacter(ExecState*, UChar, const UString& replacement);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount, 0); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
@@ -402,7 +402,7 @@ namespace JSC {
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
+ virtual JSObject* toObject(ExecState*, JSGlobalObject*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
@@ -468,7 +468,7 @@ namespace JSC {
inline JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
{
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
}
@@ -478,7 +478,7 @@ namespace JSC {
JSGlobalData* globalData = &exec->globalData();
ASSERT(offset < static_cast<unsigned>(s.length()));
UChar c = s.characters()[offset];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, 1))));
}
@@ -513,7 +513,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (size == 1) {
UChar c = s.characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, s));
@@ -521,7 +521,7 @@ namespace JSC {
inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context)
{
- ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > 0xFF));
+ ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > maxSingleCharacterString));
JSGlobalData* globalData = &exec->globalData();
return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context));
}
@@ -548,7 +548,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (length == 1) {
UChar c = s.characters()[offset];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, length)), JSString::HasOtherOwner));
@@ -561,7 +561,7 @@ namespace JSC {
return globalData->smallStrings.emptyString(globalData);
if (size == 1) {
UChar c = s.characters()[0];
- if (c <= 0xFF)
+ if (c <= maxSingleCharacterString)
return globalData->smallStrings.singleCharacterString(globalData, c);
}
return fixupVPtr(globalData, new (globalData) JSString(globalData, s, JSString::HasOtherOwner));
diff --git a/Source/JavaScriptCore/runtime/JSTypeInfo.h b/Source/JavaScriptCore/runtime/JSTypeInfo.h
index fdcaf31..284d2b2 100644
--- a/Source/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/Source/JavaScriptCore/runtime/JSTypeInfo.h
@@ -46,7 +46,6 @@ namespace JSC {
static const unsigned IsJSFinalObject = 1 << 8;
class TypeInfo {
- friend class JIT;
public:
TypeInfo(JSType type, unsigned flags = 0)
: m_type(type)
@@ -72,6 +71,16 @@ namespace JSC {
unsigned flags() const { return m_flags; }
unsigned isFinal() const { return m_flags2 && (IsJSFinalObject >> 8); }
+ static ptrdiff_t flagsOffset()
+ {
+ return OBJECT_OFFSETOF(TypeInfo, m_flags);
+ }
+
+ static ptrdiff_t typeOffset()
+ {
+ return OBJECT_OFFSETOF(TypeInfo, m_type);
+ }
+
private:
unsigned char m_type;
unsigned char m_flags;
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index f4662db..d3ee89e 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -54,14 +54,14 @@ double JSValue::toIntegerPreserveNaN(ExecState* exec) const
return trunc(toNumber(exec));
}
-JSObject* JSValue::toObjectSlowCase(ExecState* exec) const
+JSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const
{
ASSERT(!isCell());
if (isInt32() || isDouble())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, globalObject, asValue());
if (isTrue() || isFalse())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, globalObject, asValue());
ASSERT(isUndefinedOrNull());
throwError(exec, createNotAnObjectError(exec, *this));
@@ -73,9 +73,9 @@ JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
ASSERT(!isCell());
if (isInt32() || isDouble())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
if (isTrue() || isFalse())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
ASSERT(isUndefinedOrNull());
return exec->globalThisValue();
}
@@ -84,9 +84,9 @@ JSObject* JSValue::synthesizeObject(ExecState* exec) const
{
ASSERT(!isCell());
if (isNumber())
- return constructNumber(exec, asValue());
+ return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
if (isBoolean())
- return constructBooleanFromImmediateBoolean(exec, asValue());
+ return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
ASSERT(isUndefinedOrNull());
throwError(exec, createNotAnObjectError(exec, *this));
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index b2e7a51..098123e 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -37,6 +37,7 @@ namespace JSC {
class Identifier;
class JSCell;
class JSGlobalData;
+ class JSGlobalObject;
class JSImmediate;
class JSObject;
class JSString;
@@ -52,11 +53,33 @@ namespace JSC {
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+
#if USE(JSVALUE32_64)
typedef int64_t EncodedJSValue;
#else
typedef void* EncodedJSValue;
#endif
+
+ union EncodedValueDescriptor {
+ EncodedJSValue asEncodedJSValue;
+#if USE(JSVALUE32_64)
+ double asDouble;
+#elif USE(JSVALUE64)
+ JSCell* ptr;
+#endif
+
+#if CPU(BIG_ENDIAN)
+ struct {
+ int32_t tag;
+ int32_t payload;
+ } asBits;
+#else
+ struct {
+ int32_t payload;
+ int32_t tag;
+ } asBits;
+#endif
+ };
double nonInlineNaN();
@@ -167,6 +190,7 @@ namespace JSC {
UString toString(ExecState*) const;
UString toPrimitiveString(ExecState*) const;
JSObject* toObject(ExecState*) const;
+ JSObject* toObject(ExecState*, JSGlobalObject*) const;
// Integer conversions.
double toInteger(ExecState*) const;
@@ -222,7 +246,7 @@ namespace JSC {
JSValue(HashTableDeletedValueTag);
inline const JSValue asValue() const { return *this; }
- JSObject* toObjectSlowCase(ExecState*) const;
+ JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
JSObject* toThisObjectSlowCase(ExecState*) const;
JSObject* synthesizePrototype(ExecState*) const;
@@ -239,28 +263,14 @@ namespace JSC {
enum { DeletedValueTag = 0xfffffff8 };
enum { LowestTag = DeletedValueTag };
-
+
uint32_t tag() const;
int32_t payload() const;
- union {
- EncodedJSValue asEncodedJSValue;
- double asDouble;
-#if CPU(BIG_ENDIAN)
- struct {
- int32_t tag;
- int32_t payload;
- } asBits;
-#else
- struct {
- int32_t payload;
- int32_t tag;
- } asBits;
-#endif
- } u;
-#else // USE(JSVALUE32_64)
+ EncodedValueDescriptor u;
+#elif USE(JSVALUE64)
JSCell* m_ptr;
-#endif // USE(JSVALUE32_64)
+#endif
};
#if USE(JSVALUE32_64)
@@ -392,9 +402,6 @@ namespace JSC {
{
JSValue v;
v.u.asEncodedJSValue = encodedJSValue;
-#if ENABLE(JSC_ZOMBIES)
- ASSERT(!v.isZombie());
-#endif
return v;
}
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index e94d277..891ada8 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -44,7 +44,7 @@ namespace JSC {
friend class JIT;
public:
- SymbolTable& symbolTable() const { return *d->symbolTable; }
+ SymbolTable& symbolTable() const { return *m_symbolTable; }
virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
@@ -54,39 +54,24 @@ namespace JSC {
virtual bool isVariableObject() const;
virtual bool isDynamicScope(bool& requiresDynamicChecks) const = 0;
- WriteBarrier<Unknown>& registerAt(int index) const { return d->registers[index]; }
+ WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; }
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
+
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags;
- // Subclasses of JSVariableObject can subclass this struct to add data
- // without increasing their own size (since there's a hard limit on the
- // size of a JSCell).
- struct JSVariableObjectData {
- JSVariableObjectData(SymbolTable* symbolTable, Register* registers)
- : symbolTable(symbolTable)
- , registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
- {
- ASSERT(symbolTable);
- }
-
- SymbolTable* symbolTable; // Maps name -> offset from "r" in register file.
- WriteBarrier<Unknown>* registers; // "r" in the register file.
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
-
- private:
- JSVariableObjectData(const JSVariableObjectData&);
- JSVariableObjectData& operator=(const JSVariableObjectData&);
- };
-
- JSVariableObject(NonNullPassRefPtr<Structure> structure, JSVariableObjectData* data)
+
+ JSVariableObject(NonNullPassRefPtr<Structure> structure, SymbolTable* symbolTable, Register* registers)
: JSNonFinalObject(structure)
- , d(data) // Subclass owns this pointer.
+ , m_symbolTable(symbolTable)
+ , m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
{
+ ASSERT(m_symbolTable);
COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier);
}
@@ -99,7 +84,9 @@ namespace JSC {
bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
- JSVariableObjectData* d;
+ SymbolTable* m_symbolTable; // Maps name -> offset from "r" in register file.
+ WriteBarrier<Unknown>* m_registers; // "r" in the register file.
+ OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
};
inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
@@ -161,9 +148,9 @@ namespace JSC {
inline void JSVariableObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray)
{
- ASSERT(registerArray != d->registerArray);
- d->registerArray = registerArray;
- d->registers = registers;
+ ASSERT(registerArray != m_registerArray);
+ m_registerArray = registerArray;
+ m_registers = registers;
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index 6d586df..63833e9 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -30,19 +30,19 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSNonFinalObject {
protected:
- explicit JSWrapperObject(JSGlobalData&, NonNullPassRefPtr<Structure>);
+ explicit JSWrapperObject(NonNullPassRefPtr<Structure>);
public:
- JSValue internalValue() const { return m_internalValue.get(); }
+ JSValue internalValue() const;
void setInternalValue(JSGlobalData&, JSValue);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned AnonymousSlotCount = 1 + JSObject::AnonymousSlotCount;
+ static const unsigned StructureFlags = OverridesMarkChildren | JSNonFinalObject::StructureFlags;
private:
virtual void markChildren(MarkStack&);
@@ -50,10 +50,14 @@ namespace JSC {
WriteBarrier<Unknown> m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure)
+ inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure)
: JSNonFinalObject(structure)
{
- putAnonymousValue(globalData, 0, jsNull());
+ }
+
+ inline JSValue JSWrapperObject::internalValue() const
+ {
+ return m_internalValue.get();
}
inline void JSWrapperObject::setInternalValue(JSGlobalData& globalData, JSValue value)
@@ -61,7 +65,6 @@ namespace JSC {
ASSERT(value);
ASSERT(!value.isObject());
m_internalValue.set(globalData, this, value);
- putAnonymousValue(globalData, 0, value);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSZombie.cpp b/Source/JavaScriptCore/runtime/JSZombie.cpp
index c0c5f11..23cf135 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.cpp
+++ b/Source/JavaScriptCore/runtime/JSZombie.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSZombie.h"
#include "ClassInfo.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#if ENABLE(JSC_ZOMBIES)
@@ -38,7 +39,7 @@ Structure* JSZombie::leakedZombieStructure() {
static Structure* structure = 0;
if (!structure) {
Structure::startIgnoringLeaks();
- structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0, &info).leakRef();
+ structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0, &s_info).leakRef();
Structure::stopIgnoringLeaks();
}
return structure;
diff --git a/Source/JavaScriptCore/runtime/JSZombie.h b/Source/JavaScriptCore/runtime/JSZombie.h
index 5fe6b6d..179ff53 100644
--- a/Source/JavaScriptCore/runtime/JSZombie.h
+++ b/Source/JavaScriptCore/runtime/JSZombie.h
@@ -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(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, 0), AnonymousSlotCount, &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
index 4614a7c..3e205a1 100644
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
@@ -28,6 +28,11 @@
#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)
@@ -74,12 +79,14 @@
#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
#include <signal.h>
#ifndef SA_RESTART
-#error MachineStackMarker requires SA_RESTART
+#error MachineThreads requires SA_RESTART
#endif
#endif
#endif
+using namespace WTF;
+
namespace JSC {
static inline void swapIfBackwards(void*& begin, void*& end)
@@ -113,7 +120,7 @@ static void pthreadSignalHandlerSuspendResume(int signo)
}
#endif
-class MachineStackMarker::Thread {
+class MachineThreads::Thread {
public:
Thread(pthread_t pthread, const PlatformThread& platThread, void* base)
: posixThread(pthread)
@@ -142,20 +149,20 @@ public:
#endif
-MachineStackMarker::MachineStackMarker(Heap* heap)
+MachineThreads::MachineThreads(Heap* heap)
: m_heap(heap)
#if ENABLE(JSC_MULTIPLE_THREADS)
, m_registeredThreads(0)
- , m_currentThreadRegistrar(0)
+ , m_threadSpecific(0)
#endif
{
}
-MachineStackMarker::~MachineStackMarker()
+MachineThreads::~MachineThreads()
{
#if ENABLE(JSC_MULTIPLE_THREADS)
- if (m_currentThreadRegistrar) {
- int error = pthread_key_delete(m_currentThreadRegistrar);
+ if (m_threadSpecific) {
+ int error = pthread_key_delete(m_threadSpecific);
ASSERT_UNUSED(error, !error);
}
@@ -181,24 +188,24 @@ static inline PlatformThread getCurrentPlatformThread()
#endif
}
-void MachineStackMarker::makeUsableFromMultipleThreads()
+void MachineThreads::makeUsableFromMultipleThreads()
{
- if (m_currentThreadRegistrar)
+ if (m_threadSpecific)
return;
- int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
+ int error = pthread_key_create(&m_threadSpecific, removeThread);
if (error)
CRASH();
}
-void MachineStackMarker::registerThread()
+void MachineThreads::addCurrentThread()
{
ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
- if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
+ if (!m_threadSpecific || pthread_getspecific(m_threadSpecific))
return;
- pthread_setspecific(m_currentThreadRegistrar, this);
+ pthread_setspecific(m_threadSpecific, this);
Thread* thread = new Thread(pthread_self(), getCurrentPlatformThread(), m_heap->globalData()->stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
@@ -207,13 +214,13 @@ void MachineStackMarker::registerThread()
m_registeredThreads = thread;
}
-void MachineStackMarker::unregisterThread(void* p)
+void MachineThreads::removeThread(void* p)
{
if (p)
- static_cast<MachineStackMarker*>(p)->unregisterThread();
+ static_cast<MachineThreads*>(p)->removeCurrentThread();
}
-void MachineStackMarker::unregisterThread()
+void MachineThreads::removeCurrentThread()
{
pthread_t currentPosixThread = pthread_self();
@@ -240,21 +247,13 @@ void MachineStackMarker::unregisterThread()
#endif
-void NEVER_INLINE MachineStackMarker::markCurrentThreadConservativelyInternal(ConservativeSet& conservativeSet)
-{
- void* begin = m_heap->globalData()->stack().current();
- void* end = m_heap->globalData()->stack().origin();
- swapIfBackwards(begin, end);
- conservativeSet.add(begin, end);
-}
-
#if COMPILER(GCC)
#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
#else
#define REGISTER_BUFFER_ALIGNMENT
#endif
-void MachineStackMarker::markCurrentThreadConservatively(ConservativeSet& conservativeSet)
+void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, void* stackCurrent)
{
// setjmp forces volatile registers onto the stack
jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
@@ -267,7 +266,15 @@ void MachineStackMarker::markCurrentThreadConservatively(ConservativeSet& conser
#pragma warning(pop)
#endif
- markCurrentThreadConservativelyInternal(conservativeSet);
+ 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)
@@ -431,20 +438,19 @@ static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
#endif
}
-void MachineStackMarker::markOtherThreadConservatively(ConservativeSet& conservativeSet, Thread* thread)
+void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread)
{
suspendThread(thread->platformThread);
PlatformThreadRegisters regs;
size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
- // mark the thread's registers
- conservativeSet.add(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+ 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);
- conservativeSet.add(stackPointer, stackBase);
+ conservativeRoots.add(stackPointer, stackBase);
resumeThread(thread->platformThread);
@@ -453,27 +459,27 @@ void MachineStackMarker::markOtherThreadConservatively(ConservativeSet& conserva
#endif
-void MachineStackMarker::markMachineStackConservatively(ConservativeSet& conservativeSet)
+void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, void* stackCurrent)
{
- markCurrentThreadConservatively(conservativeSet);
+ gatherFromCurrentThread(conservativeRoots, stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
- if (m_currentThreadRegistrar) {
+ if (m_threadSpecific) {
MutexLocker lock(m_registeredThreadsMutex);
#ifndef NDEBUG
- // Forbid malloc during the mark phase. Marking a thread suspends it, so
- // a malloc inside markChildren() would risk a deadlock with a thread that had been
- // suspended while holding the malloc lock.
+ // 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()))
- markOtherThreadConservatively(conservativeSet, thread);
+ gatherFromOtherThread(conservativeRoots, thread);
}
#ifndef NDEBUG
fastMallocAllow();
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.h b/Source/JavaScriptCore/runtime/MachineStackMarker.h
index 8afdb46..c814ac5 100644
--- a/Source/JavaScriptCore/runtime/MachineStackMarker.h
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef MachineStackMarker_h
-#define MachineStackMarker_h
+#ifndef MachineThreads_h
+#define MachineThreads_h
#include <wtf/Noncopyable.h>
#include <wtf/ThreadingPrimitives.h>
@@ -32,32 +32,31 @@
namespace JSC {
class Heap;
- class ConservativeSet;
+ class ConservativeRoots;
- class MachineStackMarker {
- WTF_MAKE_NONCOPYABLE(MachineStackMarker);
+ class MachineThreads {
+ WTF_MAKE_NONCOPYABLE(MachineThreads);
public:
- MachineStackMarker(Heap*);
- ~MachineStackMarker();
+ MachineThreads(Heap*);
+ ~MachineThreads();
- void markMachineStackConservatively(ConservativeSet&);
+ void gatherConservativeRoots(ConservativeRoots&, void* stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
void makeUsableFromMultipleThreads();
- void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
+ void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
#endif
private:
- void markCurrentThreadConservatively(ConservativeSet&);
- void markCurrentThreadConservativelyInternal(ConservativeSet&);
+ void gatherFromCurrentThread(ConservativeRoots&, void* stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS)
class Thread;
- static void unregisterThread(void*);
+ static void removeThread(void*);
+ void removeCurrentThread();
- void unregisterThread();
- void markOtherThreadConservatively(ConservativeSet&, Thread*);
+ void gatherFromOtherThread(ConservativeRoots&, Thread*);
#endif
Heap* m_heap;
@@ -65,10 +64,10 @@ namespace JSC {
#if ENABLE(JSC_MULTIPLE_THREADS)
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
- pthread_key_t m_currentThreadRegistrar;
+ pthread_key_t m_threadSpecific;
#endif
};
} // namespace JSC
-#endif // MachineStackMarker_h
+#endif // MachineThreads_h
diff --git a/Source/JavaScriptCore/runtime/MarkStack.cpp b/Source/JavaScriptCore/runtime/MarkStack.cpp
index a350c35..e9d1b13 100644
--- a/Source/JavaScriptCore/runtime/MarkStack.cpp
+++ b/Source/JavaScriptCore/runtime/MarkStack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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
@@ -26,6 +26,14 @@
#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;
@@ -37,4 +45,83 @@ void MarkStack::compact()
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
index 0b7941e..7131917 100644
--- a/Source/JavaScriptCore/runtime/MarkStack.h
+++ b/Source/JavaScriptCore/runtime/MarkStack.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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
@@ -27,6 +27,7 @@
#define MarkStack_h
#include "JSValue.h"
+#include "Register.h"
#include "WriteBarrier.h"
#include <wtf/Vector.h>
#include <wtf/Noncopyable.h>
@@ -34,6 +35,7 @@
namespace JSC {
+ class ConservativeRoots;
class JSGlobalData;
class Register;
@@ -50,7 +52,13 @@ namespace JSC {
#endif
{
}
-
+
+ ~MarkStack()
+ {
+ ASSERT(m_markSets.isEmpty());
+ ASSERT(m_values.isEmpty());
+ }
+
void deprecatedAppend(JSValue*);
void deprecatedAppend(JSCell**);
void deprecatedAppend(Register*);
@@ -70,17 +78,18 @@ namespace JSC {
if (count)
m_markSets.append(MarkSet(values, values + count, properties));
}
+
+ void append(ConservativeRoots&);
- inline void drain();
+ void drain();
void compact();
- ~MarkStack()
- {
- ASSERT(m_markSets.isEmpty());
- ASSERT(m_values.isEmpty());
- }
-
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*);
@@ -196,7 +205,105 @@ namespace JSC {
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/MarkedBlock.cpp b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
index 48dda4c..cae701f 100644
--- a/Source/JavaScriptCore/runtime/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.cpp
@@ -27,6 +27,8 @@
#include "MarkedBlock.h"
#include "JSCell.h"
+#include "JSObject.h"
+#include "JSZombie.h"
#include "ScopeChain.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/MarkedBlock.h b/Source/JavaScriptCore/runtime/MarkedBlock.h
index e80fe82..0e2b59c 100644
--- a/Source/JavaScriptCore/runtime/MarkedBlock.h
+++ b/Source/JavaScriptCore/runtime/MarkedBlock.h
@@ -24,6 +24,7 @@
#include <wtf/Bitmap.h>
#include <wtf/PageAllocationAligned.h>
+#include <wtf/StdLibExtras.h>
namespace JSC {
@@ -35,15 +36,6 @@ namespace JSC {
static const size_t KB = 1024;
- // Efficient implementation that takes advantage of powers of two.
- template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
- {
- COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
-
- size_t remainderMask = divisor - 1;
- return (x + remainderMask) & ~remainderMask;
- }
-
class MarkedBlock {
public:
static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
@@ -109,7 +101,7 @@ namespace JSC {
inline size_t MarkedBlock::firstAtom()
{
- return roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
+ return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
}
inline MarkedBlock::Atom* MarkedBlock::atoms()
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.cpp b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
index 15ab514..d9a1e42 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.cpp
@@ -24,6 +24,7 @@
#include "JSCell.h"
#include "JSGlobalData.h"
#include "JSLock.h"
+#include "JSObject.h"
#include "ScopeChain.h"
namespace JSC {
@@ -35,7 +36,10 @@ MarkedSpace::MarkedSpace(JSGlobalData* globalData)
, m_highWaterMark(0)
, m_globalData(globalData)
{
- for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep)
+ 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;
}
@@ -148,7 +152,10 @@ void MarkedSpace::reset()
{
m_waterMark = 0;
- for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep)
+ 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();
diff --git a/Source/JavaScriptCore/runtime/MarkedSpace.h b/Source/JavaScriptCore/runtime/MarkedSpace.h
index 2e88887..29a8cd0 100644
--- a/Source/JavaScriptCore/runtime/MarkedSpace.h
+++ b/Source/JavaScriptCore/runtime/MarkedSpace.h
@@ -32,8 +32,7 @@
#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)
-#define ASSERT_CLASS_FILLS_CELL(class) COMPILE_ASSERT(sizeof(class) == MarkedSpace::maxCellSize, class_fills_cell)
+#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) < MarkedSpace::maxCellSize, class_fits_in_cell)
namespace JSC {
@@ -48,7 +47,7 @@ namespace JSC {
WTF_MAKE_NONCOPYABLE(MarkedSpace);
public:
// Currently public for use in assertions.
- static const size_t maxCellSize = 64;
+ static const size_t maxCellSize = 1024;
static Heap* heap(JSCell*);
@@ -81,10 +80,15 @@ namespace JSC {
template<typename Functor> void forEach(Functor&);
private:
- // [ 8, 16... 64 ]
+ // [ 8, 16... 128 )
static const size_t preciseStep = MarkedBlock::atomSize;
- static const size_t preciseCutoff = maxCellSize;
- static const size_t preciseCount = preciseCutoff / preciseStep;
+ 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;
@@ -106,6 +110,7 @@ namespace JSC {
void clearMarks(MarkedBlock*);
SizeClass m_preciseSizeClasses[preciseCount];
+ SizeClass m_impreciseSizeClasses[impreciseCount];
HashSet<MarkedBlock*> m_blocks;
size_t m_waterMark;
size_t m_highWaterMark;
diff --git a/Source/JavaScriptCore/runtime/MathObject.h b/Source/JavaScriptCore/runtime/MathObject.h
index 86e7951..26eaae0 100644
--- a/Source/JavaScriptCore/runtime/MathObject.h
+++ b/Source/JavaScriptCore/runtime/MathObject.h
@@ -34,9 +34,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 7949dd9..d8fda69 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -41,7 +41,7 @@ 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(prototype);
+ m_errorStructure = ErrorInstance::createStructure(exec->globalData(), prototype);
}
static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
index e4978cc..23f798e 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -35,9 +35,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
Structure* errorStructure() { return m_errorStructure.get(); }
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index 3e4d6c7..aee143a 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -104,7 +104,7 @@ static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&)
// ECMA 15.7.1
static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* exec)
{
- NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->numberObjectStructure());
double n = exec->argumentCount() ? exec->argument(0).toNumber(exec) : 0;
object->setInternalValue(exec->globalData(), jsNumber(n));
return JSValue::encode(object);
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.h b/Source/JavaScriptCore/runtime/NumberConstructor.h
index aaf7c32..ab4507e 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.h
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.h
@@ -37,9 +37,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index 4408673..74b5e98 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& globalData, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(globalData, structure)
+NumberObject::NumberObject(JSGlobalData&, NonNullPassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
}
@@ -42,9 +42,9 @@ JSValue NumberObject::getJSNumber()
return internalValue();
}
-NumberObject* constructNumber(ExecState* exec, JSValue number)
+NumberObject* constructNumber(ExecState* exec, JSGlobalObject* globalObject, JSValue number)
{
- NumberObject* object = new (exec) NumberObject(exec->globalData(), exec->lexicalGlobalObject()->numberObjectStructure());
+ NumberObject* object = new (exec) NumberObject(exec->globalData(), globalObject->numberObjectStructure());
object->setInternalValue(exec->globalData(), number);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index 8a80382..90d0b26 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -31,19 +31,16 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
- protected:
- static const unsigned StructureFlags = JSWrapperObject::StructureFlags;
-
private:
virtual JSValue getJSNumber();
};
- NumberObject* constructNumber(ExecState*, JSValue);
+ NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 5080ef8..c642a5b 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -95,18 +95,18 @@ bool ObjectConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
}
// ECMA 15.2.2
-static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
JSValue arg = args.at(0);
if (arg.isUndefinedOrNull())
- return constructEmptyObject(exec);
- return arg.toObject(exec);
+ return constructEmptyObject(exec, globalObject);
+ return arg.toObject(exec, globalObject);
}
static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructObject(exec, args));
+ return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
@@ -118,7 +118,7 @@ ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructObject(exec, args));
+ return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
CallType ObjectConstructor::getCallData(CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.h b/Source/JavaScriptCore/runtime/ObjectConstructor.h
index 895f988..b7bfc1d 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.h
@@ -36,9 +36,9 @@ namespace JSC {
static const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index 85a3818..c000dc8 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -291,7 +291,7 @@ inline PropertyTable::~PropertyTable()
{
iterator end = this->end();
for (iterator iter = begin(); iter != end; ++iter)
- iter->key->ref();
+ iter->key->deref();
fastFree(m_index);
}
diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
index 351ecc3..8efb406 100644
--- a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "PropertyNameArray.h"
+#include "JSObject.h"
#include "ScopeChain.h"
#include "Structure.h"
#include "StructureChain.h"
diff --git a/Source/JavaScriptCore/runtime/PutPropertySlot.h b/Source/JavaScriptCore/runtime/PutPropertySlot.h
index 4c9e0e6..69d1f8b 100644
--- a/Source/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PutPropertySlot.h
@@ -45,14 +45,14 @@ namespace JSC {
{
}
- void setExistingProperty(DeprecatedPtr<JSObject> base, size_t offset)
+ void setExistingProperty(JSObject* base, size_t offset)
{
m_type = ExistingProperty;
m_base = base;
m_offset = offset;
}
- void setNewProperty(DeprecatedPtr<JSObject> base, size_t offset)
+ void setNewProperty(JSObject* base, size_t offset)
{
m_type = NewProperty;
m_base = base;
@@ -60,7 +60,7 @@ namespace JSC {
}
Type type() const { return m_type; }
- JSObject* base() const { return m_base.get(); }
+ JSObject* base() const { return m_base; }
bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
@@ -68,9 +68,10 @@ namespace JSC {
ASSERT(isCacheable());
return m_offset;
}
+
private:
Type m_type;
- DeprecatedPtr<JSObject> m_base;
+ JSObject* m_base;
size_t m_offset;
bool m_isStrictMode;
};
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 95ce5e9..25cb2d5 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -34,6 +34,38 @@
namespace JSC {
+RegExpFlags regExpFlags(const UString& string)
+{
+ RegExpFlags flags = NoFlags;
+
+ for (unsigned i = 0; i < string.length(); ++i) {
+ switch (string.characters()[i]) {
+ case 'g':
+ if (flags & FlagGlobal)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagGlobal);
+ break;
+
+ case 'i':
+ if (flags & FlagIgnoreCase)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
+ break;
+
+ case 'm':
+ if (flags & FlagMultiline)
+ return InvalidFlags;
+ flags = static_cast<RegExpFlags>(flags | FlagMultiline);
+ break;
+
+ default:
+ return InvalidFlags;
+ }
+ }
+
+ return flags;
+}
+
struct RegExpRepresentation {
#if ENABLE(YARR_JIT)
Yarr::YarrCodeBlock m_regExpJITCode;
@@ -41,9 +73,9 @@ struct RegExpRepresentation {
OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
};
-inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
: m_patternString(patternString)
- , m_flagBits(0)
+ , m_flags(flags)
, m_constructionError(0)
, m_numSubpatterns(0)
#if ENABLE(REGEXP_TRACING)
@@ -52,17 +84,6 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, co
#endif
, m_representation(adoptPtr(new RegExpRepresentation))
{
- // NOTE: The global flag is handled on a case-by-case basis by functions like
- // String::match and RegExpObject::match.
- if (!flags.isNull()) {
- if (flags.find('g') != notFound)
- m_flagBits |= Global;
- if (flags.find('i') != notFound)
- m_flagBits |= IgnoreCase;
- if (flags.find('m') != notFound)
- m_flagBits |= Multiline;
- }
-
m_state = compile(globalData);
}
@@ -70,7 +91,7 @@ RegExp::~RegExp()
{
}
-PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
{
RefPtr<RegExp> res = adoptRef(new RegExp(globalData, patternString, flags));
#if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index d99befb..000c33a 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -24,6 +24,7 @@
#include "UString.h"
#include "ExecutableAllocator.h"
+#include "RegExpKey.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
@@ -32,18 +33,20 @@ namespace JSC {
struct RegExpRepresentation;
class JSGlobalData;
+ RegExpFlags regExpFlags(const UString&);
+
class RegExp : public RefCounted<RegExp> {
public:
- static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
~RegExp();
- bool global() const { return m_flagBits & Global; }
- bool ignoreCase() const { return m_flagBits & IgnoreCase; }
- bool multiline() const { return m_flagBits & Multiline; }
+ bool global() const { return m_flags & FlagGlobal; }
+ bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
+ bool multiline() const { return m_flags & FlagMultiline; }
const UString& pattern() const { return m_patternString; }
- bool isValid() const { return !m_constructionError; }
+ bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
const char* errorMessage() const { return m_constructionError; }
int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
@@ -54,7 +57,7 @@ namespace JSC {
#endif
private:
- RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+ RegExp(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
enum RegExpState {
ParseError,
@@ -68,9 +71,8 @@ namespace JSC {
void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult);
#endif
- enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
UString m_patternString;
- int m_flagBits;
+ RegExpFlags m_flags;
const char* m_constructionError;
unsigned m_numSubpatterns;
#if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp
index d101758..c96b047 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp
@@ -31,7 +31,7 @@
namespace JSC {
-PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, RegExpFlags flags)
{
if (patternString.length() < maxCacheablePatternLength) {
pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0);
@@ -43,7 +43,7 @@ PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, con
return create(patternString, flags, m_cacheMap.end());
}
-PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator)
+PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, RegExpFlags flags, RegExpCacheMap::iterator iterator)
{
RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags);
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h
index b5b637f..b4a6ae5 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.h
+++ b/Source/JavaScriptCore/runtime/RegExpCache.h
@@ -41,8 +41,8 @@ class RegExpCache {
typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap;
public:
- PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags);
- PassRefPtr<RegExp> create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator);
+ PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, RegExpFlags);
+ PassRefPtr<RegExp> create(const UString& patternString, RegExpFlags, RegExpCacheMap::iterator);
RegExpCache(JSGlobalData* globalData);
private:
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index c06fdc4..19b4b36 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -291,9 +291,9 @@ void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValu
{
asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}
-
+
// ECMA 15.10.4
-JSObject* constructRegExp(ExecState* exec, const ArgList& args)
+JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
JSValue arg0 = args.at(0);
JSValue arg1 = args.at(1);
@@ -305,18 +305,28 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
}
UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
- UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+ if (exec->hadException())
+ return 0;
+
+ RegExpFlags flags = NoFlags;
+ if (!arg1.isUndefined()) {
+ flags = regExpFlags(arg1.toString(exec));
+ if (exec->hadException())
+ return 0;
+ if (flags == InvalidFlags)
+ return throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+ }
RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
if (!regExp->isValid())
return throwError(exec, createSyntaxError(exec, regExp->errorMessage()));
- return new (exec) RegExpObject(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
+ return new (exec) RegExpObject(exec->lexicalGlobalObject(), globalObject->regExpStructure(), regExp.release());
}
static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, args));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
@@ -329,7 +339,7 @@ ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec)
{
ArgList args(exec);
- return JSValue::encode(constructRegExp(exec, args));
+ return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
}
CallType RegExpConstructor::getCallData(CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h
index 8a8a54a..5e0b2b8 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h
@@ -59,9 +59,9 @@ namespace JSC {
public:
RegExpConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, RegExpPrototype*);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -96,7 +96,7 @@ namespace JSC {
RegExpConstructor* asRegExpConstructor(JSValue);
- JSObject* constructRegExp(ExecState*, const ArgList&);
+ JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&);
inline RegExpConstructor* asRegExpConstructor(JSValue value)
{
diff --git a/Source/JavaScriptCore/runtime/RegExpKey.h b/Source/JavaScriptCore/runtime/RegExpKey.h
index cd1368d..b4847f9 100644
--- a/Source/JavaScriptCore/runtime/RegExpKey.h
+++ b/Source/JavaScriptCore/runtime/RegExpKey.h
@@ -25,63 +25,54 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "UString.h"
-#include <wtf/text/StringHash.h>
-
#ifndef RegExpKey_h
#define RegExpKey_h
+#include "UString.h"
+#include <wtf/text/StringHash.h>
+
namespace JSC {
+enum RegExpFlags {
+ NoFlags = 0,
+ FlagGlobal = 1,
+ FlagIgnoreCase = 2,
+ FlagMultiline = 4,
+ InvalidFlags = 8,
+ DeletedValueFlags = -1
+};
+
struct RegExpKey {
- int flagsValue;
+ RegExpFlags flagsValue;
RefPtr<StringImpl> pattern;
RegExpKey()
- : flagsValue(0)
+ : flagsValue(NoFlags)
{
}
- RegExpKey(int flags)
+ RegExpKey(RegExpFlags flags)
: flagsValue(flags)
{
}
- RegExpKey(int flags, const UString& pattern)
+ RegExpKey(RegExpFlags flags, const UString& pattern)
: flagsValue(flags)
, pattern(pattern.impl())
{
}
- RegExpKey(int flags, const PassRefPtr<StringImpl> pattern)
+ RegExpKey(RegExpFlags flags, const PassRefPtr<StringImpl> pattern)
: flagsValue(flags)
, pattern(pattern)
{
}
- RegExpKey(int flags, const RefPtr<StringImpl>& pattern)
+ RegExpKey(RegExpFlags flags, const RefPtr<StringImpl>& pattern)
: flagsValue(flags)
, pattern(pattern)
{
}
-
- RegExpKey(const UString& flags, const UString& pattern)
- : pattern(pattern.impl())
- {
- flagsValue = getFlagsValue(flags);
- }
-
- int getFlagsValue(const UString flags)
- {
- flagsValue = 0;
- if (flags.find('g') != notFound)
- flagsValue += 4;
- if (flags.find('i') != notFound)
- flagsValue += 2;
- if (flags.find('m') != notFound)
- flagsValue += 1;
- return flagsValue;
- }
};
inline bool operator==(const RegExpKey& a, const RegExpKey& b)
@@ -112,8 +103,8 @@ template<> struct DefaultHash<JSC::RegExpKey> {
};
template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> {
- static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = -1; }
- static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == -1; }
+ static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::DeletedValueFlags; }
+ static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::DeletedValueFlags; }
};
} // namespace WTF
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 5baf884..4b5028b 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -63,7 +63,7 @@ const ClassInfo RegExpObject::s_info = { "RegExp", &JSObjectWithGlobalObject::s_
RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp)
: JSObjectWithGlobalObject(globalObject, structure)
- , d(adoptPtr(new RegExpObjectData(regExp, 0)))
+ , d(adoptPtr(new RegExpObjectData(regExp)))
{
ASSERT(inherits(&s_info));
}
@@ -72,6 +72,13 @@ RegExpObject::~RegExpObject()
{
}
+void RegExpObject::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+ if (UNLIKELY(!d->lastIndex.get().isInt32()))
+ markStack.append(&d->lastIndex);
+}
+
bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
@@ -104,7 +111,7 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&)
{
- return jsNumber(asRegExpObject(slotBase)->lastIndex());
+ return asRegExpObject(slotBase)->getLastIndex();
}
void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
@@ -114,7 +121,7 @@ void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue
void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
+ asRegExpObject(baseObject)->setLastIndex(exec->globalData(), value);
}
JSValue RegExpObject::test(ExecState* exec)
@@ -133,12 +140,7 @@ JSValue RegExpObject::exec(ExecState* exec)
bool RegExpObject::match(ExecState* exec)
{
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
-
- UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec);
- if (input.isNull()) {
- throwError(exec, createError(exec, makeUString("No input to ", toString(exec), ".")));
- return false;
- }
+ UString input = exec->argument(0).toString(exec);
if (!regExp()->global()) {
int position;
@@ -147,20 +149,32 @@ bool RegExpObject::match(ExecState* exec)
return position >= 0;
}
- if (d->lastIndex < 0 || d->lastIndex > input.length()) {
- d->lastIndex = 0;
- return false;
+ JSValue jsLastIndex = getLastIndex();
+ unsigned lastIndex;
+ if (LIKELY(jsLastIndex.isUInt32())) {
+ lastIndex = jsLastIndex.asUInt32();
+ if (lastIndex > input.length()) {
+ setLastIndex(0);
+ return false;
+ }
+ } else {
+ double doubleLastIndex = jsLastIndex.toInteger(exec);
+ if (doubleLastIndex < 0 || doubleLastIndex > input.length()) {
+ setLastIndex(0);
+ return false;
+ }
+ lastIndex = static_cast<unsigned>(doubleLastIndex);
}
int position;
int length = 0;
- regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
+ regExpConstructor->performMatch(d->regExp.get(), input, lastIndex, position, length);
if (position < 0) {
- d->lastIndex = 0;
+ setLastIndex(0);
return false;
}
- d->lastIndex = position + length;
+ setLastIndex(position + length);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index 1f89b84..fa2024d 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -28,14 +28,26 @@ namespace JSC {
class RegExpObject : public JSObjectWithGlobalObject {
public:
+ typedef JSObjectWithGlobalObject Base;
+
RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>);
virtual ~RegExpObject();
void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
RegExp* regExp() const { return d->regExp.get(); }
- void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
- double lastIndex() const { return d->lastIndex; }
+ void setLastIndex(size_t lastIndex)
+ {
+ d->lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
+ }
+ void setLastIndex(JSGlobalData& globalData, JSValue lastIndex)
+ {
+ d->lastIndex.set(globalData, this, lastIndex);
+ }
+ JSValue getLastIndex() const
+ {
+ return d->lastIndex.get();
+ }
JSValue test(ExecState*);
JSValue exec(ExecState*);
@@ -46,28 +58,30 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
-
+ static const unsigned StructureFlags = OverridesMarkChildren | OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags;
+
private:
+ virtual void markChildren(MarkStack&);
+
bool match(ExecState*);
struct RegExpObjectData {
WTF_MAKE_FAST_ALLOCATED;
public:
- RegExpObjectData(NonNullPassRefPtr<RegExp> regExp, double lastIndex)
+ RegExpObjectData(NonNullPassRefPtr<RegExp> regExp)
: regExp(regExp)
- , lastIndex(lastIndex)
{
+ lastIndex.setWithoutWriteBarrier(jsNumber(0));
}
RefPtr<RegExp> regExp;
- double lastIndex;
+ WriteBarrier<Unknown> lastIndex;
};
#if COMPILER(MSVC)
friend void WTF::deleteOwnedPtr<RegExpObjectData>(RegExpObjectData*);
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 106006c..61747b1 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -48,11 +48,11 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
// ECMA 15.10.5
RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
- : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", ""))
+ : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", NoFlags))
{
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 2, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 1, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
}
@@ -90,7 +90,17 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
regExp = asRegExpObject(arg0)->regExp();
} else {
UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec);
- UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ RegExpFlags flags = NoFlags;
+ if (!arg1.isUndefined()) {
+ flags = regExpFlags(arg1.toString(exec));
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ if (flags == InvalidFlags)
+ return throwVMError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+ }
regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
}
diff --git a/Source/JavaScriptCore/runtime/ScopeChain.h b/Source/JavaScriptCore/runtime/ScopeChain.h
index fbecd11..cb70a34 100644
--- a/Source/JavaScriptCore/runtime/ScopeChain.h
+++ b/Source/JavaScriptCore/runtime/ScopeChain.h
@@ -64,7 +64,7 @@ namespace JSC {
void print();
#endif
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto) { return Structure::create(globalData, proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
virtual void markChildren(MarkStack&);
private:
static const unsigned StructureFlags = OverridesMarkChildren;
@@ -100,7 +100,7 @@ namespace JSC {
bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
private:
- DeprecatedPtr<ScopeChainNode> m_node;
+ ScopeChainNode* m_node;
};
inline ScopeChainIterator ScopeChainNode::begin()
@@ -128,6 +128,17 @@ namespace JSC {
{
return scopeChain()->globalThis.get();
}
+
+ ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
+ {
+ return static_cast<ScopeChainNode*>(jsValue().asCell());
+ }
+
+ ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
+ {
+ *this = JSValue(scopeChain);
+ return *this;
+ }
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.cpp b/Source/JavaScriptCore/runtime/SmallStrings.cpp
index 9b193f5..ac67020 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/Source/JavaScriptCore/runtime/SmallStrings.cpp
@@ -33,8 +33,6 @@
namespace JSC {
-static const unsigned numCharactersToStore = 0x100;
-
static inline bool isMarked(JSCell* string)
{
return string && Heap::isMarked(string);
@@ -45,17 +43,22 @@ class SmallStringsStorage {
public:
SmallStringsStorage();
- StringImpl* rep(unsigned char character) { return m_reps[character].get(); }
+ StringImpl* rep(unsigned char character)
+ {
+ return m_reps[character].get();
+ }
private:
- RefPtr<StringImpl> m_reps[numCharactersToStore];
+ static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
+
+ RefPtr<StringImpl> m_reps[singleCharacterStringCount];
};
SmallStringsStorage::SmallStringsStorage()
{
UChar* characterBuffer = 0;
- RefPtr<StringImpl> baseString = StringImpl::createUninitialized(numCharactersToStore, characterBuffer);
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ RefPtr<StringImpl> baseString = StringImpl::createUninitialized(singleCharacterStringCount, characterBuffer);
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
characterBuffer[i] = i;
m_reps[i] = StringImpl::create(baseString, i, 1);
}
@@ -63,7 +66,7 @@ SmallStringsStorage::SmallStringsStorage()
SmallStrings::SmallStrings()
{
- COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
+ COMPILE_ASSERT(singleCharacterStringCount == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
clear();
}
@@ -71,7 +74,7 @@ SmallStrings::~SmallStrings()
{
}
-void SmallStrings::markChildren(MarkStack& markStack)
+void SmallStrings::markChildren(HeapRootMarker& heapRootMarker)
{
/*
Our hypothesis is that small strings are very common. So, we cache them
@@ -83,9 +86,9 @@ void SmallStrings::markChildren(MarkStack& markStack)
so, it's probably reasonable to mark the rest. If not, we clear the cache.
*/
- bool isAnyStringMarked = isMarked(m_emptyString.get());
- for (unsigned i = 0; i < numCharactersToStore && !isAnyStringMarked; ++i)
- isAnyStringMarked = isMarked(m_singleCharacterStrings[i].get());
+ bool isAnyStringMarked = isMarked(m_emptyString);
+ for (unsigned i = 0; i < singleCharacterStringCount && !isAnyStringMarked; ++i)
+ isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
if (!isAnyStringMarked) {
clear();
@@ -93,17 +96,17 @@ void SmallStrings::markChildren(MarkStack& markStack)
}
if (m_emptyString)
- markStack.append(&m_emptyString);
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ heapRootMarker.mark(&m_emptyString);
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i])
- markStack.append(&m_singleCharacterStrings[i]);
+ heapRootMarker.mark(&m_singleCharacterStrings[i]);
}
}
void SmallStrings::clear()
{
m_emptyString = 0;
- for (unsigned i = 0; i < numCharactersToStore; ++i)
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i)
m_singleCharacterStrings[i] = 0;
}
@@ -112,7 +115,7 @@ unsigned SmallStrings::count() const
unsigned count = 0;
if (m_emptyString)
++count;
- for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i])
++count;
}
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h
index cd9c325..b54d020 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.h
+++ b/Source/JavaScriptCore/runtime/SmallStrings.h
@@ -33,13 +33,16 @@
namespace JSC {
+ class HeapRootMarker;
class JSGlobalData;
class JSString;
class MarkStack;
class SmallStringsStorage;
+ static const unsigned maxSingleCharacterString = 0xFF;
+
class SmallStrings {
- WTF_MAKE_NONCOPYABLE(SmallStrings); WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(SmallStrings);
public:
SmallStrings();
~SmallStrings();
@@ -48,30 +51,33 @@ namespace JSC {
{
if (!m_emptyString)
createEmptyString(globalData);
- return m_emptyString.get();
+ return m_emptyString;
}
+
JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
{
if (!m_singleCharacterStrings[character])
createSingleCharacterString(globalData, character);
- return m_singleCharacterStrings[character].get();
+ return m_singleCharacterStrings[character];
}
StringImpl* singleCharacterStringRep(unsigned char character);
- void markChildren(MarkStack&);
+ void markChildren(HeapRootMarker&);
void clear();
unsigned count() const;
- JSCell** singleCharacterStrings() { return m_singleCharacterStrings[0].slot(); }
+ JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
private:
+ static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
+
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
- DeprecatedPtr<JSString> m_emptyString;
- FixedArray<DeprecatedPtr<JSString>, 0x100> m_singleCharacterStrings;
+ JSString* m_emptyString;
+ JSString* m_singleCharacterStrings[singleCharacterStringCount];
OwnPtr<SmallStringsStorage> m_storage;
};
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index 5398f31..ed088e4 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -67,9 +67,10 @@ StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObje
// ECMA 15.5.2
static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec)
{
+ JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
if (!exec->argumentCount())
- return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure()));
- return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), exec->argument(0).toString(exec)));
+ return JSValue::encode(new (exec) StringObject(exec, globalObject->stringObjectStructure()));
+ return JSValue::encode(new (exec) StringObject(exec, globalObject->stringObjectStructure(), exec->argument(0).toString(exec)));
}
ConstructType StringConstructor::getConstructData(ConstructData& constructData)
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index 5fe7544..47e5860 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -30,21 +30,21 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0 };
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsEmptyString(exec));
}
StringObject::StringObject(JSGlobalData& globalData, NonNullPassRefPtr<Structure> structure, JSString* string)
- : JSWrapperObject(globalData, structure)
+ : JSWrapperObject(structure)
{
ASSERT(inherits(&s_info));
setInternalValue(globalData, string);
}
StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(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 99f9add..ae3376d 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -31,7 +31,7 @@ namespace JSC {
StringObject(ExecState*, NonNullPassRefPtr<Structure>);
StringObject(ExecState*, NonNullPassRefPtr<Structure>, const UString&);
- static StringObject* create(ExecState*, JSString*);
+ static StringObject* create(ExecState*, JSGlobalObject*, JSString*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
@@ -45,15 +45,15 @@ namespace JSC {
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
StringObject(JSGlobalData&, NonNullPassRefPtr<Structure>, JSString*);
- };
+ };
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index 0a44ed3..e4c7061 100644
--- a/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -33,7 +33,7 @@ namespace JSC {
static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
{
return new (exec) StringObjectThatMasqueradesAsUndefined(exec,
- createStructure(exec->lexicalGlobalObject()->stringPrototype()), string);
+ createStructure(exec->globalData(), exec->lexicalGlobalObject()->stringPrototype()), string);
}
private:
@@ -42,9 +42,9 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValue proto)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index aa37122..a6bf4e6 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -604,9 +604,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
JSValue a0 = exec->argument(0);
- UString u = s;
RefPtr<RegExp> reg;
- RegExpObject* imp = 0;
if (a0.inherits(&RegExpObject::s_info))
reg = asRegExpObject(a0)->regExp();
else {
@@ -615,12 +613,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+ reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength = 0;
- regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, 0, pos, matchLength);
if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
if (pos < 0)
@@ -630,15 +628,13 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
// return array of matches
MarkedArgumentBuffer list;
- int lastIndex = 0;
+ unsigned lastIndex = 0;
while (pos >= 0) {
- list.append(jsSubstring(exec, u, pos, matchLength));
+ list.append(jsSubstring(exec, s, pos, matchLength));
lastIndex = pos;
pos += matchLength == 0 ? 1 : matchLength;
- regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, pos, pos, matchLength);
}
- if (imp)
- imp->setLastIndex(lastIndex);
if (list.isEmpty()) {
// if there are no matches at all, it's important to return
// Null instead of an empty array, because this matches
@@ -658,7 +654,6 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
JSValue a0 = exec->argument(0);
- UString u = s;
RefPtr<RegExp> reg;
if (a0.inherits(&RegExpObject::s_info))
reg = asRegExpObject(a0)->regExp();
@@ -668,12 +663,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+ reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength = 0;
- regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), s, 0, pos, matchLength);
return JSValue::encode(jsNumber(pos));
}
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.h b/Source/JavaScriptCore/runtime/StringPrototype.h
index feea2e2..57def22 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.h
+++ b/Source/JavaScriptCore/runtime/StringPrototype.h
@@ -34,12 +34,18 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+ return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
}
static const ClassInfo s_info;
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | StringObject::StructureFlags;
+
+ COMPILE_ASSERT(!StringObject::AnonymousSlotCount, StringPrototype_stomps_on_your_anonymous_slot);
+ static const unsigned AnonymousSlotCount = 1;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index bf27334..c9f900a 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -32,7 +32,6 @@
#include "PropertyMapHashTable.h"
#include "PropertyNameArray.h"
#include "Protect.h"
-#include "StructureChain.h"
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "UString.h"
@@ -46,6 +45,7 @@ namespace JSC {
class MarkStack;
class PropertyNameArray;
class PropertyNameArrayData;
+ class StructureChain;
struct ClassInfo;
@@ -56,13 +56,18 @@ namespace JSC {
class Structure : public RefCounted<Structure> {
public:
- friend class JIT;
friend class StructureTransitionTable;
- static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
+ static PassRefPtr<Structure> create(JSGlobalData&, JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount, const ClassInfo* classInfo)
{
return adoptRef(new Structure(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();
@@ -102,6 +107,7 @@ namespace JSC {
DeprecatedPtr<Unknown>* storedPrototypeSlot() { return &m_prototype; }
JSValue prototypeForLookup(ExecState*) const;
StructureChain* prototypeChain(ExecState*) const;
+ DeprecatedPtr<StructureChain>* cachedPrototypeChainSlot() { return &m_cachedPrototypeChain; }
Structure* previousID() const { return m_previous.get(); }
@@ -140,6 +146,21 @@ namespace JSC {
static void initializeThreading();
+ static ptrdiff_t prototypeOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_prototype);
+ }
+
+ static ptrdiff_t typeInfoFlagsOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
+ }
+
+ static ptrdiff_t typeInfoTypeOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
+ }
+
private:
Structure(JSValue prototype, const TypeInfo&, unsigned anonymousSlotCount, const ClassInfo*);
Structure(const Structure*);
@@ -190,7 +211,7 @@ namespace JSC {
TypeInfo m_typeInfo;
DeprecatedPtr<Unknown> m_prototype;
- mutable RefPtr<StructureChain> m_cachedPrototypeChain;
+ mutable DeprecatedPtr<StructureChain> m_cachedPrototypeChain;
RefPtr<Structure> m_previous;
RefPtr<StringImpl> m_nameInPrevious;
diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp
index e4523c3..4fa4a4b 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp
@@ -32,7 +32,8 @@
namespace JSC {
-StructureChain::StructureChain(Structure* head)
+StructureChain::StructureChain(NonNullPassRefPtr<Structure> structure, Structure* head)
+ : JSCell(structure.releaseRef())
{
size_t size = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h
index 816b66d..88592dc 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.h
+++ b/Source/JavaScriptCore/runtime/StructureChain.h
@@ -26,6 +26,8 @@
#ifndef StructureChain_h
#define StructureChain_h
+#include "JSCell.h"
+
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -35,15 +37,16 @@ namespace JSC {
class Structure;
- class StructureChain : public RefCounted<StructureChain> {
+ class StructureChain : public JSCell {
friend class JIT;
public:
- static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
+ static StructureChain* create(JSGlobalData& globalData, Structure* head) { return new (&globalData) StructureChain(globalData.structureChainStructure, head); }
RefPtr<Structure>* head() { return m_vector.get(); }
+ static PassRefPtr<Structure> createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, prototype, TypeInfo(CompoundType, OverridesMarkChildren), 0, 0); }
private:
- StructureChain(Structure* head);
+ StructureChain(NonNullPassRefPtr<Structure>, Structure* head);
OwnArrayPtr<RefPtr<Structure> > m_vector;
};
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
index 04d904d..d3867d4 100644
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -101,7 +101,7 @@ static inline unsigned getCPUTime()
// use a relative time from first call in order to avoid an overflow
static double firstTime = currentTime();
- return (currentTime() - firstTime) * 1000;
+ return static_cast<unsigned> ((currentTime() - firstTime) * 1000);
#endif
}
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index 44840ad..af018a8 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -35,6 +35,7 @@ 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) { }
@@ -54,6 +55,7 @@ protected:
JSCell* m_cell;
};
+// FIXME: Remove all uses of this class.
template <> class DeprecatedPtr<Unknown> {
public:
DeprecatedPtr() { }
@@ -73,17 +75,23 @@ private:
JSValue m_value;
};
-template <typename T> struct WriteBarrierCheck {
+template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+template <typename T> struct JSValueChecker {
static const bool IsJSValue = false;
};
-template <> struct WriteBarrierCheck<JSValue> {
+template <> struct JSValueChecker<JSValue> {
static const bool IsJSValue = true;
};
+// We have a separate base class with no constructors for use in Unions.
template <typename T> class WriteBarrierBase {
public:
- COMPILE_ASSERT(!WriteBarrierCheck<T>::IsJSValue, WriteBarrier_JSValue_is_invalid__use_unknown);
+ 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); }
T* get() const { return reinterpret_cast<T*>(m_cell); }
@@ -100,20 +108,10 @@ public:
void setWithoutWriteBarrier(T* value) { this->m_cell = reinterpret_cast<JSCell*>(value); }
-protected:
+private:
JSCell* m_cell;
};
-template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
-public:
- WriteBarrier() { this->m_cell = 0; }
- WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
- {
- this->set(globalData, owner, value);
- }
-
-};
-
template <> class WriteBarrierBase<Unknown> {
public:
void set(JSGlobalData&, const JSCell*, JSValue value) { m_value = JSValue::encode(value); }
@@ -138,29 +136,41 @@ public:
operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
bool operator!() const { return !get(); }
-protected:
+private:
EncodedJSValue m_value;
};
+template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
+public:
+ WriteBarrier()
+ {
+ this->setWithoutWriteBarrier(0);
+ }
+
+ WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
+ {
+ this->set(globalData, owner, value);
+ }
+};
+
template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
public:
- WriteBarrier() { m_value = JSValue::encode(JSValue()); }
+ WriteBarrier()
+ {
+ this->setWithoutWriteBarrier(JSValue());
+ }
+
WriteBarrier(JSGlobalData& globalData, const JSCell* owner, JSValue value)
{
this->set(globalData, owner, value);
}
};
-template <typename U, typename V> inline bool operator==(const DeprecatedPtr<U>& lhs, const DeprecatedPtr<V>& rhs)
-{
- return lhs.get() == rhs.get();
-}
-
template <typename U, typename V> inline bool operator==(const WriteBarrierBase<U>& lhs, const WriteBarrierBase<V>& rhs)
{
return lhs.get() == rhs.get();
}
-}
+} // namespace JSC
#endif // WriteBarrier_h