summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-16 14:56:46 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-16 14:57:30 +0200
commitb297e0fa5c217c9467033b7c8b46891a52870120 (patch)
tree43fc14689295e9e64f2719d05aad94e3049f6cd7 /Source/JavaScriptCore/runtime
parent69d517dbfa69903d8593cc1737f0474b21e3251e (diff)
downloadqtwebkit-b297e0fa5c217c9467033b7c8b46891a52870120.tar.gz
Revert "Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)"
This reverts commit 5466563f4b5b6b86523e3f89bb7f77e5b5270c78. Caused OOM issues on some CI machines :(
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h9
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConventions.h2
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp33
-rw-r--r--Source/JavaScriptCore/runtime/ArrayStorage.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/Butterfly.h25
-rw-r--r--Source/JavaScriptCore/runtime/ButterflyInlineMethods.h8
-rw-r--r--Source/JavaScriptCore/runtime/ClassInfo.h4
-rw-r--r--Source/JavaScriptCore/runtime/CommonSlowPaths.h6
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h13
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.cpp76
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.h53
-rw-r--r--Source/JavaScriptCore/runtime/InitializeThreading.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp914
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h130
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h59
-rw-r--r--Source/JavaScriptCore/runtime/JSDestructibleObject.h43
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h48
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h33
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalThis.cpp58
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalThis.h76
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/JSNameScope.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp473
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h212
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h14
-rw-r--r--Source/JavaScriptCore/runtime/JSProxy.cpp129
-rw-r--r--Source/JavaScriptCore/runtime/JSProxy.h95
-rw-r--r--Source/JavaScriptCore/runtime/JSScope.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSSymbolTableObject.h12
-rw-r--r--Source/JavaScriptCore/runtime/JSType.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSWithScope.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h10
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/NameConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/NameInstance.h6
-rw-r--r--Source/JavaScriptCore/runtime/NamePrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/Options.h16
-rw-r--r--Source/JavaScriptCore/runtime/PropertyMapHashTable.h11
-rw-r--r--Source/JavaScriptCore/runtime/PropertyOffset.h52
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.h2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.h2
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp33
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h82
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.h5
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h14
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.h5
-rw-r--r--Source/JavaScriptCore/runtime/TypedArrayDescriptor.h76
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h6
96 files changed, 1001 insertions, 2051 deletions
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index ba73b2cf2..fdf202192 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -33,7 +33,9 @@ using namespace std;
namespace JSC {
-const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
+ASSERT_CLASS_FITS_IN_CELL(Arguments);
+
+const ClassInfo Arguments::s_info = { "Arguments", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
@@ -404,19 +406,19 @@ void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* re
JSValue value;
Register* location = &registers[CallFrame::argumentOffset(i)];
switch (recovery.technique()) {
- case AlreadyInJSStack:
+ case AlreadyInRegisterFile:
value = location->jsValue();
break;
- case AlreadyInJSStackAsUnboxedInt32:
+ case AlreadyInRegisterFileAsUnboxedInt32:
value = jsNumber(location->unboxedInt32());
break;
- case AlreadyInJSStackAsUnboxedCell:
+ case AlreadyInRegisterFileAsUnboxedCell:
value = location->unboxedCell();
break;
- case AlreadyInJSStackAsUnboxedBoolean:
+ case AlreadyInRegisterFileAsUnboxedBoolean:
value = jsBoolean(location->unboxedBoolean());
break;
- case AlreadyInJSStackAsUnboxedDouble:
+ case AlreadyInRegisterFileAsUnboxedDouble:
#if USE(JSVALUE64)
value = jsNumber(*bitwise_cast<double*>(location));
#else
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 7c8b69bd1..40063bead 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -26,7 +26,6 @@
#include "CodeOrigin.h"
#include "JSActivation.h"
-#include "JSDestructibleObject.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Interpreter.h"
@@ -34,11 +33,11 @@
namespace JSC {
- class Arguments : public JSDestructibleObject {
+ class Arguments : public JSNonFinalObject {
friend class JIT;
friend class DFG::SpeculativeJIT;
public:
- typedef JSDestructibleObject Base;
+ typedef JSNonFinalObject Base;
static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
{
@@ -148,12 +147,12 @@ namespace JSC {
}
inline Arguments::Arguments(CallFrame* callFrame)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
{
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
{
}
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index a13648442..eda35e146 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -53,6 +53,8 @@ const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_in
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
+
ArrayConstructor::ArrayConstructor(JSGlobalObject* globalObject, Structure* structure)
: InternalFunction(globalObject, structure)
{
diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h
index a557b1ef9..3ea6b0471 100644
--- a/Source/JavaScriptCore/runtime/ArrayConventions.h
+++ b/Source/JavaScriptCore/runtime/ArrayConventions.h
@@ -79,7 +79,7 @@ static const unsigned minDensityMultiplier = 8;
inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
{
- return length / minDensityMultiplier <= numValues;
+ return length <= MIN_SPARSE_ARRAY_INDEX || length / minDensityMultiplier <= numValues;
}
inline IndexingHeader indexingHeaderForArray(unsigned length, unsigned vectorLength)
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 6975dc778..1eacd1179 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -42,6 +42,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
+
static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
@@ -192,8 +194,7 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
// currentCount) will be shifted to the left or right as appropriate; in the
// case of shift this must be removing values, in the case of unshift this
// must be introducing new values.
-template<JSArray::ShiftCountMode shiftCountMode>
-void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
+static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
{
ASSERT(currentCount > resultCount);
unsigned count = currentCount - resultCount;
@@ -201,9 +202,9 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current
ASSERT(header <= length);
ASSERT(currentCount <= (length - header));
- if (isJSArray(thisObj)) {
+ if (!header && isJSArray(thisObj)) {
JSArray* array = asArray(thisObj);
- if (array->length() == length && asArray(thisObj)->shiftCount<shiftCountMode>(exec, header, count))
+ if (array->length() == length && asArray(thisObj)->shiftCount(exec, count))
return;
}
@@ -230,8 +231,7 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current
}
}
}
-template<JSArray::ShiftCountMode shiftCountMode>
-void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
+static inline void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
{
ASSERT(resultCount > currentCount);
unsigned count = resultCount - currentCount;
@@ -245,12 +245,12 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre
return;
}
- if (isJSArray(thisObj)) {
+ if (!header && isJSArray(thisObj)) {
JSArray* array = asArray(thisObj);
- if (array->length() == length && array->unshiftCount<shiftCountMode>(exec, header, count))
+ if (array->length() == length && asArray(thisObj)->unshiftCount(exec, count))
return;
}
-
+
for (unsigned k = length - currentCount; k > header; --k) {
unsigned from = k + currentCount - 1;
unsigned to = k + resultCount - 1;
@@ -526,7 +526,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
array->push(exec, exec->argument(0));
return JSValue::encode(jsNumber(array->length()));
}
-
+
JSObject* thisObj = thisValue.toObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (exec->hadException())
@@ -544,7 +544,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
}
-
JSValue newLength(static_cast<int64_t>(length) + static_cast<int64_t>(exec->argumentCount()));
putProperty(exec, thisObj, exec->propertyNames().length, newLength);
return JSValue::encode(newLength);
@@ -601,7 +600,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
result = jsUndefined();
} else {
result = thisObj->get(exec, 0);
- shift<JSArray::ShiftCountForShift>(exec, thisObj, 0, 1, 0, length);
+ shift(exec, thisObj, 0, 1, 0, length);
if (exec->hadException())
return JSValue::encode(jsUndefined());
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1));
@@ -656,7 +655,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
CallData callData;
CallType callType = getCallData(function, callData);
- if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->hasSparseMap() && !shouldUseSlowPut(thisObj->structure()->indexingType())) {
+ if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseIndexingMode() && !shouldUseSlowPut(thisObj->structure()->indexingType())) {
if (isNumericCompareFunction(exec, callType, callData))
asArray(thisObj)->sortNumeric(exec, function, callType, callData);
else if (callType != CallTypeNone)
@@ -731,7 +730,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* 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));
@@ -763,11 +762,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
if (additionalArgs < deleteCount) {
- shift<JSArray::ShiftCountForSplice>(exec, thisObj, begin, deleteCount, additionalArgs, length);
+ shift(exec, thisObj, begin, deleteCount, additionalArgs, length);
if (exec->hadException())
return JSValue::encode(jsUndefined());
} else if (additionalArgs > deleteCount) {
- unshift<JSArray::ShiftCountForSplice>(exec, thisObj, begin, deleteCount, additionalArgs, length);
+ unshift(exec, thisObj, begin, deleteCount, additionalArgs, length);
if (exec->hadException())
return JSValue::encode(jsUndefined());
}
@@ -792,7 +791,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
unsigned nrArgs = exec->argumentCount();
if (nrArgs) {
- unshift<JSArray::ShiftCountForShift>(exec, thisObj, 0, 0, nrArgs, length);
+ unshift(exec, thisObj, 0, 0, nrArgs, length);
if (exec->hadException())
return JSValue::encode(jsUndefined());
}
diff --git a/Source/JavaScriptCore/runtime/ArrayStorage.h b/Source/JavaScriptCore/runtime/ArrayStorage.h
index ffd84b281..1ab936335 100644
--- a/Source/JavaScriptCore/runtime/ArrayStorage.h
+++ b/Source/JavaScriptCore/runtime/ArrayStorage.h
@@ -41,8 +41,6 @@ namespace JSC {
// setStorage() methods. It is important to note that there may be space before the ArrayStorage that
// is used to quick unshift / shift operation. The actual allocated pointer is available by using:
// getStorage() - m_indexBias * sizeof(JSValue)
-// All slots in ArrayStorage (slots from 0 to vectorLength) are expected to be initialized to a JSValue or,
-// for hole slots, JSValue().
struct ArrayStorage {
WTF_MAKE_NONCOPYABLE(ArrayStorage);
private:
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 0485350ce..9b666292c 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -26,6 +26,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanConstructor);
const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) };
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index 355993864..bf2655bbb 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp
@@ -25,6 +25,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanObject);
const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) };
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
index a331c6c15..c8c77220a 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -47,6 +47,7 @@ const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info,
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanPrototype);
BooleanPrototype::BooleanPrototype(ExecState* exec, Structure* structure)
diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h
index cb93aea8a..1926169ba 100644
--- a/Source/JavaScriptCore/runtime/Butterfly.h
+++ b/Source/JavaScriptCore/runtime/Butterfly.h
@@ -35,7 +35,7 @@
namespace JSC {
class JSGlobalData;
-class CopyVisitor;
+class SlotVisitor;
struct ArrayStorage;
class Butterfly {
@@ -56,15 +56,6 @@ public:
return reinterpret_cast<Butterfly*>(static_cast<EncodedJSValue*>(base) + preCapacity + propertyCapacity + 1);
}
- // This method is here not just because it's handy, but to remind you that
- // the whole point of butterflies is to do evil pointer arithmetic.
- static Butterfly* fromPointer(char* ptr)
- {
- return reinterpret_cast<Butterfly*>(ptr);
- }
-
- char* pointer() { return reinterpret_cast<char*>(this); }
-
static ptrdiff_t offsetOfIndexingHeader() { return IndexingHeader::offsetOfIndexingHeader(); }
static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); }
static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); }
@@ -73,27 +64,15 @@ public:
static Butterfly* create(JSGlobalData&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes);
static Butterfly* create(JSGlobalData&, Structure*);
- static Butterfly* createUninitializedDuringCollection(CopyVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
+ static Butterfly* createUninitializedDuringCollection(SlotVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
IndexingHeader* indexingHeader() { return IndexingHeader::from(this); }
const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); }
PropertyStorage propertyStorage() { return indexingHeader()->propertyStorage(); }
ConstPropertyStorage propertyStorage() const { return indexingHeader()->propertyStorage(); }
-
- uint32_t publicLength() { return indexingHeader()->publicLength(); }
- uint32_t vectorLength() { return indexingHeader()->vectorLength(); }
- void setPublicLength(uint32_t value) { indexingHeader()->setPublicLength(value); }
- void setVectorLength(uint32_t value) { indexingHeader()->setVectorLength(value); }
-
template<typename T>
T* indexingPayload() { return reinterpret_cast<T*>(this); }
ArrayStorage* arrayStorage() { return indexingPayload<ArrayStorage>(); }
- WriteBarrier<Unknown>* contiguous() { return indexingPayload<WriteBarrier<Unknown> >(); }
-
- static Butterfly* fromContiguous(WriteBarrier<Unknown>* contiguous)
- {
- return reinterpret_cast<Butterfly*>(contiguous);
- }
static ptrdiff_t offsetOfPropertyStorage() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); }
static int indexOfPropertyStorage()
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h
index 86a836bef..049350342 100644
--- a/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h
+++ b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h
@@ -29,8 +29,8 @@
#include "ArrayStorage.h"
#include "Butterfly.h"
#include "CopiedSpaceInlineMethods.h"
-#include "CopyVisitor.h"
#include "JSGlobalData.h"
+#include "SlotVisitor.h"
#include "Structure.h"
namespace JSC {
@@ -59,7 +59,7 @@ inline Butterfly* Butterfly::create(JSGlobalData& globalData, Structure* structu
return create(globalData, 0, structure->outOfLineCapacity(), hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0);
}
-inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::createUninitializedDuringCollection(SlotVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
{
Butterfly* result = fromBase(
visitor.allocateNewSpace(totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)),
@@ -144,7 +144,7 @@ inline Butterfly* Butterfly::resizeArray(JSGlobalData& globalData, Structure* st
inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots)
{
- ASSERT(hasArrayStorage(structure->indexingType()));
+ ASSERT(hasIndexingHeader(structure->indexingType()));
ASSERT(numberOfSlots <= indexingHeader()->preCapacity(structure));
unsigned propertyCapacity = structure->outOfLineCapacity();
// FIXME: It would probably be wise to rewrite this as a loop since (1) we know in which
@@ -163,7 +163,7 @@ inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots)
inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots)
{
- ASSERT(hasArrayStorage(structure->indexingType()));
+ ASSERT(hasIndexingHeader(structure->indexingType()));
unsigned propertyCapacity = structure->outOfLineCapacity();
// FIXME: See comment in unshift(), above.
memmove(
diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h
index c918621fe..e8823d571 100644
--- a/Source/JavaScriptCore/runtime/ClassInfo.h
+++ b/Source/JavaScriptCore/runtime/ClassInfo.h
@@ -39,9 +39,6 @@ namespace JSC {
typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&);
VisitChildrenFunctionPtr visitChildren;
- typedef void (*CopyBackingStoreFunctionPtr)(JSCell*, CopyVisitor&);
- CopyBackingStoreFunctionPtr copyBackingStore;
-
typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&);
GetCallDataFunctionPtr getCallData;
@@ -119,7 +116,6 @@ struct MemberCheck##member { \
#define CREATE_METHOD_TABLE(ClassName) { \
&ClassName::destroy, \
&ClassName::visitChildren, \
- &ClassName::copyBackingStore, \
&ClassName::getCallData, \
&ClassName::getConstructData, \
&ClassName::put, \
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index 2f5159461..7edd9091c 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -43,7 +43,7 @@ namespace JSC {
namespace CommonSlowPaths {
-ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, JSStack* stack, CodeSpecializationKind kind)
+ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFile, CodeSpecializationKind kind)
{
JSFunction* callee = jsCast<JSFunction*>(exec->callee());
ASSERT(!callee->isHostFunction());
@@ -51,7 +51,7 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, JSStack* stack, CodeSpec
int argumentCountIncludingThis = exec->argumentCountIncludingThis();
// This ensures enough space for the worst case scenario of zero arguments passed by the caller.
- if (!stack->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
+ if (!registerFile->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
return 0;
ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
@@ -71,7 +71,7 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, JSStack* stack, CodeSpec
dst[i] = jsUndefined();
ExecState* newExec = ExecState::create(dst);
- ASSERT((void*)newExec <= stack->end());
+ ASSERT((void*)newExec <= registerFile->end());
return newExec;
}
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index f78e8bf55..e4f89dd37 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -71,6 +71,7 @@ const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_inf
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(DateConstructor);
DateConstructor::DateConstructor(JSGlobalObject* globalObject, Structure* structure)
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 75da466fb..9b2cb164f 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -70,6 +70,8 @@ using namespace WTF;
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
+
static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*);
static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*);
static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*);
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index 68ae12d90..27a729d0a 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -177,6 +177,8 @@ JSObject* throwSyntaxError(ExecState* exec)
return throwError(exec, createSyntaxError(exec, ASCIILiteral("Syntax error")));
}
+ASSERT_CLASS_FITS_IN_CELL(StrictModeTypeErrorFunction);
+
const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
void StrictModeTypeErrorFunction::destroy(JSCell* cell)
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index f2578a497..96272d0cf 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -27,6 +27,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorConstructor);
const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorConstructor) };
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index a30efdc31..6c9d6df04 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -30,7 +30,7 @@
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorPrototype);
+ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*);
@@ -48,6 +48,8 @@ const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, 0, E
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
+
ErrorPrototype::ErrorPrototype(ExecState* exec, Structure* structure)
: ErrorInstance(exec->globalData(), structure)
{
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 76a537da3..6eeda3a82 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -81,8 +81,6 @@ namespace JSC {
typedef JSCell Base;
#if ENABLE(JIT)
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
#endif
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index bf74c0a97..570444e3c 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -34,6 +34,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionConstructor);
const ClassInfo FunctionConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionConstructor) };
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index a4b2202c1..dd1628b29 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -32,6 +32,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionPrototype);
const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionPrototype) };
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 45dd0bbde..a9a2a66bf 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -30,7 +30,6 @@
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#include <wtf/HashSet.h>
-#include <wtf/text/ASCIIFastPath.h>
#include <wtf/text/StringHash.h>
using WTF::ThreadSpecific;
@@ -81,7 +80,11 @@ struct IdentifierLCharFromUCharTranslator {
{
LChar* d;
StringImpl* r = StringImpl::createUninitialized(buf.length, d).leakRef();
- WTF::copyLCharsFromUCharSource(d, buf.s, buf.length);
+ for (unsigned i = 0; i != buf.length; i++) {
+ UChar c = buf.s[i];
+ ASSERT(c <= 0xff);
+ d[i] = c;
+ }
r->setHash(hash);
location = r;
}
@@ -99,7 +102,7 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c)
const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c);
if (iter != literalIdentifierTable.end())
- return iter->value;
+ return iter->second;
HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierASCIIStringTranslator>(reinterpret_cast<const LChar*>(c));
diff --git a/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h
index 22785ce24..e1d893b0b 100644
--- a/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h
+++ b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h
@@ -42,17 +42,10 @@ inline size_t IndexingHeader::preCapacity(Structure* structure)
inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure)
{
- switch (structure->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return vectorLength() * sizeof(EncodedJSValue);
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return ArrayStorage::sizeFor(arrayStorage()->vectorLength());
-
- default:
- ASSERT(!hasIndexedProperties(structure->indexingType()));
+ if (LIKELY(!hasArrayStorage(structure->indexingType())))
return 0;
- }
+
+ return ArrayStorage::sizeFor(arrayStorage()->vectorLength());
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/IndexingType.cpp b/Source/JavaScriptCore/runtime/IndexingType.cpp
deleted file mode 100644
index 7261847a2..000000000
--- a/Source/JavaScriptCore/runtime/IndexingType.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "IndexingType.h"
-
-#include <stdio.h>
-#include <wtf/StringExtras.h>
-
-namespace JSC {
-
-const char* indexingTypeToString(IndexingType indexingType)
-{
- static char result[128];
- const char* basicName;
- switch (indexingType & AllArrayTypes) {
- case NonArray:
- basicName = "NonArray";
- break;
- case NonArrayWithContiguous:
- basicName = "NonArrayWithContiguous";
- break;
- case NonArrayWithArrayStorage:
- basicName = "NonArrayWithArrayStorage";
- break;
- case NonArrayWithSlowPutArrayStorage:
- basicName = "NonArrayWithSlowPutArrayStorage";
- break;
- case ArrayClass:
- basicName = "ArrayClass";
- break;
- case ArrayWithContiguous:
- basicName = "ArrayWithContiguous";
- break;
- case ArrayWithArrayStorage:
- basicName = "ArrayWithArrayStorage";
- break;
- case ArrayWithSlowPutArrayStorage:
- basicName = "ArrayWithSlowPutArrayStorage";
- break;
- default:
- basicName = "Unknown!";
- break;
- }
-
- snprintf(
- result, sizeof(result), "%s%s", basicName,
- (indexingType & MayHaveIndexedAccessors) ? "|MayHaveIndexedAccessors" : "");
-
- return result;
-}
-
-} // namespace JSC
-
diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h
index 4bbe3cfa0..3b97230ea 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.h
+++ b/Source/JavaScriptCore/runtime/IndexingType.h
@@ -26,44 +26,32 @@
#ifndef IndexingType_h
#define IndexingType_h
-#include <wtf/StdLibExtras.h>
-
namespace JSC {
typedef uint8_t IndexingType;
// Flags for testing the presence of capabilities.
static const IndexingType IsArray = 1;
-
-// The shape of the indexed property storage.
-static const IndexingType IndexingShapeMask = 30;
-static const IndexingType NoIndexingShape = 0;
-static const IndexingType ContiguousShape = 26;
-static const IndexingType ArrayStorageShape = 28;
-static const IndexingType SlowPutArrayStorageShape = 30;
+static const IndexingType HasArrayStorage = 8;
+static const IndexingType HasSlowPutArrayStorage = 16;
// Additional flags for tracking the history of the type. These are usually
// masked off unless you ask for them directly.
-static const IndexingType MayHaveIndexedAccessors = 32;
+static const IndexingType HadArrayStorage = 32; // Means that this object did have array storage in the past.
+static const IndexingType MayHaveIndexedAccessors = 64;
// List of acceptable array types.
static const IndexingType NonArray = 0;
-static const IndexingType NonArrayWithContiguous = ContiguousShape;
-static const IndexingType NonArrayWithArrayStorage = ArrayStorageShape;
-static const IndexingType NonArrayWithSlowPutArrayStorage = SlowPutArrayStorageShape;
+static const IndexingType NonArrayWithArrayStorage = HasArrayStorage;
+static const IndexingType NonArrayWithSlowPutArrayStorage = HasSlowPutArrayStorage;
static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution.
-static const IndexingType ArrayWithContiguous = IsArray | ContiguousShape;
-static const IndexingType ArrayWithArrayStorage = IsArray | ArrayStorageShape;
-static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArrayStorageShape;
+static const IndexingType ArrayWithArrayStorage = IsArray | HasArrayStorage;
+static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | HasSlowPutArrayStorage;
#define ALL_BLANK_INDEXING_TYPES \
NonArray: \
case ArrayClass
-#define ALL_CONTIGUOUS_INDEXING_TYPES \
- NonArrayWithContiguous: \
- case ArrayWithContiguous
-
#define ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES \
ArrayWithArrayStorage: \
case ArrayWithSlowPutArrayStorage
@@ -75,7 +63,12 @@ static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArr
static inline bool hasIndexedProperties(IndexingType indexingType)
{
- return (indexingType & IndexingShapeMask) != NoIndexingShape;
+ switch (indexingType) {
+ case ALL_BLANK_INDEXING_TYPES:
+ return false;
+ default:
+ return true;
+ }
}
static inline bool hasIndexingHeader(IndexingType type)
@@ -83,30 +76,16 @@ static inline bool hasIndexingHeader(IndexingType type)
return hasIndexedProperties(type);
}
-static inline bool hasContiguous(IndexingType indexingType)
-{
- return (indexingType & IndexingShapeMask) == ContiguousShape;
-}
-
-// FIXME: This is an awkward name. This should really be called hasArrayStorage()
-// and then next method down should be called hasAnyArrayStorage().
-static inline bool hasFastArrayStorage(IndexingType indexingType)
-{
- return (indexingType & IndexingShapeMask) == ArrayStorageShape;
-}
-
static inline bool hasArrayStorage(IndexingType indexingType)
{
- return static_cast<uint8_t>((indexingType & IndexingShapeMask) - ArrayStorageShape) <= static_cast<uint8_t>(SlowPutArrayStorageShape - ArrayStorageShape);
+ return !!(indexingType & (HasArrayStorage | HasSlowPutArrayStorage));
}
static inline bool shouldUseSlowPut(IndexingType indexingType)
{
- return (indexingType & IndexingShapeMask) == SlowPutArrayStorageShape;
+ return !!(indexingType & HasSlowPutArrayStorage);
}
-const char* indexingTypeToString(IndexingType);
-
// Mask of all possible types.
static const IndexingType AllArrayTypes = 31;
diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
index 1a6c84514..1a7239f60 100644
--- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -31,7 +31,6 @@
#include "ExecutableAllocator.h"
#include "Heap.h"
-#include "HeapStatistics.h"
#include "Options.h"
#include "Identifier.h"
#include "JSDateMath.h"
@@ -57,15 +56,13 @@ static void initializeThreadingOnce()
WTF::initializeThreading();
GlobalJSLock::initialize();
Options::initialize();
- if (Options::recordGCPauseTimes())
- HeapStatistics::initialize();
#if ENABLE(WRITE_BARRIER_PROFILING)
WriteBarrierCounters::initialize();
#endif
#if ENABLE(ASSEMBLER)
ExecutableAllocator::initializeAllocator();
#endif
- JSStack::initializeThreading();
+ RegisterFile::initializeThreading();
#if ENABLE(LLINT)
LLInt::initialize();
#endif
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index afb5e6317..e2de03d92 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -29,12 +29,13 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction);
-const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
+const ClassInfo InternalFunction::s_info = { "Function", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure)
- : JSDestructibleObject(globalObject->globalData(), structure)
+ : JSNonFinalObject(globalObject->globalData(), structure)
{
}
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index daeebc34d..e26b9f953 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -24,16 +24,16 @@
#ifndef InternalFunction_h
#define InternalFunction_h
+#include "JSObject.h"
#include "Identifier.h"
-#include "JSDestructibleObject.h"
namespace JSC {
class FunctionPrototype;
- class InternalFunction : public JSDestructibleObject {
+ class InternalFunction : public JSNonFinalObject {
public:
- typedef JSDestructibleObject Base;
+ typedef JSNonFinalObject Base;
static JS_EXPORTDATA const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index 3b665962f..c34e10bc8 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -37,6 +37,8 @@ using namespace std;
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSActivation);
+
const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) };
void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -47,7 +49,7 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
Base::visitChildren(thisObject, visitor);
- // No need to mark our registers if they're still in the JSStack.
+ // No need to mark our registers if they're still in the RegisterFile.
if (!thisObject->isTornOff())
return;
@@ -114,11 +116,11 @@ void JSActivation::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec
SymbolTable::const_iterator end = thisObject->symbolTable()->end();
for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) {
- if (it->value.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
+ if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
continue;
- if (!thisObject->isValid(it->value))
+ if (!thisObject->isValid(it->second))
continue;
- propertyNames.add(Identifier(exec, it->key.get()));
+ propertyNames.add(Identifier(exec, it->first.get()));
}
// Skip the JSVariableObject implementation of getOwnNonIndexPropertyNames
JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
@@ -131,7 +133,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
SymbolTable::iterator iter = symbolTable()->find(propertyName.publicName());
if (iter == symbolTable()->end())
return false;
- SymbolTableEntry& entry = iter->value;
+ SymbolTableEntry& entry = iter->second;
ASSERT(!entry.isNull());
if (!isValid(entry))
return false;
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 7028c3b95..8398ae77d 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -44,6 +44,8 @@ using namespace WTF;
namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSArray);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSArray);
const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSArray)};
@@ -243,8 +245,8 @@ void JSArray::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pro
JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
}
-// This method makes room in the vector, but leaves the new space for count slots uncleared.
-bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, unsigned count)
+// This method makes room in the vector, but leaves the new space uncleared.
+bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count)
{
ArrayStorage* storage = ensureArrayStorage(globalData);
Butterfly* butterfly = storage->butterfly();
@@ -252,7 +254,7 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, un
unsigned propertySize = structure()->outOfLineSize();
// If not, we should have handled this on the fast path.
- ASSERT(!addToFront || count > storage->m_indexBias);
+ ASSERT(count > storage->m_indexBias);
// Step 1:
// Gather 4 key metrics:
@@ -276,7 +278,7 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, un
unsigned desiredCapacity = min(MAX_STORAGE_VECTOR_LENGTH, max(BASE_VECTOR_LEN, requiredVectorLength) << 1);
// Step 2:
- // We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing one.
+ // We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing on.
void* newAllocBase = 0;
unsigned newStorageCapacity;
@@ -295,48 +297,36 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, un
// Work out where we're going to move things to.
// Determine how much of the vector to use as pre-capacity, and how much as post-capacity.
- // If we're adding to the end, we'll add all the new space to the end.
// If the vector had no free post-capacity (length >= m_vectorLength), don't give it any.
// If it did, we calculate the amount that will remain based on an atomic decay - leave the
// vector with half the post-capacity it had previously.
unsigned postCapacity = 0;
- if (!addToFront)
- postCapacity = max(newStorageCapacity - requiredVectorLength, count);
- else if (length < storage->vectorLength()) {
+ if (length < storage->vectorLength()) {
// Atomic decay, + the post-capacity cannot be greater than what is available.
postCapacity = min((storage->vectorLength() - length) >> 1, newStorageCapacity - requiredVectorLength);
// If we're moving contents within the same allocation, the post-capacity is being reduced.
ASSERT(newAllocBase != butterfly->base(structure()) || postCapacity < storage->vectorLength() - length);
}
-
+
unsigned newVectorLength = requiredVectorLength + postCapacity;
unsigned newIndexBias = newStorageCapacity - newVectorLength;
Butterfly* newButterfly = Butterfly::fromBase(newAllocBase, newIndexBias, propertyCapacity);
-
- if (addToFront) {
- ASSERT(count + usedVectorLength <= newVectorLength);
- memmove(newButterfly->arrayStorage()->m_vector + count, storage->m_vector, sizeof(JSValue) * usedVectorLength);
- memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0));
- } else if ((newAllocBase != butterfly->base(structure())) || (newIndexBias != storage->m_indexBias)) {
- memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0));
- memmove(newButterfly->arrayStorage()->m_vector, storage->m_vector, sizeof(JSValue) * usedVectorLength);
-
- WriteBarrier<Unknown>* newVector = newButterfly->arrayStorage()->m_vector;
- for (unsigned i = requiredVectorLength; i < newVectorLength; i++)
- newVector[i].clear();
- }
-
+
+ memmove(newButterfly->arrayStorage()->m_vector + count, storage->m_vector, sizeof(JSValue) * usedVectorLength);
+ memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0));
+
newButterfly->arrayStorage()->setVectorLength(newVectorLength);
newButterfly->arrayStorage()->m_indexBias = newIndexBias;
-
+
m_butterfly = newButterfly;
return true;
}
-bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, bool throwException, ArrayStorage* storage)
+bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
{
+ ArrayStorage* storage = ensureArrayStorage(exec->globalData());
unsigned length = storage->length();
// If the length is read only then we enter sparse mode, so should enter the following 'if'.
@@ -353,7 +343,7 @@ bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo
keys.reserveCapacity(min(map->size(), static_cast<size_t>(length - newLength)));
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
- unsigned index = static_cast<unsigned>(it->key);
+ unsigned index = static_cast<unsigned>(it->first);
if (index < length && index >= newLength)
keys.append(index);
}
@@ -368,7 +358,7 @@ bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo
unsigned index = keys[--i];
SparseArrayValueMap::iterator it = map->find(index);
ASSERT(it != map->notFound());
- if (it->value.attributes & DontDelete) {
+ if (it->second.attributes & DontDelete) {
storage->setLength(index + 1);
return reject(exec, throwException, "Unable to delete property.");
}
@@ -399,71 +389,12 @@ bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo
return true;
}
-bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
-{
- switch (structure()->indexingType()) {
- case ArrayClass:
- if (!newLength)
- return true;
- if (newLength >= MIN_SPARSE_ARRAY_INDEX) {
- return setLengthWithArrayStorage(
- exec, newLength, throwException,
- convertContiguousToArrayStorage(exec->globalData()));
- }
- createInitialContiguous(exec->globalData(), newLength);
- return true;
-
- case ArrayWithContiguous:
- if (newLength == m_butterfly->publicLength())
- return true;
- if (newLength >= MAX_ARRAY_INDEX // This case ensures that we can do fast push.
- || (newLength >= MIN_SPARSE_ARRAY_INDEX
- && !isDenseEnoughForVector(newLength, countElementsInContiguous(m_butterfly)))) {
- return setLengthWithArrayStorage(
- exec, newLength, throwException,
- convertContiguousToArrayStorage(exec->globalData()));
- }
- if (newLength > m_butterfly->publicLength()) {
- ensureContiguousLength(exec->globalData(), newLength);
- return true;
- }
- for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
- m_butterfly->contiguous()[i].clear();
- m_butterfly->setPublicLength(newLength);
- return true;
-
- case ArrayWithArrayStorage:
- case ArrayWithSlowPutArrayStorage:
- return setLengthWithArrayStorage(exec, newLength, throwException, arrayStorage());
-
- default:
- CRASH();
- return false;
- }
-}
-
JSValue JSArray::pop(ExecState* exec)
{
switch (structure()->indexingType()) {
case ArrayClass:
return jsUndefined();
- case ArrayWithContiguous: {
- unsigned length = m_butterfly->publicLength();
-
- if (!length--)
- return jsUndefined();
-
- ASSERT(length < m_butterfly->vectorLength());
- JSValue value = m_butterfly->contiguous()[length].get();
- if (value) {
- m_butterfly->contiguous()[length].clear();
- m_butterfly->setPublicLength(length);
- return value;
- }
- break;
- }
-
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
@@ -487,28 +418,26 @@ JSValue JSArray::pop(ExecState* exec)
return element;
}
}
- break;
+
+ // Let element be the result of calling the [[Get]] internal method of O with argument indx.
+ JSValue element = get(exec, index);
+ if (exec->hadException())
+ return jsUndefined();
+ // Call the [[Delete]] internal method of O with arguments indx and true.
+ if (!deletePropertyByIndex(this, exec, index)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return jsUndefined();
+ }
+ // Call the [[Put]] internal method of O with arguments "length", indx, and true.
+ setLength(exec, index, true);
+ // Return element.
+ return element;
}
default:
- CRASH();
+ ASSERT_NOT_REACHED();
return JSValue();
}
-
- unsigned index = getArrayLength() - 1;
- // Let element be the result of calling the [[Get]] internal method of O with argument indx.
- JSValue element = get(exec, index);
- if (exec->hadException())
- return jsUndefined();
- // Call the [[Delete]] internal method of O with arguments indx and true.
- if (!deletePropertyByIndex(this, exec, index)) {
- throwTypeError(exec, "Unable to delete property.");
- return jsUndefined();
- }
- // Call the [[Put]] internal method of O with arguments "length", indx, and true.
- setLength(exec, index, true);
- // Return element.
- return element;
}
// Push & putIndex are almost identical, with two small differences.
@@ -522,26 +451,6 @@ void JSArray::push(ExecState* exec, JSValue value)
break;
}
- case ArrayWithContiguous: {
- unsigned length = m_butterfly->publicLength();
- ASSERT(length <= m_butterfly->vectorLength());
- if (length < m_butterfly->vectorLength()) {
- m_butterfly->contiguous()[length].set(exec->globalData(), this, value);
- m_butterfly->setPublicLength(length + 1);
- return;
- }
-
- if (length > MAX_ARRAY_INDEX) {
- methodTable()->putByIndex(this, exec, length, value, true);
- if (!exec->hadException())
- throwError(exec, createRangeError(exec, "Invalid array length"));
- return;
- }
-
- putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, length, value);
- return;
- }
-
case ArrayWithSlowPutArrayStorage: {
unsigned oldLength = length();
if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true)) {
@@ -583,139 +492,59 @@ void JSArray::push(ExecState* exec, JSValue value)
}
}
-bool JSArray::shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage* storage)
+bool JSArray::shiftCount(ExecState* exec, unsigned count)
{
+ ASSERT(count > 0);
+
+ ArrayStorage* storage = ensureArrayStorage(exec->globalData());
+
unsigned oldLength = storage->length();
ASSERT(count <= oldLength);
// If the array contains holes or is otherwise in an abnormal state,
// use the generic algorithm in ArrayPrototype.
- if (oldLength != storage->m_numValuesInVector || inSparseIndexingMode() || shouldUseSlowPut(structure()->indexingType()))
+ if (oldLength != storage->m_numValuesInVector || inSparseIndexingMode())
return false;
if (!oldLength)
return true;
- unsigned length = oldLength - count;
-
storage->m_numValuesInVector -= count;
- storage->setLength(length);
+ storage->setLength(oldLength - count);
unsigned vectorLength = storage->vectorLength();
- if (!vectorLength)
- return true;
-
- if (startIndex >= vectorLength)
- return true;
-
- if (startIndex + count > vectorLength)
- count = vectorLength - startIndex;
-
- unsigned usedVectorLength = min(vectorLength, oldLength);
-
- vectorLength -= count;
- storage->setVectorLength(vectorLength);
-
if (vectorLength) {
- if (startIndex < usedVectorLength - (startIndex + count)) {
- if (startIndex) {
- memmove(
- storage->m_vector + count,
- storage->m_vector,
- sizeof(JSValue) * startIndex);
- }
+ count = min(vectorLength, (unsigned)count);
+
+ vectorLength -= count;
+ storage->setVectorLength(vectorLength);
+
+ if (vectorLength) {
m_butterfly = m_butterfly->shift(structure(), count);
storage = m_butterfly->arrayStorage();
storage->m_indexBias += count;
- } else {
- memmove(
- storage->m_vector + startIndex,
- storage->m_vector + startIndex + count,
- sizeof(JSValue) * (usedVectorLength - (startIndex + count)));
- for (unsigned i = usedVectorLength - count; i < usedVectorLength; ++i)
- storage->m_vector[i].clear();
}
}
return true;
}
-bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex, unsigned count)
-{
- ASSERT(count > 0);
-
- switch (structure()->indexingType()) {
- case ArrayClass:
- return true;
-
- case ArrayWithContiguous: {
- unsigned oldLength = m_butterfly->publicLength();
- ASSERT(count <= oldLength);
-
- // We may have to walk the entire array to do the shift. We're willing to do
- // so only if it's not horribly slow.
- if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX)
- return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
-
- unsigned end = oldLength - count;
- for (unsigned i = startIndex; i < end; ++i) {
- // Storing to a hole is fine since we're still having a good time. But reading
- // from a hole is totally not fine, since we might have to read from the proto
- // chain.
- JSValue v = m_butterfly->contiguous()[i + count].get();
- if (UNLIKELY(!v)) {
- // The purpose of this path is to ensure that we don't make the same
- // mistake in the future: shiftCountWithArrayStorage() can't do anything
- // about holes (at least for now), but it can detect them quickly. So
- // we convert to array storage and then allow the array storage path to
- // figure it out.
- return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
- }
- // No need for a barrier since we're just moving data around in the same vector.
- // This is in line with our standing assumption that we won't have a deletion
- // barrier.
- m_butterfly->contiguous()[i].setWithoutWriteBarrier(v);
- }
- for (unsigned i = end; i < oldLength; ++i)
- m_butterfly->contiguous()[i].clear();
-
- m_butterfly->setPublicLength(oldLength - count);
- return true;
- }
-
- case ArrayWithArrayStorage:
- case ArrayWithSlowPutArrayStorage:
- return shiftCountWithArrayStorage(startIndex, count, arrayStorage());
-
- default:
- CRASH();
- return false;
- }
-}
-
// Returns true if the unshift can be handled, false to fallback.
-bool JSArray::unshiftCountWithArrayStorage(ExecState* exec, unsigned startIndex, unsigned count, ArrayStorage* storage)
+bool JSArray::unshiftCount(ExecState* exec, unsigned count)
{
+ ArrayStorage* storage = ensureArrayStorage(exec->globalData());
unsigned length = storage->length();
- ASSERT(startIndex <= length);
-
// If the array contains holes or is otherwise in an abnormal state,
// use the generic algorithm in ArrayPrototype.
- if (length != storage->m_numValuesInVector || storage->inSparseMode() || shouldUseSlowPut(structure()->indexingType()))
+ if (length != storage->m_numValuesInVector || storage->inSparseMode())
return false;
- bool moveFront = !startIndex || startIndex < length / 2;
-
- unsigned vectorLength = storage->vectorLength();
-
- if (moveFront && storage->m_indexBias >= count) {
+ if (storage->m_indexBias >= count) {
m_butterfly = storage->butterfly()->unshift(structure(), count);
storage = m_butterfly->arrayStorage();
storage->m_indexBias -= count;
- storage->setVectorLength(vectorLength + count);
- } else if (!moveFront && vectorLength - length >= count)
- storage = storage->butterfly()->arrayStorage();
- else if (unshiftCountSlowCase(exec->globalData(), moveFront, count))
+ storage->setVectorLength(storage->vectorLength() + count);
+ } else if (unshiftCountSlowCase(exec->globalData(), count))
storage = arrayStorage();
else {
throwOutOfMemoryError(exec);
@@ -723,61 +552,11 @@ bool JSArray::unshiftCountWithArrayStorage(ExecState* exec, unsigned startIndex,
}
WriteBarrier<Unknown>* vector = storage->m_vector;
-
- if (startIndex) {
- if (moveFront)
- memmove(vector, vector + count, startIndex * sizeof(JSValue));
- else if (length - startIndex)
- memmove(vector + startIndex + count, vector + startIndex, (length - startIndex) * sizeof(JSValue));
- }
-
for (unsigned i = 0; i < count; i++)
- vector[i + startIndex].clear();
+ vector[i].clear();
return true;
}
-bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex, unsigned count)
-{
- switch (structure()->indexingType()) {
- case ArrayClass:
- // We could handle this. But it shouldn't ever come up, so we won't.
- return false;
-
- case ArrayWithContiguous: {
- unsigned oldLength = m_butterfly->publicLength();
-
- // We may have to walk the entire array to do the unshift. We're willing to do so
- // only if it's not horribly slow.
- if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
- return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
-
- ensureContiguousLength(exec->globalData(), oldLength + count);
-
- for (unsigned i = oldLength; i-- > startIndex;) {
- JSValue v = m_butterfly->contiguous()[i].get();
- if (UNLIKELY(!v))
- return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData()));
- m_butterfly->contiguous()[i + count].setWithoutWriteBarrier(v);
- }
-
- // NOTE: we're leaving being garbage in the part of the array that we shifted out
- // of. This is fine because the caller is required to store over that area, and
- // in contiguous mode storing into a hole is guaranteed to behave exactly the same
- // as storing over an existing element.
-
- return true;
- }
-
- case ArrayWithArrayStorage:
- case ArrayWithSlowPutArrayStorage:
- return unshiftCountWithArrayStorage(exec, startIndex, count, arrayStorage());
-
- default:
- CRASH();
- return false;
- }
-}
-
static int compareNumbersForQSort(const void* a, const void* b)
{
double da = static_cast<const JSValue*>(a)->asNumber();
@@ -792,45 +571,6 @@ static int compareByStringPairForQSort(const void* a, const void* b)
return codePointCompare(va->second, vb->second);
}
-template<IndexingType indexingType>
-void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
- ASSERT(indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage);
-
- unsigned lengthNotIncludingUndefined;
- unsigned newRelevantLength;
- compactForSorting<indexingType>(
- lengthNotIncludingUndefined,
- newRelevantLength);
-
- WriteBarrier<Unknown>* data = indexingData<indexingType>();
-
- if (indexingType == ArrayWithArrayStorage && arrayStorage()->m_sparseMap.get()) {
- throwOutOfMemoryError(exec);
- return;
- }
-
- if (!lengthNotIncludingUndefined)
- return;
-
- bool allValuesAreNumbers = true;
- for (size_t i = 0; i < newRelevantLength; ++i) {
- if (!data[i].isNumber()) {
- allValuesAreNumbers = false;
- break;
- }
- }
-
- if (!allValuesAreNumbers)
- return sort(exec, compareFunction, callType, callData);
-
- // For numeric comparison, which is fast, qsort is faster than mergesort. We
- // also don't require mergesort's stability, since there's no user visible
- // side-effect from swapping the order of equal primitive values.
- qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort);
- return;
-}
-
void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
{
ASSERT(!inSparseIndexingMode());
@@ -839,98 +579,41 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
case ArrayClass:
return;
- case ArrayWithContiguous:
- sortNumericVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
- return;
-
- case ArrayWithArrayStorage:
- sortNumericVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData);
- return;
-
- default:
- CRASH();
- return;
- }
-}
-
-template<IndexingType indexingType>
-void JSArray::sortCompactedVector(ExecState* exec, WriteBarrier<Unknown>* begin, unsigned relevantLength)
-{
- if (!relevantLength)
- return;
-
- JSGlobalData& globalData = exec->globalData();
-
- // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
- // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
- // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
- // random or otherwise changing results, effectively making compare function inconsistent.
+ case ArrayWithArrayStorage: {
+ unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData());
+ ArrayStorage* storage = m_butterfly->arrayStorage();
- Vector<ValueStringPair> values(relevantLength);
- if (!values.begin()) {
- throwOutOfMemoryError(exec);
- return;
- }
+ if (storage->m_sparseMap.get()) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
- Heap::heap(this)->pushTempSortVector(&values);
+ if (!lengthNotIncludingUndefined)
+ return;
- bool isSortingPrimitiveValues = true;
- for (size_t i = 0; i < relevantLength; i++) {
- JSValue value = begin[i].get();
- ASSERT(!value.isUndefined());
- values[i].first = value;
- isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
- }
+ bool allValuesAreNumbers = true;
+ size_t size = storage->m_numValuesInVector;
+ for (size_t i = 0; i < size; ++i) {
+ if (!storage->m_vector[i].isNumber()) {
+ allValuesAreNumbers = false;
+ break;
+ }
+ }
- // FIXME: The following loop continues to call toString on subsequent values even after
- // a toString call raises an exception.
+ if (!allValuesAreNumbers)
+ return sort(exec, compareFunction, callType, callData);
- for (size_t i = 0; i < relevantLength; i++)
- values[i].second = values[i].first.toWTFStringInline(exec);
+ // For numeric comparison, which is fast, qsort is faster than mergesort. We
+ // also don't require mergesort's stability, since there's no user visible
+ // side-effect from swapping the order of equal primitive values.
+ qsort(storage->m_vector, size, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort);
- if (exec->hadException()) {
- Heap::heap(this)->popTempSortVector(&values);
return;
}
- // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather
- // than O(N log N).
-
-#if HAVE(MERGESORT)
- if (isSortingPrimitiveValues)
- qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
- else
- mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
-#else
- // FIXME: The qsort library function is likely to not be a stable sort.
- // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
- qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
-#endif
-
- // If the toString function changed the length of the array or vector storage,
- // increase the length to handle the orignal number of actual values.
- switch (indexingType) {
- case ArrayWithContiguous:
- ensureContiguousLength(globalData, relevantLength);
- break;
-
- case ArrayWithArrayStorage:
- if (arrayStorage()->vectorLength() < relevantLength) {
- increaseVectorLength(exec->globalData(), relevantLength);
- begin = arrayStorage()->m_vector;
- }
- if (arrayStorage()->length() < relevantLength)
- arrayStorage()->setLength(relevantLength);
- break;
-
default:
- CRASH();
+ ASSERT_NOT_REACHED();
}
-
- for (size_t i = 0; i < relevantLength; i++)
- begin[i].set(globalData, this, values[i].first);
-
- Heap::heap(this)->popTempSortVector(&values);
}
void JSArray::sort(ExecState* exec)
@@ -941,27 +624,78 @@ void JSArray::sort(ExecState* exec)
case ArrayClass:
return;
- case ArrayWithContiguous: {
- unsigned lengthNotIncludingUndefined;
- unsigned newRelevantLength;
- compactForSorting<ArrayWithContiguous>(
- lengthNotIncludingUndefined, newRelevantLength);
-
- sortCompactedVector<ArrayWithContiguous>(
- exec, m_butterfly->contiguous(), lengthNotIncludingUndefined);
- return;
- }
-
case ArrayWithArrayStorage: {
- unsigned lengthNotIncludingUndefined;
- unsigned newRelevantLength;
- compactForSorting<ArrayWithArrayStorage>(
- lengthNotIncludingUndefined, newRelevantLength);
+ unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData());
ArrayStorage* storage = m_butterfly->arrayStorage();
- ASSERT(!storage->m_sparseMap);
+ if (storage->m_sparseMap.get()) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ if (!lengthNotIncludingUndefined)
+ return;
+
+ // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
+ // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
+ // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
+ // random or otherwise changing results, effectively making compare function inconsistent.
+
+ Vector<ValueStringPair> values(lengthNotIncludingUndefined);
+ if (!values.begin()) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ Heap::heap(this)->pushTempSortVector(&values);
+
+ bool isSortingPrimitiveValues = true;
+ for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
+ JSValue value = storage->m_vector[i].get();
+ ASSERT(!value.isUndefined());
+ values[i].first = value;
+ isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
+ }
+
+ // FIXME: The following loop continues to call toString on subsequent values even after
+ // a toString call raises an exception.
+
+ for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
+ values[i].second = values[i].first.toWTFStringInline(exec);
+
+ if (exec->hadException()) {
+ Heap::heap(this)->popTempSortVector(&values);
+ return;
+ }
+
+ // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather
+ // than O(N log N).
+
+#if HAVE(MERGESORT)
+ if (isSortingPrimitiveValues)
+ qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
+ else
+ mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
+#else
+ // FIXME: The qsort library function is likely to not be a stable sort.
+ // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
+ qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
+#endif
+
+ // If the toString function changed the length of the array or vector storage,
+ // increase the length to handle the orignal number of actual values.
+ if (storage->vectorLength() < lengthNotIncludingUndefined) {
+ increaseVectorLength(exec->globalData(), lengthNotIncludingUndefined);
+ storage = m_butterfly->arrayStorage();
+ }
+ if (storage->length() < lengthNotIncludingUndefined)
+ storage->setLength(lengthNotIncludingUndefined);
+
+ JSGlobalData& globalData = exec->globalData();
+ for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
+ storage->m_vector[i].set(globalData, this, values[i].first);
+
+ Heap::heap(this)->popTempSortVector(&values);
- sortCompactedVector<ArrayWithArrayStorage>(
- exec, storage->m_vector, lengthNotIncludingUndefined);
return;
}
@@ -1047,116 +781,122 @@ struct AVLTreeAbstractorForArrayCompare {
static handle null() { return 0x7FFFFFFF; }
};
-template<IndexingType indexingType>
-void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
+void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
{
ASSERT(!inSparseIndexingMode());
- ASSERT(indexingType == structure()->indexingType());
- // FIXME: This ignores exceptions raised in the compare function or in toNumber.
-
- // The maximum tree depth is compiled in - but the caller is clearly up to no good
- // if a larger array is passed.
- ASSERT(m_butterfly->publicLength() <= static_cast<unsigned>(std::numeric_limits<int>::max()));
- if (m_butterfly->publicLength() > static_cast<unsigned>(std::numeric_limits<int>::max()))
+ switch (structure()->indexingType()) {
+ case ArrayClass:
return;
- unsigned usedVectorLength = relevantLength<indexingType>();
- unsigned nodeCount = usedVectorLength;
+ case ArrayWithArrayStorage: {
+ ArrayStorage* storage = m_butterfly->arrayStorage();
- if (!nodeCount)
- return;
+ // FIXME: This ignores exceptions raised in the compare function or in toNumber.
- AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
- tree.abstractor().m_exec = exec;
- tree.abstractor().m_compareFunction = compareFunction;
- tree.abstractor().m_compareCallType = callType;
- tree.abstractor().m_compareCallData = &callData;
- tree.abstractor().m_nodes.grow(nodeCount);
+ // The maximum tree depth is compiled in - but the caller is clearly up to no good
+ // if a larger array is passed.
+ ASSERT(storage->length() <= static_cast<unsigned>(std::numeric_limits<int>::max()));
+ if (storage->length() > static_cast<unsigned>(std::numeric_limits<int>::max()))
+ return;
- if (callType == CallTypeJS)
- tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, jsCast<JSFunction*>(compareFunction), 2));
+ unsigned usedVectorLength = min(storage->length(), storage->vectorLength());
+ unsigned nodeCount = usedVectorLength + (storage->m_sparseMap ? storage->m_sparseMap->size() : 0);
- if (!tree.abstractor().m_nodes.begin()) {
- throwOutOfMemoryError(exec);
- return;
- }
+ if (!nodeCount)
+ return;
- // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified
- // right out from under us while we're building the tree here.
-
- unsigned numDefined = 0;
- unsigned numUndefined = 0;
-
- // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
- for (; numDefined < usedVectorLength; ++numDefined) {
- if (numDefined > m_butterfly->vectorLength())
- break;
- JSValue v = indexingData<indexingType>()[numDefined].get();
- if (!v || v.isUndefined())
- break;
- tree.abstractor().m_nodes[numDefined].value = v;
- tree.insert(numDefined);
- }
- for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- if (i > m_butterfly->vectorLength())
- break;
- JSValue v = indexingData<indexingType>()[i].get();
- if (v) {
- if (v.isUndefined())
- ++numUndefined;
- else {
- tree.abstractor().m_nodes[numDefined].value = v;
+ AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
+ tree.abstractor().m_exec = exec;
+ tree.abstractor().m_compareFunction = compareFunction;
+ tree.abstractor().m_compareCallType = callType;
+ tree.abstractor().m_compareCallData = &callData;
+ tree.abstractor().m_nodes.grow(nodeCount);
+
+ if (callType == CallTypeJS)
+ tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, jsCast<JSFunction*>(compareFunction), 2));
+
+ if (!tree.abstractor().m_nodes.begin()) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified
+ // right out from under us while we're building the tree here.
+
+ unsigned numDefined = 0;
+ unsigned numUndefined = 0;
+
+ // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
+ for (; numDefined < usedVectorLength; ++numDefined) {
+ JSValue v = storage->m_vector[numDefined].get();
+ if (!v || v.isUndefined())
+ break;
+ tree.abstractor().m_nodes[numDefined].value = v;
+ tree.insert(numDefined);
+ }
+ for (unsigned i = numDefined; i < usedVectorLength; ++i) {
+ JSValue v = storage->m_vector[i].get();
+ if (v) {
+ if (v.isUndefined())
+ ++numUndefined;
+ else {
+ tree.abstractor().m_nodes[numDefined].value = v;
+ tree.insert(numDefined);
+ ++numDefined;
+ }
+ }
+ }
+
+ unsigned newUsedVectorLength = numDefined + numUndefined;
+
+ if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
+ newUsedVectorLength += map->size();
+ if (newUsedVectorLength > storage->vectorLength()) {
+ // Check that it is possible to allocate an array large enough to hold all the entries.
+ if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(exec->globalData(), newUsedVectorLength)) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+ storage = m_butterfly->arrayStorage();
+ }
+
+ SparseArrayValueMap::const_iterator end = map->end();
+ for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
+ tree.abstractor().m_nodes[numDefined].value = it->second.getNonSparseMode();
tree.insert(numDefined);
++numDefined;
}
+
+ deallocateSparseIndexMap();
}
- }
- unsigned newUsedVectorLength = numDefined + numUndefined;
+ ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
- // The array size may have changed. Figure out the new bounds.
- unsigned newestUsedVectorLength = relevantLength<indexingType>();
+ // FIXME: If the compare function changed the length of the array, the following might be
+ // modifying the vector incorrectly.
- unsigned elementsToExtractThreshold = min(min(newestUsedVectorLength, numDefined), static_cast<unsigned>(tree.abstractor().m_nodes.size()));
- unsigned undefinedElementsThreshold = min(newestUsedVectorLength, newUsedVectorLength);
- unsigned clearElementsThreshold = min(newestUsedVectorLength, usedVectorLength);
+ // Copy the values back into m_storage.
+ AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
+ iter.start_iter_least(tree);
+ JSGlobalData& globalData = exec->globalData();
+ for (unsigned i = 0; i < numDefined; ++i) {
+ storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
+ ++iter;
+ }
- // Copy the values back into m_storage.
- AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
- iter.start_iter_least(tree);
- JSGlobalData& globalData = exec->globalData();
- for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
- indexingData<indexingType>()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
- ++iter;
- }
- // Put undefined values back in.
- for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i)
- indexingData<indexingType>()[i].setUndefined();
-
- // Ensure that unused values in the vector are zeroed out.
- for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i)
- indexingData<indexingType>()[i].clear();
-
- if (hasArrayStorage(indexingType))
- arrayStorage()->m_numValuesInVector = newUsedVectorLength;
-}
-
-void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
-{
- ASSERT(!inSparseIndexingMode());
-
- switch (structure()->indexingType()) {
- case ArrayClass:
- return;
+ // Put undefined values back in.
+ for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
+ storage->m_vector[i].setUndefined();
+
+ // Ensure that unused values in the vector are zeroed out.
+ for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
+ storage->m_vector[i].clear();
+
+ storage->m_numValuesInVector = newUsedVectorLength;
- case ArrayWithContiguous:
- sortVector<ArrayWithContiguous>(exec, compareFunction, callType, callData);
- return;
-
- case ArrayWithArrayStorage:
- sortVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData);
return;
+ }
default:
ASSERT_NOT_REACHED();
@@ -1165,127 +905,129 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
- unsigned i = 0;
- unsigned vectorEnd;
- WriteBarrier<Unknown>* vector;
-
switch (structure()->indexingType()) {
case ArrayClass:
return;
-
- case ArrayWithContiguous: {
- vectorEnd = m_butterfly->publicLength();
- vector = m_butterfly->contiguous();
- break;
- }
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
- vector = storage->m_vector;
- vectorEnd = min(storage->length(), storage->vectorLength());
- break;
+ WriteBarrier<Unknown>* vector = storage->m_vector;
+ unsigned vectorEnd = min(storage->length(), storage->vectorLength());
+ unsigned i = 0;
+ for (; i < vectorEnd; ++i) {
+ WriteBarrier<Unknown>& v = vector[i];
+ if (!v)
+ break;
+ args.append(v.get());
+ }
+
+ for (; i < storage->length(); ++i)
+ args.append(get(exec, i));
+ return;
}
default:
- CRASH();
- vector = 0;
- vectorEnd = 0;
- break;
- }
-
- for (; i < vectorEnd; ++i) {
- WriteBarrier<Unknown>& v = vector[i];
- if (!v)
- break;
- args.append(v.get());
+ ASSERT_NOT_REACHED();
}
-
- for (; i < length(); ++i)
- args.append(get(exec, i));
}
void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length)
{
- unsigned i = 0;
- WriteBarrier<Unknown>* vector;
- unsigned vectorEnd;
-
ASSERT(length == this->length());
switch (structure()->indexingType()) {
case ArrayClass:
return;
- case ArrayWithContiguous: {
- vector = m_butterfly->contiguous();
- vectorEnd = m_butterfly->publicLength();
- break;
- }
-
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
- vector = storage->m_vector;
- vectorEnd = min(length, storage->vectorLength());
- break;
+ unsigned i = 0;
+ WriteBarrier<Unknown>* vector = storage->m_vector;
+ unsigned vectorEnd = min(length, storage->vectorLength());
+ for (; i < vectorEnd; ++i) {
+ WriteBarrier<Unknown>& v = vector[i];
+ if (!v)
+ break;
+ callFrame->setArgument(i, v.get());
+ }
+
+ for (; i < length; ++i)
+ callFrame->setArgument(i, get(exec, i));
+ return;
}
default:
- CRASH();
- vector = 0;
- vectorEnd = 0;
- break;
- }
-
- for (; i < vectorEnd; ++i) {
- WriteBarrier<Unknown>& v = vector[i];
- if (!v)
- break;
- callFrame->setArgument(i, v.get());
+ ASSERT_NOT_REACHED();
}
-
- for (; i < length; ++i)
- callFrame->setArgument(i, get(exec, i));
}
-template<IndexingType indexingType>
-void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLength)
+unsigned JSArray::compactForSorting(JSGlobalData& globalData)
{
ASSERT(!inSparseIndexingMode());
- ASSERT(indexingType == structure()->indexingType());
- unsigned myRelevantLength = relevantLength<indexingType>();
-
- numDefined = 0;
- unsigned numUndefined = 0;
+ switch (structure()->indexingType()) {
+ case ArrayClass:
+ return 0;
+
+ case ArrayWithArrayStorage: {
+ ArrayStorage* storage = m_butterfly->arrayStorage();
- for (; numDefined < myRelevantLength; ++numDefined) {
- JSValue v = indexingData<indexingType>()[numDefined].get();
- if (!v || v.isUndefined())
- break;
- }
+ unsigned usedVectorLength = min(storage->length(), storage->vectorLength());
- for (unsigned i = numDefined; i < myRelevantLength; ++i) {
- JSValue v = indexingData<indexingType>()[i].get();
- if (v) {
- if (v.isUndefined())
- ++numUndefined;
- else
- indexingData<indexingType>()[numDefined++].setWithoutWriteBarrier(v);
+ unsigned numDefined = 0;
+ unsigned numUndefined = 0;
+
+ for (; numDefined < usedVectorLength; ++numDefined) {
+ JSValue v = storage->m_vector[numDefined].get();
+ if (!v || v.isUndefined())
+ break;
}
+
+ for (unsigned i = numDefined; i < usedVectorLength; ++i) {
+ JSValue v = storage->m_vector[i].get();
+ if (v) {
+ if (v.isUndefined())
+ ++numUndefined;
+ else
+ storage->m_vector[numDefined++].setWithoutWriteBarrier(v);
+ }
+ }
+
+ unsigned newUsedVectorLength = numDefined + numUndefined;
+
+ if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
+ newUsedVectorLength += map->size();
+ if (newUsedVectorLength > storage->vectorLength()) {
+ // Check that it is possible to allocate an array large enough to hold all the entries - if not,
+ // exception is thrown by caller.
+ if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(globalData, newUsedVectorLength))
+ return 0;
+
+ storage = m_butterfly->arrayStorage();
+ }
+
+ SparseArrayValueMap::const_iterator end = map->end();
+ for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
+ storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.getNonSparseMode());
+
+ deallocateSparseIndexMap();
+ }
+
+ for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
+ storage->m_vector[i].setUndefined();
+ for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
+ storage->m_vector[i].clear();
+
+ storage->m_numValuesInVector = newUsedVectorLength;
+
+ return numDefined;
}
- newRelevantLength = numDefined + numUndefined;
-
- if (hasArrayStorage(indexingType))
- ASSERT(!arrayStorage()->m_sparseMap);
-
- for (unsigned i = numDefined; i < newRelevantLength; ++i)
- indexingData<indexingType>()[i].setUndefined();
- for (unsigned i = newRelevantLength; i < myRelevantLength; ++i)
- indexingData<indexingType>()[i].clear();
-
- if (hasArrayStorage(indexingType))
- arrayStorage()->m_numValuesInVector = newRelevantLength;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index d4622aacc..6e539c9db 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -71,60 +71,8 @@ namespace JSC {
void push(ExecState*, JSValue);
JSValue pop(ExecState*);
- enum ShiftCountMode {
- // This form of shift hints that we're doing queueing. With this assumption in hand,
- // we convert to ArrayStorage, which has queue optimizations.
- ShiftCountForShift,
-
- // This form of shift hints that we're just doing care and feeding on an array that
- // is probably typically used for ordinary accesses. With this assumption in hand,
- // we try to preserve whatever indexing type it has already.
- ShiftCountForSplice
- };
-
- bool shiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
- {
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
- }
- bool shiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
- {
- return shiftCountWithAnyIndexingType(exec, startIndex, count);
- }
- template<ShiftCountMode shiftCountMode>
- bool shiftCount(ExecState* exec, unsigned startIndex, unsigned count)
- {
- switch (shiftCountMode) {
- case ShiftCountForShift:
- return shiftCountForShift(exec, startIndex, count);
- case ShiftCountForSplice:
- return shiftCountForSplice(exec, startIndex, count);
- default:
- CRASH();
- return false;
- }
- }
-
- bool unshiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
- {
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
- }
- bool unshiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
- {
- return unshiftCountWithAnyIndexingType(exec, startIndex, count);
- }
- template<ShiftCountMode shiftCountMode>
- bool unshiftCount(ExecState* exec, unsigned startIndex, unsigned count)
- {
- switch (shiftCountMode) {
- case ShiftCountForShift:
- return unshiftCountForShift(exec, startIndex, count);
- case ShiftCountForSplice:
- return unshiftCountForSplice(exec, startIndex, count);
- default:
- CRASH();
- return false;
- }
- }
+ bool shiftCount(ExecState*, unsigned count);
+ bool unshiftCount(ExecState*, unsigned count);
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToArguments(ExecState*, CallFrame*, uint32_t length);
@@ -146,44 +94,18 @@ namespace JSC {
{
ArrayStorage* storage = arrayStorageOrNull();
if (!storage)
- return true;
+ return false;
SparseArrayValueMap* map = storage->m_sparseMap.get();
return !map || !map->lengthIsReadOnly();
}
-
- bool shiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
- bool shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage*);
-
- bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
- bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*);
- bool unshiftCountSlowCase(JSGlobalData&, bool, unsigned);
-
- template<IndexingType indexingType>
- void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
-
- template<IndexingType indexingType>
- void sortCompactedVector(ExecState*, WriteBarrier<Unknown>* begin, unsigned relevantLength);
-
- template<IndexingType indexingType>
- void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
- bool setLengthWithArrayStorage(ExecState*, unsigned newLength, bool throwException, ArrayStorage*);
void setLengthWritable(ExecState*, bool writable);
+
+ bool unshiftCountSlowCase(JSGlobalData&, unsigned count);
- template<IndexingType indexingType>
- void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
+ unsigned compactForSorting(JSGlobalData&);
};
- inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length)
- {
- IndexingHeader header;
- header.setVectorLength(std::max(length, BASE_VECTOR_LEN));
- header.setPublicLength(length);
- Butterfly* result = Butterfly::create(
- globalData, 0, 0, true, header, header.vectorLength() * sizeof(EncodedJSValue));
- return result;
- }
-
inline Butterfly* createArrayButterfly(JSGlobalData& globalData, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
@@ -199,16 +121,7 @@ namespace JSC {
inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
{
- Butterfly* butterfly;
- if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
- butterfly = createContiguousArrayButterfly(globalData, initialLength);
- ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
- } else {
- ASSERT(
- structure->indexingType() == ArrayWithSlowPutArrayStorage
- || (initialLength && structure->indexingType() == ArrayWithArrayStorage));
- butterfly = createArrayButterfly(globalData, initialLength);
- }
+ Butterfly* butterfly = createArrayButterfly(globalData, initialLength);
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
array->finishCreation(globalData);
return array;
@@ -220,26 +133,15 @@ namespace JSC {
if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
return 0;
- Butterfly* butterfly;
- if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
-
- void* temp;
- if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
- return 0;
- butterfly = Butterfly::fromBase(temp, 0, 0);
- butterfly->setVectorLength(vectorLength);
- butterfly->setPublicLength(initialLength);
- } else {
- void* temp;
- if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
- return 0;
- butterfly = Butterfly::fromBase(temp, 0, 0);
- *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
- ArrayStorage* storage = butterfly->arrayStorage();
- storage->m_indexBias = 0;
- storage->m_sparseMap.clear();
- storage->m_numValuesInVector = initialLength;
- }
+ void* temp;
+ if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
+ return 0;
+ Butterfly* butterfly = Butterfly::fromBase(temp, 0, 0);
+ *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
+ ArrayStorage* storage = butterfly->arrayStorage();
+ storage->m_indexBias = 0;
+ storage->m_sparseMap.clear();
+ storage->m_numValuesInVector = initialLength;
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
array->finishCreation(globalData);
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
index d8f611477..3815c144e 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
@@ -31,6 +31,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSBoundFunction);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSBoundFunction);
const ClassInfo JSBoundFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSBoundFunction) };
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index f6f4d716d..739247fb2 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -38,10 +38,6 @@ void JSCell::destroy(JSCell* cell)
cell->JSCell::~JSCell();
}
-void JSCell::copyBackingStore(JSCell*, CopyVisitor&)
-{
-}
-
bool JSCell::getString(ExecState* exec, String& stringValue) const
{
if (!isString())
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index a39af1283..cf6f4ec45 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -31,15 +31,12 @@
#include "JSValueInlineMethods.h"
#include "SlotVisitor.h"
#include "SlotVisitorInlineMethods.h"
-#include "TypedArrayDescriptor.h"
#include "WriteBarrier.h"
#include <wtf/Noncopyable.h>
#include <wtf/TypeTraits.h>
namespace JSC {
- class CopyVisitor;
- class JSDestructibleObject;
class JSGlobalObject;
class LLIntOffsetsExtractor;
class PropertyDescriptor;
@@ -51,6 +48,19 @@ namespace JSC {
IncludeDontEnumProperties
};
+ enum TypedArrayType {
+ TypedArrayNone,
+ TypedArrayInt8,
+ TypedArrayInt16,
+ TypedArrayInt32,
+ TypedArrayUint8,
+ TypedArrayUint8Clamped,
+ TypedArrayUint16,
+ TypedArrayUint32,
+ TypedArrayFloat32,
+ TypedArrayFloat64
+ };
+
class JSCell {
friend class JSValue;
friend class MarkedBlock;
@@ -60,9 +70,6 @@ namespace JSC {
public:
static const unsigned StructureFlags = 0;
- static const bool needsDestruction = false;
- static const bool hasImmortalStructure = false;
-
enum CreatingEarlyCellTag { CreatingEarlyCell };
JSCell(CreatingEarlyCellTag);
@@ -101,7 +108,6 @@ namespace JSC {
JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
static void visitChildren(JSCell*, SlotVisitor&);
- JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&);
// Object operations, with the toObject operation included.
const ClassInfo* classInfo() const;
@@ -303,29 +309,46 @@ namespace JSC {
return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
}
+ template<class T>
+ struct NeedsDestructor {
+ static const bool value = !WTF::HasTrivialDestructor<T>::value;
+ };
+
template<typename T>
- void* allocateCell(Heap& heap, size_t size)
+ void* allocateCell(Heap& heap)
{
- ASSERT(size >= sizeof(T));
#if ENABLE(GC_VALIDATION)
ASSERT(!heap.globalData()->isInitializingObject());
heap.globalData()->setInitializingObjectClass(&T::s_info);
#endif
JSCell* result = 0;
- if (T::needsDestruction && T::hasImmortalStructure)
- result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
- else if (T::needsDestruction && !T::hasImmortalStructure)
- result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
- else
- result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
+ if (NeedsDestructor<T>::value)
+ result = static_cast<JSCell*>(heap.allocateWithDestructor(sizeof(T)));
+ else {
+ ASSERT(T::s_info.methodTable.destroy == JSCell::destroy);
+ result = static_cast<JSCell*>(heap.allocateWithoutDestructor(sizeof(T)));
+ }
result->clearStructure();
return result;
}
template<typename T>
- void* allocateCell(Heap& heap)
+ void* allocateCell(Heap& heap, size_t size)
{
- return allocateCell<T>(heap, sizeof(T));
+ ASSERT(size >= sizeof(T));
+#if ENABLE(GC_VALIDATION)
+ ASSERT(!heap.globalData()->isInitializingObject());
+ heap.globalData()->setInitializingObjectClass(&T::s_info);
+#endif
+ JSCell* result = 0;
+ if (NeedsDestructor<T>::value)
+ result = static_cast<JSCell*>(heap.allocateWithDestructor(size));
+ else {
+ ASSERT(T::s_info.methodTable.destroy == JSCell::destroy);
+ result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
+ }
+ result->clearStructure();
+ return result;
}
inline bool isZapped(const JSCell* cell)
@@ -339,7 +362,7 @@ namespace JSC {
ASSERT(!from || from->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info));
return static_cast<To>(from);
}
-
+
template<typename To>
inline To jsCast(JSValue from)
{
diff --git a/Source/JavaScriptCore/runtime/JSDestructibleObject.h b/Source/JavaScriptCore/runtime/JSDestructibleObject.h
deleted file mode 100644
index b8479be62..000000000
--- a/Source/JavaScriptCore/runtime/JSDestructibleObject.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef JSDestructibleObject_h
-#define JSDestructibleObject_h
-
-#include "JSObject.h"
-
-namespace JSC {
-
-struct ClassInfo;
-
-class JSDestructibleObject : public JSNonFinalObject {
-public:
- typedef JSNonFinalObject Base;
-
- static const bool needsDestruction = true;
-
- const ClassInfo* classInfo() const { return m_classInfo; }
-
-protected:
- JSDestructibleObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0)
- : JSNonFinalObject(globalData, structure, butterfly)
- , m_classInfo(structure->classInfo())
- {
- ASSERT(m_classInfo);
- }
-
-private:
- const ClassInfo* m_classInfo;
-};
-
-inline const ClassInfo* JSCell::classInfo() const
-{
- if (MarkedBlock::blockFor(this)->destructorType() == MarkedBlock::Normal)
- return static_cast<const JSDestructibleObject*>(this)->classInfo();
-#if ENABLE(GC_VALIDATION)
- return m_structure.unvalidatedGet()->classInfo();
-#else
- return m_structure->classInfo();
-#endif
-}
-
-} // namespace JSC
-
-#endif
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 891a23930..4afe63216 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -48,6 +48,7 @@ EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec)
return throwVMError(exec, createNotAConstructorError(exec, exec->callee()));
}
+ASSERT_CLASS_FITS_IN_CELL(JSFunction);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFunction);
const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) };
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index bc3d00067..e30a7913d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -231,9 +231,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
interpreter->initialize(this->canUseJIT());
-#if ENABLE(JIT)
initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support.
-#endif
heap.notifyIsSafeToCollect();
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 6cc0aad8d..603f9f82a 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -44,7 +44,6 @@
#include "Strong.h"
#include "Terminator.h"
#include "TimeoutChecker.h"
-#include "TypedArrayDescriptor.h"
#include "WeakRandom.h"
#include <wtf/BumpPointerAllocator.h>
#include <wtf/Forward.h>
@@ -109,6 +108,24 @@ namespace JSC {
ThreadStackTypeSmall
};
+ struct TypedArrayDescriptor {
+ TypedArrayDescriptor()
+ : m_classInfo(0)
+ , m_storageOffset(0)
+ , m_lengthOffset(0)
+ {
+ }
+ TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset)
+ : m_classInfo(classInfo)
+ , m_storageOffset(storageOffset)
+ , m_lengthOffset(lengthOffset)
+ {
+ }
+ const ClassInfo* m_classInfo;
+ size_t m_storageOffset;
+ size_t m_lengthOffset;
+ };
+
#if ENABLE(DFG_JIT)
class ConservativeRoots;
@@ -412,35 +429,6 @@ namespace JSC {
registerTypedArrayFunction(float32, Float32);
registerTypedArrayFunction(float64, Float64);
#undef registerTypedArrayFunction
-
- const TypedArrayDescriptor* typedArrayDescriptor(TypedArrayType type) const
- {
- switch (type) {
- case TypedArrayNone:
- return 0;
- case TypedArrayInt8:
- return &int8ArrayDescriptor();
- case TypedArrayInt16:
- return &int16ArrayDescriptor();
- case TypedArrayInt32:
- return &int32ArrayDescriptor();
- case TypedArrayUint8:
- return &uint8ArrayDescriptor();
- case TypedArrayUint8Clamped:
- return &uint8ClampedArrayDescriptor();
- case TypedArrayUint16:
- return &uint16ArrayDescriptor();
- case TypedArrayUint32:
- return &uint32ArrayDescriptor();
- case TypedArrayFloat32:
- return &float32ArrayDescriptor();
- case TypedArrayFloat64:
- return &float64ArrayDescriptor();
- default:
- CRASH();
- return 0;
- }
- }
JSLock& apiLock() { return m_apiLock; }
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 9eb266135..b0a0e8122 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -100,6 +100,8 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &all
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject);
+
// Default number of ticks before a timeout check should be done.
static const int initialTickCountThreshold = 255;
@@ -226,11 +228,10 @@ void JSGlobalObject::reset(JSValue prototype)
m_callbackFunctionStructure.set(exec->globalData(), this, JSCallbackFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), this, m_objectPrototype.get()));
m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), this, m_objectPrototype.get()));
- m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
+ m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSNonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous));
- m_arrayStructureWithArrayStorage.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
+ m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
@@ -317,9 +318,6 @@ void JSGlobalObject::reset(JSValue prototype)
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
-
- m_specialPointers[Special::CallFunction] = m_callFunction.get();
- m_specialPointers[Special::ApplyFunction] = m_applyFunction.get();
if (m_experimentsEnabled) {
NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()));
@@ -356,8 +354,7 @@ ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder(
inline bool hasBrokenIndexing(JSObject* object)
{
// This will change if we have more indexing types.
- IndexingType type = object->structure()->indexingType();
- return hasContiguous(type) || hasFastArrayStorage(type);
+ return !!(object->structure()->indexingType() & HasArrayStorage);
}
void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
@@ -410,7 +407,6 @@ void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
// Make sure that all JSArray allocations that load the appropriate structure from
// this object now load a structure that uses SlowPut.
m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get());
- m_arrayStructureWithArrayStorage.set(globalData, this, m_arrayStructureForSlowPut.get());
// Make sure that all objects that have indexed storage switch to the slow kind of
// indexed storage.
@@ -486,7 +482,6 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_nameScopeStructure);
visitor.append(&thisObject->m_argumentsStructure);
visitor.append(&thisObject->m_arrayStructure);
- visitor.append(&thisObject->m_arrayStructureWithArrayStorage);
visitor.append(&thisObject->m_arrayStructureForSlowPut);
visitor.append(&thisObject->m_booleanObjectStructure);
visitor.append(&thisObject->m_callbackConstructorStructure);
@@ -507,14 +502,9 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_internalFunctionStructure);
}
-JSObject* JSGlobalObject::toThisObject(JSCell* cell, ExecState*)
-{
- return jsCast<JSGlobalObject*>(cell)->globalThis();
-}
-
ExecState* JSGlobalObject::globalExec()
{
- return CallFrame::create(m_globalCallFrame + JSStack::CallFrameHeaderSize);
+ return CallFrame::create(m_globalCallFrame + RegisterFile::CallFrameHeaderSize);
}
void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 2994aa64b..ad56783cc 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -24,10 +24,10 @@
#include "JSArray.h"
#include "JSGlobalData.h"
+#include "JSGlobalThis.h"
#include "JSSegmentedVariableObject.h"
#include "JSWeakObjectMapRefInternal.h"
#include "NumberPrototype.h"
-#include "SpecialPointer.h"
#include "StringPrototype.h"
#include "StructureChain.h"
#include "Watchpoint.h"
@@ -46,12 +46,12 @@ namespace JSC {
class FunctionPrototype;
class GetterSetter;
class GlobalCodeBlock;
- class JSStack;
class LLIntOffsetsExtractor;
class NativeErrorConstructor;
class ProgramCodeBlock;
class RegExpConstructor;
class RegExpPrototype;
+ class RegisterFile;
struct ActivationStackNode;
struct HashTable;
@@ -77,6 +77,7 @@ namespace JSC {
class JSGlobalObject : public JSSegmentedVariableObject {
private:
+ typedef JSSegmentedVariableObject Base;
typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
struct JSGlobalObjectRareData {
@@ -91,7 +92,7 @@ namespace JSC {
protected:
- Register m_globalCallFrame[JSStack::CallFrameHeaderSize];
+ Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
WriteBarrier<JSObject> m_globalThis;
WriteBarrier<JSObject> m_methodCallDummy;
@@ -126,7 +127,6 @@ namespace JSC {
WriteBarrier<Structure> m_nameScopeStructure;
WriteBarrier<Structure> m_argumentsStructure;
WriteBarrier<Structure> m_arrayStructure; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time.
- WriteBarrier<Structure> m_arrayStructureWithArrayStorage; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time.
WriteBarrier<Structure> m_arrayStructureForSlowPut;
WriteBarrier<Structure> m_booleanObjectStructure;
WriteBarrier<Structure> m_callbackConstructorStructure;
@@ -146,8 +146,6 @@ namespace JSC {
WriteBarrier<Structure> m_regExpStructure;
WriteBarrier<Structure> m_stringObjectStructure;
WriteBarrier<Structure> m_internalFunctionStructure;
-
- void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
Debugger* m_debugger;
@@ -170,16 +168,14 @@ namespace JSC {
if (m_rareData)
return;
m_rareData = adoptPtr(new JSGlobalObjectRareData);
+ Heap::heap(this)->addFinalizer(this, clearRareData);
}
public:
- typedef JSSegmentedVariableObject Base;
-
static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure)
{
JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure);
globalObject->finishCreation(globalData);
- globalData.heap.addFinalizer(globalObject, destroy);
return globalObject;
}
@@ -196,7 +192,7 @@ namespace JSC {
init(this);
}
- void finishCreation(JSGlobalData& globalData, JSObject* thisValue)
+ void finishCreation(JSGlobalData& globalData, JSGlobalThis* thisValue)
{
Base::finishCreation(globalData);
structure()->setGlobalObject(globalData, this);
@@ -207,8 +203,6 @@ namespace JSC {
public:
JS_EXPORT_PRIVATE ~JSGlobalObject();
JS_EXPORT_PRIVATE static void destroy(JSCell*);
- // We don't need a destructor because we use a finalizer instead.
- static const bool needsDestruction = false;
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
@@ -268,9 +262,7 @@ namespace JSC {
Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
Structure* arrayStructure() const { return m_arrayStructure.get(); }
- Structure* arrayStructureWithArrayStorage() const { return m_arrayStructureWithArrayStorage.get(); }
void* addressOfArrayStructure() { return &m_arrayStructure; }
- void* addressOfArrayStructureWithArrayStorage() { return &m_arrayStructureWithArrayStorage; }
Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
@@ -290,12 +282,6 @@ namespace JSC {
Structure* regExpStructure() const { return m_regExpStructure.get(); }
Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
- void* actualPointerFor(Special::Pointer pointer)
- {
- ASSERT(pointer < Special::TableSize);
- return m_specialPointers[pointer];
- }
-
WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
@@ -380,16 +366,13 @@ namespace JSC {
};
JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
- JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*);
-
- JS_EXPORT_PRIVATE void setGlobalThis(JSGlobalData&, JSObject* globalThis);
-
private:
friend class LLIntOffsetsExtractor;
// FIXME: Fold reset into init.
JS_EXPORT_PRIVATE void init(JSObject* thisValue);
void reset(JSValue prototype);
+ void setGlobalThis(JSGlobalData&, JSObject* globalThis);
void createThrowTypeError(ExecState*);
@@ -482,7 +465,7 @@ namespace JSC {
inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength = 0)
{
- return JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureWithArrayStorage() : globalObject->arrayStructure(), initialLength);
+ return JSArray::create(exec->globalData(), globalObject->arrayStructure(), initialLength);
}
inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength = 0)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.cpp b/Source/JavaScriptCore/runtime/JSGlobalThis.cpp
new file mode 100644
index 000000000..a3f2e7785
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSGlobalThis.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalThis.h"
+
+#include "JSGlobalObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSGlobalThis);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSGlobalThis);
+
+const ClassInfo JSGlobalThis::s_info = { "JSGlobalThis", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSGlobalThis) };
+
+void JSGlobalThis::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ JSGlobalThis* thisObject = jsCast<JSGlobalThis*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
+
+ COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
+ ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
+
+ Base::visitChildren(thisObject, visitor);
+ visitor.append(&thisObject->m_unwrappedObject);
+}
+
+void JSGlobalThis::setUnwrappedObject(JSGlobalData& globalData, JSGlobalObject* globalObject)
+{
+ ASSERT_ARG(globalObject, globalObject);
+ m_unwrappedObject.set(globalData, this, globalObject);
+ setPrototype(globalData, globalObject->prototype());
+ resetInheritorID(globalData);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.h b/Source/JavaScriptCore/runtime/JSGlobalThis.h
new file mode 100644
index 000000000..0ca99414a
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSGlobalThis.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSGlobalThis_h
+#define JSGlobalThis_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class JSGlobalThis : public JSNonFinalObject {
+public:
+ typedef JSNonFinalObject Base;
+
+ static JSGlobalThis* create(JSGlobalData& globalData, Structure* structure)
+ {
+ JSGlobalThis* globalThis = new (NotNull, allocateCell<JSGlobalThis>(globalData.heap)) JSGlobalThis(globalData, structure);
+ globalThis->finishCreation(globalData);
+ return globalThis;
+ }
+
+ static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+ {
+ return Structure::create(globalData, 0, prototype, TypeInfo(GlobalThisType, StructureFlags), &s_info);
+ }
+
+ static JS_EXPORTDATA const JSC::ClassInfo s_info;
+
+ JSGlobalObject* unwrappedObject() const { return m_unwrappedObject.get(); }
+
+protected:
+ JSGlobalThis(JSGlobalData& globalData, Structure* structure)
+ : JSNonFinalObject(globalData, structure)
+ {
+ }
+
+ void finishCreation(JSGlobalData& globalData)
+ {
+ Base::finishCreation(globalData);
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
+
+ JS_EXPORT_PRIVATE void setUnwrappedObject(JSGlobalData&, JSGlobalObject*);
+
+private:
+ WriteBarrier<JSGlobalObject> m_unwrappedObject;
+};
+
+} // namespace JSC
+
+#endif // JSGlobalThis_h
diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp
index 85dbdfedb..9f02b69b8 100644
--- a/Source/JavaScriptCore/runtime/JSLock.cpp
+++ b/Source/JavaScriptCore/runtime/JSLock.cpp
@@ -140,13 +140,13 @@ bool JSLock::currentThreadIsHoldingLock()
// context if the thread leaves JSC by making a call out to an external
// function through a callback.
//
-// All threads using the context share the same JS stack (the JSStack).
-// Whenever a thread calls into JSC it starts using the JSStack from the
+// All threads using the context share the same JS stack (the RegisterFile).
+// Whenever a thread calls into JSC it starts using the RegisterFile from the
// previous 'high water mark' - the maximum point the stack has ever grown to
-// (returned by JSStack::end()). So if a first thread calls out to a
+// (returned by RegisterFile::end()). So if a first thread calls out to a
// callback, and a second thread enters JSC, then also exits by calling out
// to a callback, we can be left with stackframes from both threads in the
-// JSStack. As such, a problem may occur should the first thread's
+// RegisterFile. As such, a problem may occur should the first thread's
// callback complete first, and attempt to return to JSC. Were we to allow
// this to happen, and were its stack to grow further, then it may potentially
// write over the second thread's call frames.
diff --git a/Source/JavaScriptCore/runtime/JSNameScope.cpp b/Source/JavaScriptCore/runtime/JSNameScope.cpp
index 335631fd0..5dc665c44 100644
--- a/Source/JavaScriptCore/runtime/JSNameScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSNameScope.cpp
@@ -30,6 +30,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSNameScope);
+
const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNameScope) };
void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
index 53592ba2b..f75fa1f96 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -34,6 +34,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSNotAnObject);
const ClassInfo JSNotAnObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNotAnObject) };
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index fd939934e..fe894afba 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -41,6 +41,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSONObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSONObject);
static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*);
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 6a3fb84e4..bf38f6876 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -26,14 +26,13 @@
#include "ButterflyInlineMethods.h"
#include "CopiedSpaceInlineMethods.h"
-#include "CopyVisitor.h"
-#include "CopyVisitorInlineMethods.h"
#include "DatePrototype.h"
#include "ErrorConstructor.h"
#include "GetterSetter.h"
#include "IndexingHeaderInlineMethods.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "JSGlobalThis.h"
#include "Lookup.h"
#include "NativeErrorConstructor.h"
#include "Nodes.h"
@@ -64,6 +63,10 @@ JSCell* getCallableObjectSlow(JSCell* cell)
return 0;
}
+ASSERT_CLASS_FITS_IN_CELL(JSObject);
+ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
+ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
+
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFinalObject);
@@ -92,7 +95,7 @@ static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* class
}
}
-ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butterfly, size_t storageSize)
+ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* butterfly, size_t storageSize)
{
ASSERT(butterfly);
@@ -109,93 +112,61 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt
preCapacity = 0;
indexingPayloadSizeInBytes = 0;
}
- size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
- if (visitor.checkIfShouldCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes)) {
+ size_t capacityInBytes = Butterfly::totalSize(
+ preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+ if (visitor.checkIfShouldCopyAndPinOtherwise(
+ butterfly->base(preCapacity, propertyCapacity), capacityInBytes)) {
Butterfly* newButterfly = Butterfly::createUninitializedDuringCollection(visitor, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
- // Copy the properties.
+ // Mark and copy the properties.
PropertyStorage currentTarget = newButterfly->propertyStorage();
PropertyStorage currentSource = butterfly->propertyStorage();
- for (size_t count = storageSize; count--;)
- (--currentTarget)->setWithoutWriteBarrier((--currentSource)->get());
+ for (size_t count = storageSize; count--;) {
+ JSValue value = (--currentSource)->get();
+ ASSERT(value);
+ visitor.appendUnbarrieredValue(&value);
+ (--currentTarget)->setWithoutWriteBarrier(value);
+ }
if (UNLIKELY(hasIndexingHeader)) {
*newButterfly->indexingHeader() = *butterfly->indexingHeader();
- // Copy the array if appropriate.
-
- WriteBarrier<Unknown>* currentTarget;
- WriteBarrier<Unknown>* currentSource;
- size_t count;
-
+ // Mark and copy the array if appropriate.
switch (structure->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- currentTarget = newButterfly->contiguous();
- currentSource = butterfly->contiguous();
- ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength());
- count = newButterfly->vectorLength();
- break;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
newButterfly->arrayStorage()->copyHeaderFromDuringGC(*butterfly->arrayStorage());
- currentTarget = newButterfly->arrayStorage()->m_vector;
- currentSource = butterfly->arrayStorage()->m_vector;
- count = newButterfly->arrayStorage()->vectorLength();
+ WriteBarrier<Unknown>* currentTarget = newButterfly->arrayStorage()->m_vector;
+ WriteBarrier<Unknown>* currentSource = butterfly->arrayStorage()->m_vector;
+ for (size_t count = newButterfly->arrayStorage()->vectorLength(); count--;) {
+ JSValue value = (currentSource++)->get();
+ if (value)
+ visitor.appendUnbarrieredValue(&value);
+ (currentTarget++)->setWithoutWriteBarrier(value);
+ }
+ if (newButterfly->arrayStorage()->m_sparseMap)
+ visitor.append(&newButterfly->arrayStorage()->m_sparseMap);
break;
}
default:
- CRASH();
- currentTarget = 0;
- currentSource = 0;
- count = 0;
break;
}
-
- while (count--)
- (currentTarget++)->setWithoutWriteBarrier((currentSource++)->get());
}
m_butterfly = newButterfly;
- visitor.didCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes);
- }
-}
-
-ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* butterfly, size_t storageSize)
-{
- ASSERT(butterfly);
-
- Structure* structure = this->structure();
-
- size_t propertyCapacity = structure->outOfLineCapacity();
- size_t preCapacity;
- size_t indexingPayloadSizeInBytes;
- bool hasIndexingHeader = JSC::hasIndexingHeader(structure->indexingType());
- if (UNLIKELY(hasIndexingHeader)) {
- preCapacity = butterfly->indexingHeader()->preCapacity(structure);
- indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure);
} else {
- preCapacity = 0;
- indexingPayloadSizeInBytes = 0;
- }
- size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
-
- // Mark the properties.
- visitor.appendValues(butterfly->propertyStorage() - storageSize, storageSize);
- visitor.copyLater(butterfly->base(preCapacity, propertyCapacity), capacityInBytes);
-
- // Mark the array if appropriate.
- switch (structure->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- visitor.appendValues(butterfly->contiguous(), butterfly->publicLength());
- break;
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength());
- if (butterfly->arrayStorage()->m_sparseMap)
- visitor.append(&butterfly->arrayStorage()->m_sparseMap);
- break;
- default:
- break;
+ // Mark the properties.
+ visitor.appendValues(butterfly->propertyStorage() - storageSize, storageSize);
+
+ // Mark the array if appropriate.
+ switch (structure->indexingType()) {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength());
+ if (butterfly->arrayStorage()->m_sparseMap)
+ visitor.append(&butterfly->arrayStorage()->m_sparseMap);
+ break;
+ default:
+ break;
+ }
}
}
@@ -212,23 +183,13 @@ void JSObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
Butterfly* butterfly = thisObject->butterfly();
if (butterfly)
- thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize());
+ thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSizeForKnownNonFinalObject());
#if !ASSERT_DISABLED
visitor.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation;
#endif
}
-void JSObject::copyBackingStore(JSCell* cell, CopyVisitor& visitor)
-{
- JSObject* thisObject = jsCast<JSObject*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
-
- Butterfly* butterfly = thisObject->butterfly();
- if (butterfly)
- thisObject->copyButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize());
-}
-
void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSFinalObject* thisObject = jsCast<JSFinalObject*>(cell);
@@ -242,9 +203,9 @@ void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
Butterfly* butterfly = thisObject->butterfly();
if (butterfly)
- thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize());
+ thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSizeForKnownFinalObject());
- size_t storageSize = thisObject->structure()->inlineSize();
+ size_t storageSize = thisObject->structure()->inlineSizeForKnownFinalObject();
visitor.appendValues(thisObject->inlineStorage(), storageSize);
#if !ASSERT_DISABLED
@@ -274,20 +235,6 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- Butterfly* butterfly = thisObject->m_butterfly;
- if (i >= butterfly->vectorLength())
- return false;
-
- JSValue value = butterfly->contiguous()[i].get();
- if (value) {
- slot.setValue(value);
- return true;
- }
-
- return false;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
if (i >= storage->length())
@@ -302,7 +249,7 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
} else if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->notFound()) {
- it->value.get(slot);
+ it->second.get(slot);
return true;
}
}
@@ -405,16 +352,6 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- Butterfly* butterfly = thisObject->m_butterfly;
- if (propertyName >= butterfly->vectorLength())
- break;
- butterfly->contiguous()[propertyName].set(exec->globalData(), thisObject, value);
- if (propertyName >= butterfly->publicLength())
- butterfly->setPublicLength(propertyName + 1);
- return;
- }
-
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
@@ -489,7 +426,7 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists
// This will always be a new entry in the map, so no need to check we can write,
// and attributes are default so no need to set them.
if (value)
- map->add(this, i).iterator->value.set(globalData, this, value);
+ map->add(this, i).iterator->second.set(globalData, this, value);
}
Butterfly* newButterfly = storage->butterfly()->resizeArray(globalData, structure(), 0, ArrayStorage::sizeFor(0));
@@ -507,11 +444,6 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists
void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- // NOTE: this is horribly inefficient, as it will perform two conversions. We could optimize
- // this case if we ever cared.
- enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
- break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
break;
@@ -534,24 +466,6 @@ void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData)
globalObject()->haveABadTime(globalData);
}
-WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length)
-{
- ASSERT(length < MAX_ARRAY_INDEX);
- IndexingType oldType = structure()->indexingType();
- ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
- ASSERT(!structure()->needsSlowPutIndexing());
- ASSERT(!indexingShouldBeSparse());
- unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
- Butterfly* newButterfly = m_butterfly->growArrayRight(
- globalData, structure(), structure()->outOfLineCapacity(), false, 0,
- sizeof(EncodedJSValue) * vectorLength);
- newButterfly->setPublicLength(length);
- newButterfly->setVectorLength(vectorLength);
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous);
- setButterfly(globalData, newButterfly, newStructure);
- return newButterfly->contiguous();
-}
-
ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned length, unsigned vectorLength)
{
IndexingType oldType = structure()->indexingType();
@@ -567,7 +481,7 @@ ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned le
result->m_sparseMap.clear();
result->m_numValuesInVector = 0;
result->m_indexBias = 0;
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedArrayStorageTransition());
+ Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedIndexingTransition());
setButterfly(globalData, newButterfly, newStructure);
return result;
}
@@ -577,107 +491,9 @@ ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData)
return createArrayStorage(globalData, 0, BASE_VECTOR_LEN);
}
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
-{
- ASSERT(hasContiguous(structure()->indexingType()));
-
- unsigned publicLength = m_butterfly->publicLength();
- unsigned propertyCapacity = structure()->outOfLineCapacity();
- unsigned propertySize = structure()->outOfLineSize();
-
- Butterfly* newButterfly = Butterfly::createUninitialized(
- globalData, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength));
-
- memcpy(
- newButterfly->propertyStorage() - propertySize,
- m_butterfly->propertyStorage() - propertySize,
- propertySize * sizeof(EncodedJSValue));
-
- ArrayStorage* newStorage = newButterfly->arrayStorage();
- newStorage->setVectorLength(neededLength);
- newStorage->setLength(publicLength);
- newStorage->m_sparseMap.clear();
- newStorage->m_indexBias = 0;
- newStorage->m_numValuesInVector = 0;
- for (unsigned i = publicLength; i--;) {
- JSValue v = m_butterfly->contiguous()[i].get();
- if (!v)
- continue;
- newStorage->m_vector[i].setWithoutWriteBarrier(v);
- newStorage->m_numValuesInVector++;
- }
-
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newButterfly, newStructure);
- return newStorage;
-}
-
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
-{
- return convertContiguousToArrayStorage(globalData, transition, m_butterfly->vectorLength());
-}
-
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData)
-{
- return convertContiguousToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
-}
-
-WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData)
-{
- switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialContiguous(globalData, 0);
-
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
-ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData)
-{
- switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- ASSERT(!indexingShouldBeSparse());
- ASSERT(!structure()->needsSlowPutIndexing());
- return convertContiguousToArrayStorage(globalData);
-
- case ALL_BLANK_INDEXING_TYPES:
- if (UNLIKELY(indexingShouldBeSparse()))
- return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData);
- return createInitialArrayStorage(globalData);
-
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
-Butterfly* JSObject::ensureIndexedStorageSlow(JSGlobalData& globalData)
-{
- switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- if (UNLIKELY(structure()->needsSlowPutIndexing()))
- return createInitialArrayStorage(globalData)->butterfly();
- if (UNLIKELY(indexingShouldBeSparse()))
- return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)->butterfly();
- return Butterfly::fromContiguous(createInitialContiguous(globalData, 0));
-
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- // FIXME: This could be made way more efficient, if we cared.
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
@@ -697,11 +513,6 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J
void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- convertContiguousToArrayStorage(globalData, AllocateSlowPutArrayStorage);
- break;
- }
-
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage: {
Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), SwitchToSlowPutArrayStorage);
@@ -745,7 +556,8 @@ void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
if (shouldUseSlowPut(structure()->indexingType()))
return;
- switchToSlowPutArrayStorage(globalData);
+ newStructure = Structure::nonPropertyTransition(globalData, newStructure, SwitchToSlowPutArrayStorage);
+ setStructure(globalData, newStructure);
}
bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
@@ -879,14 +691,6 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
case ALL_BLANK_INDEXING_TYPES:
return true;
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- Butterfly* butterfly = thisObject->m_butterfly;
- if (i >= butterfly->vectorLength())
- return true;
- butterfly->contiguous()[i].clear();
- return true;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
@@ -899,7 +703,7 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
} else if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->notFound()) {
- if (it->value.attributes & DontDelete)
+ if (it->second.attributes & DontDelete)
return false;
map->remove(it);
}
@@ -1060,17 +864,6 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- Butterfly* butterfly = object->m_butterfly;
- unsigned usedLength = butterfly->publicLength();
- for (unsigned i = 0; i < usedLength; ++i) {
- if (!butterfly->contiguous()[i])
- continue;
- propertyNames.add(Identifier::from(exec, i));
- }
- break;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
@@ -1086,8 +879,8 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
- if (mode == IncludeDontEnumProperties || !(it->value.attributes & DontEnum))
- keys.append(static_cast<unsigned>(it->key));
+ if (mode == IncludeDontEnumProperties || !(it->second.attributes & DontEnum))
+ keys.append(static_cast<unsigned>(it->first));
}
std::sort(keys.begin(), keys.end());
@@ -1296,6 +1089,9 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert
{
ASSERT(index <= MAX_ARRAY_INDEX);
+ if (descriptor.attributes() & (ReadOnly | Accessor))
+ notifyPresenceOfIndexedAccessors(exec->globalData());
+
if (!inSparseIndexingMode()) {
// Fast case: we're putting a regular property to a regular array
// FIXME: this will pessimistically assume that if attributes are missing then they'll default to false
@@ -1305,19 +1101,16 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert
ASSERT(!descriptor.isAccessorDescriptor());
return putDirectIndex(exec, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
}
-
+
ensureArrayStorageExistsAndEnterDictionaryIndexingMode(exec->globalData());
}
- if (descriptor.attributes() & (ReadOnly | Accessor))
- notifyPresenceOfIndexedAccessors(exec->globalData());
-
SparseArrayValueMap* map = m_butterfly->arrayStorage()->m_sparseMap.get();
ASSERT(map);
// 1. Let current be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
SparseArrayValueMap::AddResult result = map->add(this, index);
- SparseArrayEntry* entryInMap = &result.iterator->value;
+ SparseArrayEntry* entryInMap = &result.iterator->second;
// 2. Let extensible be the value of the [[Extensible]] internal property of O.
// 3. If current is undefined and extensible is false, then Reject.
@@ -1437,8 +1230,8 @@ bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, J
ArrayStorage* storage = current->arrayStorageOrNull();
if (storage && storage->m_sparseMap) {
SparseArrayValueMap::iterator iter = storage->m_sparseMap->find(i);
- if (iter != storage->m_sparseMap->notFound() && (iter->value.attributes & (Accessor | ReadOnly))) {
- iter->value.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow);
+ if (iter != storage->m_sparseMap->notFound() && (iter->second.attributes & (Accessor | ReadOnly))) {
+ iter->second.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow);
return true;
}
}
@@ -1460,35 +1253,6 @@ bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, J
return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow);
}
-void JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState* exec, unsigned i, JSValue value)
-{
- ASSERT(hasContiguous(structure()->indexingType()));
- ASSERT(!indexingShouldBeSparse());
-
- // For us to get here, the index is either greater than the public length, or greater than
- // or equal to the vector length.
- ASSERT(i >= m_butterfly->vectorLength());
-
- JSGlobalData& globalData = exec->globalData();
-
- if (i >= MAX_ARRAY_INDEX - 1
- || (i >= MIN_SPARSE_ARRAY_INDEX
- && !isDenseEnoughForVector(i, countElementsInContiguous(m_butterfly)))) {
- ASSERT(i <= MAX_ARRAY_INDEX);
- convertContiguousToArrayStorage(globalData, AllocateArrayStorage);
- SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
- map->putEntry(exec, this, i, value, false);
- ASSERT(i >= arrayStorage()->length());
- arrayStorage()->setLength(i + 1);
- return;
- }
-
- ensureContiguousLength(globalData, i + 1);
-
- ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, value);
-}
-
void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage)
{
JSGlobalData& globalData = exec->globalData();
@@ -1551,7 +1315,7 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns
WriteBarrier<Unknown>* vector = storage->m_vector;
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
- vector[it->key].set(globalData, this, it->value.getNonSparseMode());
+ vector[it->first].set(globalData, this, it->second.getNonSparseMode());
deallocateSparseIndexMap();
// Store the new property into the vector.
@@ -1571,29 +1335,17 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES: {
if (indexingShouldBeSparse()) {
- putByIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, shouldThrow,
- ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
- break;
- }
- if (i >= MIN_SPARSE_ARRAY_INDEX) {
- putByIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, shouldThrow, createArrayStorage(globalData, 0, 0));
+ putByIndexBeyondVectorLengthWithArrayStorage(exec, i, value, shouldThrow, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
break;
}
- if (structure()->needsSlowPutIndexing()) {
- ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
- storage->m_vector[i].set(globalData, this, value);
- storage->m_numValuesInVector++;
+ if (!isDenseEnoughForVector(i, 0) || i >= MAX_STORAGE_VECTOR_LENGTH) {
+ putByIndexBeyondVectorLengthWithArrayStorage(exec, i, value, shouldThrow, createArrayStorage(globalData, 0, 0));
break;
}
-
- createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value);
- break;
- }
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value);
+ ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
+ storage->m_vector[i].set(globalData, this, value);
+ storage->m_numValuesInVector = 1;
break;
}
@@ -1619,10 +1371,8 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode, ArrayStorage* storage)
{
JSGlobalData& globalData = exec->globalData();
-
+
// i should be a valid array index that is outside of the current vector.
- ASSERT(hasArrayStorage(structure()->indexingType()));
- ASSERT(arrayStorage() == storage);
ASSERT(i >= storage->vectorLength() || attributes);
ASSERT(i <= MAX_ARRAY_INDEX);
@@ -1681,7 +1431,7 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec,
WriteBarrier<Unknown>* vector = storage->m_vector;
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
- vector[it->key].set(globalData, this, it->value.getNonSparseMode());
+ vector[it->first].set(globalData, this, it->second.getNonSparseMode());
deallocateSparseIndexMap();
// Store the new property into the vector.
@@ -1704,32 +1454,14 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES: {
- if (indexingShouldBeSparse() || attributes) {
- return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode,
- ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
- }
- if (i >= MIN_SPARSE_ARRAY_INDEX) {
- return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, createArrayStorage(globalData, 0, 0));
- }
- if (structure()->needsSlowPutIndexing()) {
- ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
- storage->m_vector[i].set(globalData, this, value);
- storage->m_numValuesInVector++;
- return true;
- }
+ if (indexingShouldBeSparse() || attributes)
+ return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
+ if (!isDenseEnoughForVector(i, 0) || i >= MAX_STORAGE_VECTOR_LENGTH)
+ return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, createArrayStorage(globalData, 0, 0));
- createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value);
- return true;
- }
-
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- if (attributes & (ReadOnly | Accessor)) {
- return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertContiguousToArrayStorage(globalData));
- }
- putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value);
+ ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
+ storage->m_vector[i].set(globalData, this, value);
+ storage->m_numValuesInVector = 1;
return true;
}
@@ -1754,7 +1486,12 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned currentVectorLength
else if (!currentVectorLength)
increasedLength = std::max(desiredLength, lastArraySize);
else {
- increasedLength = timesThreePlusOneDividedByTwo(desiredLength);
+ // Mathematically equivalent to:
+ // increasedLength = (newLength * 3 + 1) / 2;
+ // or:
+ // increasedLength = (unsigned)ceil(newLength * 1.5));
+ // This form is not prone to internal overflow.
+ increasedLength = desiredLength + (desiredLength >> 1) + (desiredLength & 1);
}
ASSERT(increasedLength >= desiredLength);
@@ -1774,10 +1511,9 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength)
vectorLength = 0;
length = 0;
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- vectorLength = m_butterfly->vectorLength();
- length = m_butterfly->publicLength();
+ vectorLength = m_butterfly->arrayStorage()->vectorLength();
+ length = m_butterfly->arrayStorage()->length();
break;
default:
CRASH();
@@ -1786,16 +1522,6 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength)
return getNewVectorLength(vectorLength, length, desiredLength);
}
-unsigned JSObject::countElementsInContiguous(Butterfly* butterfly)
-{
- unsigned numValues = 0;
- for (unsigned i = butterfly->publicLength(); i--;) {
- if (butterfly->contiguous()[i])
- numValues++;
- }
- return numValues;
-}
-
bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength)
{
// This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
@@ -1804,10 +1530,6 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
return false;
ArrayStorage* storage = arrayStorage();
-
- if (newLength >= MIN_SPARSE_ARRAY_INDEX
- && !isDenseEnoughForVector(newLength, storage->m_numValuesInVector))
- return false;
unsigned indexBias = storage->m_indexBias;
unsigned vectorLength = storage->vectorLength();
@@ -1839,22 +1561,6 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
return true;
}
-void JSObject::ensureContiguousLengthSlow(JSGlobalData& globalData, unsigned length)
-{
- ASSERT(length < MAX_ARRAY_INDEX);
- ASSERT(hasContiguous(structure()->indexingType()));
- ASSERT(length > m_butterfly->vectorLength());
-
- unsigned newVectorLength = std::min(
- length << 1,
- MAX_STORAGE_VECTOR_LENGTH);
- m_butterfly = m_butterfly->growArrayRight(
- globalData, structure(), structure()->outOfLineCapacity(), true,
- m_butterfly->vectorLength() * sizeof(EncodedJSValue),
- newVectorLength * sizeof(EncodedJSValue));
- m_butterfly->setVectorLength(newVectorLength);
-}
-
Butterfly* JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
{
ASSERT(newSize > oldSize);
@@ -1883,17 +1589,6 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- Butterfly* butterfly = object->m_butterfly;
- if (i >= butterfly->vectorLength())
- return false;
- JSValue value = butterfly->contiguous()[i].get();
- if (!value)
- return false;
- descriptor.setDescriptor(value, 0);
- return true;
- }
-
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
if (i >= storage->length())
@@ -1909,7 +1604,7 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
SparseArrayValueMap::iterator it = map->find(i);
if (it == map->notFound())
return false;
- it->value.get(descriptor);
+ it->second.get(descriptor);
return true;
}
return false;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 9204099cb..4b9cff5ad 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -109,13 +109,7 @@ namespace JSC {
public:
typedef JSCell Base;
- static size_t allocationSize(size_t inlineCapacity)
- {
- return sizeof(JSObject) + inlineCapacity * sizeof(WriteBarrierBase<Unknown>);
- }
-
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&);
JS_EXPORT_PRIVATE static String className(const JSObject*);
@@ -154,9 +148,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return 0;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->publicLength();
+ return m_butterfly->arrayStorage()->length();
default:
ASSERT_NOT_REACHED();
return 0;
@@ -168,9 +161,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return 0;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->vectorLength();
+ return m_butterfly->arrayStorage()->vectorLength();
default:
ASSERT_NOT_REACHED();
return 0;
@@ -215,8 +207,6 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return i < m_butterfly->vectorLength() && m_butterfly->contiguous()[i];
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i];
default:
@@ -228,8 +218,6 @@ namespace JSC {
JSValue getIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->contiguous()[i].get();
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_vector[i].get();
default:
@@ -243,13 +231,12 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
break;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- if (i < m_butterfly->publicLength())
- return m_butterfly->contiguous()[i].get();
- break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- if (i < m_butterfly->arrayStorage()->vectorLength())
- return m_butterfly->arrayStorage()->m_vector[i].get();
+ if (i < m_butterfly->arrayStorage()->vectorLength()) {
+ JSValue v = m_butterfly->arrayStorage()->m_vector[i].get();
+ if (v)
+ return v;
+ }
break;
default:
ASSERT_NOT_REACHED();
@@ -280,10 +267,9 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage:
- return i < m_butterfly->vectorLength();
+ return i < m_butterfly->arrayStorage()->vectorLength();
case NonArrayWithSlowPutArrayStorage:
case ArrayWithSlowPutArrayStorage:
return i < m_butterfly->arrayStorage()->vectorLength()
@@ -299,9 +285,8 @@ namespace JSC {
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
return false;
- case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return i < m_butterfly->vectorLength();
+ return i < m_butterfly->arrayStorage()->vectorLength();
default:
ASSERT_NOT_REACHED();
return false;
@@ -311,23 +296,15 @@ namespace JSC {
void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
- if (i >= m_butterfly->publicLength())
- m_butterfly->setPublicLength(i + 1);
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
- ArrayStorage* storage = m_butterfly->arrayStorage();
- WriteBarrier<Unknown>& x = storage->m_vector[i];
- JSValue old = x.get();
- x.set(globalData, this, v);
- if (!old) {
+ WriteBarrier<Unknown>& x = m_butterfly->arrayStorage()->m_vector[i];
+ if (!x) {
+ ArrayStorage* storage = m_butterfly->arrayStorage();
++storage->m_numValuesInVector;
if (i >= storage->length())
storage->setLength(i + 1);
}
+ x.set(globalData, this, v);
break;
}
default:
@@ -338,12 +315,6 @@ namespace JSC {
void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case ALL_CONTIGUOUS_INDEXING_TYPES: {
- ASSERT(i < m_butterfly->publicLength());
- ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
- break;
- }
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
ASSERT(i < storage->length());
@@ -356,25 +327,10 @@ namespace JSC {
}
}
- bool hasSparseMap()
- {
- switch (structure()->indexingType()) {
- case ALL_BLANK_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return false;
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_sparseMap;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
- }
-
bool inSparseIndexingMode()
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
- case ALL_CONTIGUOUS_INDEXING_TYPES:
return false;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->inSparseMode();
@@ -492,10 +448,10 @@ namespace JSC {
{
PropertyOffset result;
size_t offsetInInlineStorage = location - inlineStorageUnsafe();
- if (offsetInInlineStorage < static_cast<size_t>(firstOutOfLineOffset))
+ if (offsetInInlineStorage < static_cast<size_t>(inlineStorageCapacity))
result = offsetInInlineStorage;
else
- result = outOfLineStorage() - location + (firstOutOfLineOffset - 1);
+ result = outOfLineStorage() - location + (inlineStorageCapacity - 1);
validateOffset(result, structure()->typeInfo().type());
return result;
}
@@ -525,7 +481,7 @@ namespace JSC {
bool isNameScopeObject() const;
bool isActivationObject() const;
bool isErrorInstance() const;
- bool isProxy() const;
+ bool isGlobalThis() const;
void seal(JSGlobalData&);
void freeze(JSGlobalData&);
@@ -572,34 +528,23 @@ namespace JSC {
// foo->attemptToInterceptPutByIndexOnHole(...);
bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow);
- // Returns 0 if contiguous storage cannot be created - either because
- // indexing should be sparse or because we're having a bad time.
- WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData)
- {
- if (LIKELY(hasContiguous(structure()->indexingType())))
- return m_butterfly->contiguous();
-
- return ensureContiguousSlow(globalData);
- }
-
// Ensure that the object is in a mode where it has array storage. Use
// this if you're about to perform actions that would have required the
// object to be converted to have array storage, if it didn't have it
// already.
ArrayStorage* ensureArrayStorage(JSGlobalData& globalData)
{
- if (LIKELY(hasArrayStorage(structure()->indexingType())))
+ switch (structure()->indexingType()) {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage();
-
- return ensureArrayStorageSlow(globalData);
- }
-
- Butterfly* ensureIndexedStorage(JSGlobalData& globalData)
- {
- if (LIKELY(hasIndexedProperties(structure()->indexingType())))
- return m_butterfly;
-
- return ensureIndexedStorageSlow(globalData);
+
+ case ALL_BLANK_INDEXING_TYPES:
+ return createInitialArrayStorage(globalData);
+
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
}
static size_t offsetOfInlineStorage();
@@ -640,7 +585,6 @@ namespace JSC {
void resetInheritorID(JSGlobalData&);
void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize);
- void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize);
// Call this if you know that the object is in a mode where it has array
// storage. This will assert otherwise.
@@ -665,16 +609,11 @@ namespace JSC {
ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength);
ArrayStorage* createInitialArrayStorage(JSGlobalData&);
- WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&);
ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&);
bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
- void putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState*, unsigned propertyName, JSValue);
void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*);
bool increaseVectorLength(JSGlobalData&, unsigned newLength);
@@ -685,56 +624,6 @@ namespace JSC {
void notifyPresenceOfIndexedAccessors(JSGlobalData&);
bool attemptToInterceptPutByIndexOnHole(ExecState*, unsigned index, JSValue, bool shouldThrow);
-
- // Call this if you want setIndexQuickly to succeed and you're sure that
- // the array is contiguous.
- void ensureContiguousLength(JSGlobalData& globalData, unsigned length)
- {
- ASSERT(length < MAX_ARRAY_INDEX);
- ASSERT(hasContiguous(structure()->indexingType()));
-
- if (m_butterfly->vectorLength() < length)
- ensureContiguousLengthSlow(globalData, length);
-
- if (m_butterfly->publicLength() < length)
- m_butterfly->setPublicLength(length);
- }
-
- unsigned countElementsInContiguous(Butterfly*);
-
- template<IndexingType indexingType>
- WriteBarrier<Unknown>* indexingData()
- {
- switch (indexingType) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->contiguous();
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_vector;
-
- default:
- CRASH();
- return 0;
- }
- }
-
- template<IndexingType indexingType>
- unsigned relevantLength()
- {
- switch (indexingType) {
- case ALL_CONTIGUOUS_INDEXING_TYPES:
- return m_butterfly->publicLength();
-
- case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return std::min(
- m_butterfly->arrayStorage()->length(),
- m_butterfly->arrayStorage()->vectorLength());
-
- default:
- CRASH();
- return 0;
- }
- }
private:
friend class LLIntOffsetsExtractor;
@@ -769,12 +658,6 @@ namespace JSC {
JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&);
- void ensureContiguousLengthSlow(JSGlobalData&, unsigned length);
-
- WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&);
- ArrayStorage* ensureArrayStorageSlow(JSGlobalData&);
- Butterfly* ensureIndexedStorageSlow(JSGlobalData&);
-
protected:
Butterfly* m_butterfly;
};
@@ -794,6 +677,11 @@ namespace JSC {
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
+ static bool hasInlineStorage()
+ {
+ return false;
+ }
+
protected:
explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0)
: JSObject(globalData, structure, butterfly)
@@ -821,43 +709,45 @@ namespace JSC {
static JSFinalObject* create(ExecState*, Structure*);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info, NonArray, INLINE_STORAGE_CAPACITY);
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info);
}
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
static JS_EXPORTDATA const ClassInfo s_info;
+ static bool hasInlineStorage()
+ {
+ return true;
+ }
protected:
void visitChildrenCommon(SlotVisitor&);
void finishCreation(JSGlobalData& globalData)
{
Base::finishCreation(globalData);
- ASSERT(structure()->totalStorageCapacity() == structure()->inlineCapacity());
+ ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double)));
+ ASSERT(this->structure()->inlineCapacity() == static_cast<unsigned>(inlineStorageCapacity));
+ ASSERT(this->structure()->totalStorageCapacity() == static_cast<unsigned>(inlineStorageCapacity));
ASSERT(classInfo());
}
private:
friend class LLIntOffsetsExtractor;
-
+
explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
: JSObject(globalData, structure)
{
}
static const unsigned StructureFlags = JSObject::StructureFlags;
+
+ WriteBarrierBase<Unknown> m_inlineStorage[INLINE_STORAGE_CAPACITY];
};
inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure)
{
- JSFinalObject* finalObject = new (
- NotNull,
- allocateCell<JSFinalObject>(
- *exec->heap(),
- allocationSize(structure->inlineCapacity())
- )
- ) JSFinalObject(exec->globalData(), structure);
+ JSFinalObject* finalObject = new (NotNull, allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure);
finalObject->finishCreation(exec->globalData());
return finalObject;
}
@@ -874,7 +764,7 @@ inline bool isJSFinalObject(JSValue value)
inline size_t JSObject::offsetOfInlineStorage()
{
- return sizeof(JSObject);
+ return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage);
}
inline bool JSObject::isGlobalObject() const
@@ -902,9 +792,9 @@ inline bool JSObject::isErrorInstance() const
return structure()->typeInfo().type() == ErrorInstanceType;
}
-inline bool JSObject::isProxy() const
+inline bool JSObject::isGlobalThis() const
{
- return structure()->typeInfo().type() == ProxyType;
+ return structure()->typeInfo().type() == GlobalThisType;
}
inline void JSObject::setButterfly(JSGlobalData& globalData, Butterfly* butterfly, Structure* structure)
@@ -966,14 +856,14 @@ inline JSValue JSObject::prototype() const
return structure()->storedPrototype();
}
-inline const MethodTable* JSCell::methodTable() const
+inline bool JSCell::inherits(const ClassInfo* info) const
{
- return &classInfo()->methodTable;
+ return classInfo()->isSubClassOf(info);
}
-inline bool JSCell::inherits(const ClassInfo* info) const
+inline const MethodTable* JSCell::methodTable() const
{
- return classInfo()->isSubClassOf(info);
+ return &classInfo()->methodTable;
}
// this method is here to be after the inline declaration of JSCell::inherits
@@ -1367,8 +1257,6 @@ inline int offsetRelativeToBase(PropertyOffset offset)
return JSObject::offsetOfInlineStorage() + offsetInInlineStorage(offset) * sizeof(EncodedJSValue);
}
-COMPILE_ASSERT(!(sizeof(JSObject) % sizeof(WriteBarrierBase<Unknown>)), JSObject_inline_storage_has_correct_alignment);
-
} // namespace JSC
#endif // JSObject_h
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 225401fbd..897ceff8c 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -33,6 +33,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
+
const ClassInfo JSPropertyNameIterator::s_info = { "JSPropertyNameIterator", 0, 0, 0, CREATE_METHOD_TABLE(JSPropertyNameIterator) };
inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index e59a5c6a4..057ffe293 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -48,8 +48,6 @@ namespace JSC {
static JSPropertyNameIterator* create(ExecState*, JSObject*);
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
@@ -59,6 +57,14 @@ namespace JSC {
static void visitChildren(JSCell*, SlotVisitor&);
+ bool getOffset(size_t i, PropertyOffset& offset)
+ {
+ if (i >= m_numCacheableSlots)
+ return false;
+ offset = i + m_offsetBase;
+ return true;
+ }
+
JSValue get(ExecState*, JSObject*, size_t i);
size_t size() { return m_jsStringsSize; }
@@ -82,7 +88,7 @@ namespace JSC {
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
for (size_t i = 0; i < m_jsStringsSize; ++i)
m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].string()));
- m_cachedStructureInlineCapacity = object->structure()->inlineCapacity();
+ m_offsetBase = object->structure()->firstValidOffset();
}
private:
@@ -94,7 +100,7 @@ namespace JSC {
WriteBarrier<StructureChain> m_cachedPrototypeChain;
uint32_t m_numCacheableSlots;
uint32_t m_jsStringsSize;
- unsigned m_cachedStructureInlineCapacity;
+ PropertyOffset m_offsetBase;
OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
};
diff --git a/Source/JavaScriptCore/runtime/JSProxy.cpp b/Source/JavaScriptCore/runtime/JSProxy.cpp
deleted file mode 100644
index 7108dcfa0..000000000
--- a/Source/JavaScriptCore/runtime/JSProxy.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSProxy.h"
-
-#include "JSGlobalObject.h"
-
-namespace JSC {
-
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSProxy);
-
-const ClassInfo JSProxy::s_info = { "JSProxy", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSProxy) };
-
-void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
-
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
- Base::visitChildren(thisObject, visitor);
- visitor.append(&thisObject->m_target);
-}
-
-void JSProxy::setTarget(JSGlobalData& globalData, JSGlobalObject* globalObject)
-{
- ASSERT_ARG(globalObject, globalObject);
- m_target.set(globalData, this, globalObject);
- setPrototype(globalData, globalObject->prototype());
- resetInheritorID(globalData);
-}
-
-String JSProxy::className(const JSObject* object)
-{
- const JSProxy* thisObject = jsCast<const JSProxy*>(object);
- return thisObject->target()->methodTable()->className(thisObject->target());
-}
-
-bool JSProxy::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- return thisObject->target()->methodTable()->getOwnPropertySlot(thisObject->target(), exec, propertyName, slot);
-}
-
-bool JSProxy::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- return thisObject->target()->methodTable()->getOwnPropertySlotByIndex(thisObject->target(), exec, propertyName, slot);
-}
-
-bool JSProxy::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(object);
- return thisObject->target()->methodTable()->getOwnPropertyDescriptor(thisObject->target(), exec, propertyName, descriptor);
-}
-
-void JSProxy::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- thisObject->target()->methodTable()->put(thisObject->target(), exec, propertyName, value, slot);
-}
-
-void JSProxy::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- thisObject->target()->methodTable()->putByIndex(thisObject->target(), exec, propertyName, value, shouldThrow);
-}
-
-void JSProxy::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(object);
- thisObject->target()->putDirectVirtual(thisObject->target(), exec, propertyName, value, attributes);
-}
-
-bool JSProxy::defineOwnProperty(JSC::JSObject* object, JSC::ExecState* exec, JSC::PropertyName propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(object);
- return thisObject->target()->methodTable()->defineOwnProperty(thisObject->target(), exec, propertyName, descriptor, shouldThrow);
-}
-
-bool JSProxy::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- return thisObject->target()->methodTable()->deleteProperty(thisObject->target(), exec, propertyName);
-}
-
-bool JSProxy::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(cell);
- return thisObject->target()->methodTable()->deletePropertyByIndex(thisObject->target(), exec, propertyName);
-}
-
-void JSProxy::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(object);
- thisObject->target()->methodTable()->getPropertyNames(thisObject->target(), exec, propertyNames, mode);
-}
-
-void JSProxy::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- JSProxy* thisObject = jsCast<JSProxy*>(object);
- thisObject->target()->methodTable()->getOwnPropertyNames(thisObject->target(), exec, propertyNames, mode);
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSProxy.h b/Source/JavaScriptCore/runtime/JSProxy.h
deleted file mode 100644
index 144085a79..000000000
--- a/Source/JavaScriptCore/runtime/JSProxy.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSProxy_h
-#define JSProxy_h
-
-#include "JSDestructibleObject.h"
-
-namespace JSC {
-
-class JSProxy : public JSDestructibleObject {
-public:
- typedef JSDestructibleObject Base;
-
- static JSProxy* create(JSGlobalData& globalData, Structure* structure, JSObject* target)
- {
- JSProxy* proxy = new (NotNull, allocateCell<JSProxy>(globalData.heap)) JSProxy(globalData, structure);
- proxy->finishCreation(globalData, target);
- return proxy;
- }
-
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ProxyType, StructureFlags), &s_info);
- }
-
- static JS_EXPORTDATA const ClassInfo s_info;
-
- JSObject* target() const { return m_target.get(); }
-
-protected:
- JSProxy(JSGlobalData& globalData, Structure* structure)
- : JSDestructibleObject(globalData, structure)
- {
- }
-
- void finishCreation(JSGlobalData& globalData)
- {
- Base::finishCreation(globalData);
- }
-
- void finishCreation(JSGlobalData& globalData, JSObject* target)
- {
- Base::finishCreation(globalData);
- m_target.set(globalData, this, target);
- }
-
- static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
-
- JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
-
- JS_EXPORT_PRIVATE void setTarget(JSGlobalData&, JSGlobalObject*);
-
- JS_EXPORT_PRIVATE static String className(const JSObject*);
- JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned, PropertySlot&);
- JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
- JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
- JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow);
- JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
- JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
- JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
- JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
-
-private:
- WriteBarrier<JSObject> m_target;
-};
-
-} // namespace JSC
-
-#endif // JSProxy_h
diff --git a/Source/JavaScriptCore/runtime/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp
index 8fd49b861..b22211970 100644
--- a/Source/JavaScriptCore/runtime/JSScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSScope.cpp
@@ -33,7 +33,7 @@
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSScope);
+ASSERT_CLASS_FITS_IN_CELL(JSScope);
void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 245c48a51..1500636f2 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -71,8 +71,6 @@ namespace JSC {
typedef JSCell Base;
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
private:
diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
index 7dcde4700..765e1d3d4 100644
--- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
@@ -61,8 +61,8 @@ void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecStat
JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(object);
SymbolTable::const_iterator end = thisObject->symbolTable()->end();
for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) {
- if (!(it->value.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
- propertyNames.add(Identifier(exec, it->key.get()));
+ if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
+ propertyNames.add(Identifier(exec, it->first.get()));
}
JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
index 913679f80..b4d313c19 100644
--- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
+++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
@@ -76,7 +76,7 @@ inline bool symbolTableGet(
SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
if (iter == symbolTable.end())
return false;
- SymbolTableEntry::Fast entry = iter->value;
+ SymbolTableEntry::Fast entry = iter->second;
ASSERT(!entry.isNull());
slot.setValue(object->registerAt(entry.getIndex()).get());
return true;
@@ -90,7 +90,7 @@ inline bool symbolTableGet(
SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
if (iter == symbolTable.end())
return false;
- SymbolTableEntry::Fast entry = iter->value;
+ SymbolTableEntry::Fast entry = iter->second;
ASSERT(!entry.isNull());
descriptor.setDescriptor(
object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
@@ -106,7 +106,7 @@ inline bool symbolTableGet(
SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
if (iter == symbolTable.end())
return false;
- SymbolTableEntry::Fast entry = iter->value;
+ SymbolTableEntry::Fast entry = iter->second;
ASSERT(!entry.isNull());
slot.setValue(object->registerAt(entry.getIndex()).get());
slotIsWriteable = !entry.isReadOnly();
@@ -126,7 +126,7 @@ inline bool symbolTablePut(
if (iter == symbolTable.end())
return false;
bool wasFat;
- SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat);
+ SymbolTableEntry::Fast fastEntry = iter->second.getFast(wasFat);
ASSERT(!fastEntry.isNull());
if (fastEntry.isReadOnly()) {
if (shouldThrow)
@@ -134,7 +134,7 @@ inline bool symbolTablePut(
return true;
}
if (UNLIKELY(wasFat))
- iter->value.notifyWrite();
+ iter->second.notifyWrite();
object->registerAt(fastEntry.getIndex()).set(globalData, object, value);
return true;
}
@@ -149,7 +149,7 @@ inline bool symbolTablePutWithAttributes(
SymbolTable::iterator iter = object->symbolTable()->find(propertyName.publicName());
if (iter == object->symbolTable()->end())
return false;
- SymbolTableEntry& entry = iter->value;
+ SymbolTableEntry& entry = iter->second;
ASSERT(!entry.isNull());
entry.notifyWrite();
entry.setAttributes(attributes);
diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h
index 03f4a7790..b8ab330f5 100644
--- a/Source/JavaScriptCore/runtime/JSType.h
+++ b/Source/JavaScriptCore/runtime/JSType.h
@@ -48,7 +48,7 @@ enum JSType {
NameInstanceType,
NumberObjectType,
ErrorInstanceType,
- ProxyType,
+ GlobalThisType,
WithScopeType,
NameScopeObjectType,
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index 651e50cec..ac00fad3d 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -195,7 +195,7 @@ void JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSVa
char* JSValue::description() const
{
- static const size_t size = 256;
+ static const size_t size = 128;
static char description[size];
if (!*this)
@@ -213,12 +213,9 @@ char* JSValue::description() const
u.asDouble = asDouble();
snprintf(description, size, "Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
#endif
- } else if (isCell()) {
- snprintf(
- description, size, "Cell: %p (%p: %s, %s)",
- asCell(), asCell()->structure(), asCell()->structure()->classInfo()->className,
- indexingTypeToString(asCell()->structure()->indexingTypeIncludingHistory()));
- } else if (isTrue())
+ } else if (isCell())
+ snprintf(description, size, "Cell: %p", asCell());
+ else if (isTrue())
snprintf(description, size, "True");
else if (isFalse())
snprintf(description, size, "False");
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 25961dc09..55952820e 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -68,7 +68,7 @@ namespace JSC {
{
}
- WriteBarrierBase<Unknown>* m_registers; // "r" in the stack.
+ WriteBarrierBase<Unknown>* m_registers; // "r" in the register file.
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSWithScope.cpp b/Source/JavaScriptCore/runtime/JSWithScope.cpp
index 7d74e63c3..0c4b6e2cc 100644
--- a/Source/JavaScriptCore/runtime/JSWithScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSWithScope.cpp
@@ -28,6 +28,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSWithScope);
+
const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWithScope) };
void JSWithScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
index ff80c1e20..4a46c2c69 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -24,6 +24,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSWrapperObject);
void JSWrapperObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index 72bc1874c..65b4bdb7f 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -22,15 +22,15 @@
#ifndef JSWrapperObject_h
#define JSWrapperObject_h
-#include "JSDestructibleObject.h"
+#include "JSObject.h"
namespace JSC {
// This class is used as a base for classes such as String,
// Number, Boolean and Date which are wrappers for primitive types.
- class JSWrapperObject : public JSDestructibleObject {
+ class JSWrapperObject : public JSNonFinalObject {
public:
- typedef JSDestructibleObject Base;
+ typedef JSNonFinalObject Base;
JSValue internalValue() const;
void setInternalValue(JSGlobalData&, JSValue);
@@ -42,7 +42,7 @@ namespace JSC {
protected:
explicit JSWrapperObject(JSGlobalData&, Structure*);
- static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+ static const unsigned StructureFlags = OverridesVisitChildren | JSNonFinalObject::StructureFlags;
static void visitChildren(JSCell*, SlotVisitor&);
@@ -51,7 +51,7 @@ namespace JSC {
};
inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure)
- : JSDestructibleObject(globalData, structure)
+ : JSNonFinalObject(globalData, structure)
{
}
diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp
index 2f4df375a..2a550a38b 100644
--- a/Source/JavaScriptCore/runtime/MathObject.cpp
+++ b/Source/JavaScriptCore/runtime/MathObject.cpp
@@ -32,7 +32,7 @@
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject);
+ASSERT_CLASS_FITS_IN_CELL(MathObject);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*);
@@ -59,7 +59,9 @@ static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
namespace JSC {
-const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) };
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject);
+
+const ClassInfo MathObject::s_info = { "Math", &JSNonFinalObject::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) };
/* Source for MathObject.lut.h
@begin mathTable
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
index 0f8efc604..b35e9fbda 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
@@ -28,7 +28,7 @@
#include "ExecutableAllocator.h"
#include "JSGlobalData.h"
-#include "JSStack.h"
+#include "RegisterFile.h"
namespace JSC {
@@ -36,7 +36,7 @@ GlobalMemoryStatistics globalMemoryStatistics()
{
GlobalMemoryStatistics stats;
- stats.stackBytes = JSStack::committedByteCount();
+ stats.stackBytes = RegisterFile::committedByteCount();
#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) || ((PLATFORM(BLACKBERRY) || PLATFORM(EFL)) && ENABLE(JIT))
stats.JITBytes = ExecutableAllocator::committedByteCount();
#else
diff --git a/Source/JavaScriptCore/runtime/NameConstructor.cpp b/Source/JavaScriptCore/runtime/NameConstructor.cpp
index b5facc7cf..63f1f647a 100644
--- a/Source/JavaScriptCore/runtime/NameConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NameConstructor.cpp
@@ -31,6 +31,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NameConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(NameConstructor);
const ClassInfo NameConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameConstructor) };
diff --git a/Source/JavaScriptCore/runtime/NameInstance.h b/Source/JavaScriptCore/runtime/NameInstance.h
index 129e7c407..c5931e8ef 100644
--- a/Source/JavaScriptCore/runtime/NameInstance.h
+++ b/Source/JavaScriptCore/runtime/NameInstance.h
@@ -26,14 +26,14 @@
#ifndef NameInstance_h
#define NameInstance_h
-#include "JSDestructibleObject.h"
+#include "JSObject.h"
#include "PrivateName.h"
namespace JSC {
-class NameInstance : public JSDestructibleObject {
+class NameInstance : public JSNonFinalObject {
public:
- typedef JSDestructibleObject Base;
+ typedef JSNonFinalObject Base;
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/NamePrototype.cpp b/Source/JavaScriptCore/runtime/NamePrototype.cpp
index f14e58522..3e52856b6 100644
--- a/Source/JavaScriptCore/runtime/NamePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NamePrototype.cpp
@@ -30,6 +30,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NamePrototype);
+
static EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState*);
}
@@ -46,6 +48,8 @@ const ClassInfo NamePrototype::s_info = { "Name", &Base::s_info, 0, ExecState::p
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(NamePrototype);
+
NamePrototype::NamePrototype(ExecState* exec, Structure* structure)
: Base(exec->globalData(), structure, jsEmptyString(exec))
{
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 1f1730805..a4ba240fd 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -28,6 +28,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(NativeErrorConstructor);
const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(NativeErrorConstructor) };
diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 296a86a22..7fee213fa 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -27,6 +27,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
+
NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, Structure* structure)
: ErrorPrototype(exec, structure)
{
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index daa643da7..03d616073 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -28,6 +28,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
+
static JSValue numberConstructorNaNValue(ExecState*, JSValue, PropertyName);
static JSValue numberConstructorNegInfinity(ExecState*, JSValue, PropertyName);
static JSValue numberConstructorPosInfinity(ExecState*, JSValue, PropertyName);
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index b87753d4d..1fea25464 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.cpp
+++ b/Source/JavaScriptCore/runtime/NumberObject.cpp
@@ -27,6 +27,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(NumberObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberObject);
const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(NumberObject) };
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index 23c9dbfdd..4a10efd6d 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -68,6 +68,7 @@ const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0,
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberPrototype);
NumberPrototype::NumberPrototype(ExecState* exec, Structure* structure)
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 7df047d28..8614b9c45 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -35,6 +35,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
+
static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
index e94edfadf..b1a5b9fb3 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -63,6 +63,8 @@ const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info,
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
+
ObjectPrototype::ObjectPrototype(ExecState* exec, Structure* stucture)
: JSNonFinalObject(exec->globalData(), stucture)
{
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 386eb4fcf..ed0720b54 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "Options.h"
-#include "HeapStatistics.h"
#include <algorithm>
#include <limits>
#include <stdio.h>
@@ -42,6 +41,10 @@
#include <sys/sysctl.h>
#endif
+// Set to 1 to control the heuristics using environment variables.
+#define ENABLE_RUN_TIME_HEURISTICS 0
+
+
namespace JSC {
static bool parse(const char* string, bool& value)
@@ -72,10 +75,10 @@ static bool parse(const char* string, double& value)
return sscanf(string, "%lf", &value) == 1;
}
+#if ENABLE(RUN_TIME_HEURISTICS)
template<typename T>
void overrideOptionWithHeuristic(T& variable, const char* name)
{
-#if !OS(WINCE)
const char* stringValue = getenv(name);
if (!stringValue)
return;
@@ -84,8 +87,9 @@ void overrideOptionWithHeuristic(T& variable, const char* name)
return;
fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
-#endif
}
+#endif
+
static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers)
{
@@ -126,19 +130,17 @@ void Options::initialize()
#if USE(CF) || OS(UNIX)
objectsAreImmortal() = !!getenv("JSImmortalZombieEnabled");
useZombieMode() = !!getenv("JSImmortalZombieEnabled") || !!getenv("JSZombieEnabled");
-
- gcMaxHeapSize() = getenv("GCMaxHeapSize") ? HeapStatistics::parseMemoryAmount(getenv("GCMaxHeapSize")) : 0;
- recordGCPauseTimes() = !!getenv("JSRecordGCPauseTimes");
- logHeapStatisticsAtExit() = gcMaxHeapSize() || recordGCPauseTimes();
#endif
// Allow environment vars to override options if applicable.
// The evn var should be the name of the option prefixed with
// "JSC_".
+#if ENABLE(RUN_TIME_HEURISTICS)
#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
overrideOptionWithHeuristic(name_(), "JSC_" #name_);
JSC_OPTIONS(FOR_EACH_OPTION)
#undef FOR_EACH_OPTION
+#endif // RUN_TIME_HEURISTICS
#if 0
; // Deconfuse editors that do auto indentation
@@ -151,7 +153,7 @@ void Options::initialize()
#if !ENABLE(YARR_JIT)
useRegExpJIT() = false;
#endif
-
+
// Do range checks where needed and make corrections to the options:
ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon());
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index d6d8c66c8..7571f9138 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -51,8 +51,9 @@ namespace JSC {
// purposes, you can do so in Options::initialize() after the default values
// are set.
//
-// Alternatively, you can override the default values by specifying
-// environment variables of the form: JSC_<name of JSC option>.
+// Alternatively, you can enable RUN_TIME_HEURISTICS which will allow you
+// to override the default values by specifying environment variables of the
+// form: JSC_<name of JSC option>.
//
// Note: Options::initialize() tries to ensure some sanity on the option values
// which are set by doing some range checks, and value corrections. These
@@ -115,19 +116,14 @@ namespace JSC {
v(unsigned, gcMarkStackSegmentSize, pageSize()) \
v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
v(unsigned, opaqueRootMergeThreshold, 1000) \
- v(double, minHeapUtilization, 0.8) \
- v(double, minCopiedBlockUtilization, 0.9) \
\
v(bool, forceWeakRandomSeed, false) \
v(unsigned, forcedWeakRandomSeed, 0) \
\
v(bool, useZombieMode, false) \
v(bool, objectsAreImmortal, false) \
- v(bool, showObjectStatistics, false) \
- \
- v(unsigned, gcMaxHeapSize, 0) \
- v(bool, recordGCPauseTimes, false) \
- v(bool, logHeapStatisticsAtExit, false)
+ v(bool, showHeapStatistics, false)
+
class Options {
public:
@@ -165,7 +161,7 @@ private:
boolType,
unsignedType,
doubleType,
- int32Type,
+ int32Type
};
// For storing for an option value:
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index 9c6ddb20f..2d0f27a3e 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -178,7 +178,7 @@ public:
PropertyOffset getDeletedOffset();
void addDeletedOffset(PropertyOffset);
- PropertyOffset nextOffset(PropertyOffset inlineCapacity);
+ PropertyOffset nextOffset(JSType);
// Copy this PropertyTable, ensuring the copy has at least the capacity provided.
PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
@@ -486,12 +486,15 @@ inline void PropertyTable::addDeletedOffset(PropertyOffset offset)
m_deletedOffsets->append(offset);
}
-inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity)
+inline PropertyOffset PropertyTable::nextOffset(JSType type)
{
if (hasDeletedOffset())
return getDeletedOffset();
-
- return propertyOffsetFor(size(), inlineCapacity);
+
+ if (type == FinalObjectType)
+ return size();
+
+ return size() + firstOutOfLineOffset;
}
inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
diff --git a/Source/JavaScriptCore/runtime/PropertyOffset.h b/Source/JavaScriptCore/runtime/PropertyOffset.h
index 1a2bba446..2aea2981e 100644
--- a/Source/JavaScriptCore/runtime/PropertyOffset.h
+++ b/Source/JavaScriptCore/runtime/PropertyOffset.h
@@ -26,6 +26,7 @@
#ifndef PropertyOffset_h
#define PropertyOffset_h
+#include "JSType.h"
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UnusedParam.h>
@@ -41,13 +42,14 @@ namespace JSC {
typedef int PropertyOffset;
static const PropertyOffset invalidOffset = -1;
-static const PropertyOffset firstOutOfLineOffset = 100;
+static const PropertyOffset inlineStorageCapacity = INLINE_STORAGE_CAPACITY;
+static const PropertyOffset firstOutOfLineOffset = inlineStorageCapacity;
// Declare all of the functions because they tend to do forward calls.
inline void checkOffset(PropertyOffset);
-inline void checkOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline void checkOffset(PropertyOffset, JSType);
inline void validateOffset(PropertyOffset);
-inline void validateOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline void validateOffset(PropertyOffset, JSType);
inline bool isValidOffset(PropertyOffset);
inline bool isInlineOffset(PropertyOffset);
inline bool isOutOfLineOffset(PropertyOffset);
@@ -55,7 +57,9 @@ inline size_t offsetInInlineStorage(PropertyOffset);
inline size_t offsetInOutOfLineStorage(PropertyOffset);
inline size_t offsetInRespectiveStorage(PropertyOffset);
inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset);
-inline size_t numberOfSlotsForLastOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline size_t numberOfSlotsForLastOffset(PropertyOffset, JSType);
+inline PropertyOffset nextPropertyOffsetFor(PropertyOffset, JSType);
+inline PropertyOffset firstPropertyOffsetFor(JSType);
inline void checkOffset(PropertyOffset offset)
{
@@ -63,14 +67,14 @@ inline void checkOffset(PropertyOffset offset)
ASSERT(offset >= invalidOffset);
}
-inline void checkOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline void checkOffset(PropertyOffset offset, JSType type)
{
UNUSED_PARAM(offset);
- UNUSED_PARAM(inlineCapacity);
+ UNUSED_PARAM(type);
ASSERT(offset >= invalidOffset);
ASSERT(offset == invalidOffset
- || offset < inlineCapacity
- || isOutOfLineOffset(offset));
+ || type == FinalObjectType
+ || isOutOfLineOffset(offset));
}
inline void validateOffset(PropertyOffset offset)
@@ -79,9 +83,9 @@ inline void validateOffset(PropertyOffset offset)
ASSERT(isValidOffset(offset));
}
-inline void validateOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline void validateOffset(PropertyOffset offset, JSType type)
{
- checkOffset(offset, inlineCapacity);
+ checkOffset(offset, type);
ASSERT(isValidOffset(offset));
}
@@ -94,7 +98,7 @@ inline bool isValidOffset(PropertyOffset offset)
inline bool isInlineOffset(PropertyOffset offset)
{
checkOffset(offset);
- return offset < firstOutOfLineOffset;
+ return offset < inlineStorageCapacity;
}
inline bool isOutOfLineOffset(PropertyOffset offset)
@@ -132,24 +136,28 @@ inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset offset)
return offset - firstOutOfLineOffset + 1;
}
-inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, JSType type)
{
- checkOffset(offset, inlineCapacity);
- if (offset < inlineCapacity)
+ checkOffset(offset, type);
+ if (type == FinalObjectType)
return offset + 1;
- return inlineCapacity + numberOfOutOfLineSlotsForLastOffset(offset);
+ return numberOfOutOfLineSlotsForLastOffset(offset);
}
-inline PropertyOffset propertyOffsetFor(PropertyOffset propertyNumber, PropertyOffset inlineCapacity)
+inline PropertyOffset nextPropertyOffsetFor(PropertyOffset offset, JSType type)
{
- PropertyOffset offset = propertyNumber;
- if (offset >= inlineCapacity) {
- offset += firstOutOfLineOffset;
- offset -= inlineCapacity;
- }
- return offset;
+ checkOffset(offset, type);
+ if (type != FinalObjectType && offset == invalidOffset)
+ return firstOutOfLineOffset;
+ return offset + 1;
+}
+
+inline PropertyOffset firstPropertyOffsetFor(JSType type)
+{
+ return nextPropertyOffsetFor(invalidOffset, type);
}
} // namespace JSC
#endif // PropertyOffset_h
+
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index b2b65d90c..287444b95 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -47,8 +47,6 @@ namespace JSC {
typedef JSCell Base;
JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags);
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
bool global() const { return m_flags & FlagGlobal; }
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp
index 8acafba23..c67dab8e6 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp
@@ -80,7 +80,7 @@ void RegExpCache::invalidateCode()
RegExpCacheMap::iterator end = m_weakCache.end();
for (RegExpCacheMap::iterator it = m_weakCache.begin(); it != end; ++it) {
- RegExp* regExp = it->value.get();
+ RegExp* regExp = it->second.get();
if (!regExp) // Skip zombies.
continue;
regExp->invalidateCode();
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index cc6ceb1d1..b8c4cd0b3 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -53,6 +53,8 @@ static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue);
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(RegExpConstructor);
+
const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::regExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) };
/* Source for RegExpConstructor.lut.h
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
index ce9c2d2db..04fea60e8 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
@@ -30,6 +30,8 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(RegExpMatchesArray);
+
const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RegExpMatchesArray)};
RegExpMatchesArray::RegExpMatchesArray(JSGlobalData& globalData, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result)
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index dfbf533f7..bed44f22c 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -49,9 +49,9 @@ static JSValue regExpObjectSource(ExecState*, JSValue, PropertyName);
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(RegExpObject);
+ASSERT_CLASS_FITS_IN_CELL(RegExpObject);
-const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) };
+const ClassInfo RegExpObject::s_info = { "RegExp", &JSNonFinalObject::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) };
/* Source for RegExpObject.lut.h
@begin regExpTable
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index e4bf2cf9a..3c742a0d3 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -59,6 +59,8 @@ const ClassInfo RegExpPrototype::s_info = { "RegExp", &RegExpObject::s_info, 0,
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
+
RegExpPrototype::RegExpPrototype(JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
: RegExpObject(globalObject, structure, regExp)
{
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
index 7f21e2c9f..b9ba25735 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
@@ -88,7 +88,7 @@ SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigne
void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, JSValue value, bool shouldThrow)
{
AddResult result = add(array, i);
- SparseArrayEntry& entry = result.iterator->value;
+ SparseArrayEntry& entry = result.iterator->second;
// To save a separate find & add, we first always add to the sparse map.
// In the uncommon case that this is a new property, and the array is not
@@ -106,7 +106,7 @@ void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i,
bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
{
AddResult result = add(array, i);
- SparseArrayEntry& entry = result.iterator->value;
+ SparseArrayEntry& entry = result.iterator->second;
// To save a separate find & add, we first always add to the sparse map.
// In the uncommon case that this is a new property, and the array is not
@@ -207,7 +207,7 @@ void SparseArrayValueMap::visitChildren(JSCell* thisObject, SlotVisitor& visitor
SparseArrayValueMap* thisMap = jsCast<SparseArrayValueMap*>(thisObject);
iterator end = thisMap->m_map.end();
for (iterator it = thisMap->m_map.begin(); it != end; ++it)
- visitor.append(&it->value);
+ visitor.append(&it->second);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
index 366a7b8ba..5d8d0577a 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
@@ -81,8 +81,6 @@ public:
static SparseArrayValueMap* create(JSGlobalData&);
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue prototype);
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index 7f36a84be..460343761 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -45,6 +45,7 @@ const ClassInfo StringConstructor::s_info = { "Function", &InternalFunction::s_i
@end
*/
+ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringConstructor);
StringConstructor::StringConstructor(JSGlobalObject* globalObject, Structure* structure)
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index ab7d6cb23..15900913d 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -27,6 +27,7 @@
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(StringObject);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 1540177be..8daa0f335 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -47,6 +47,7 @@ using namespace WTF;
namespace JSC {
+ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringPrototype);
static EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*);
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index a931def27..a59a0860d 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -149,7 +149,7 @@ void Structure::dumpStatistics()
#endif
}
-Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity)
+Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType)
: JSCell(globalData, globalData.structureStructure.get())
, m_typeInfo(typeInfo)
, m_indexingType(indexingType)
@@ -158,7 +158,6 @@ Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSV
, m_classInfo(classInfo)
, m_transitionWatchpointSet(InitializedWatching)
, m_outOfLineCapacity(0)
- , m_inlineCapacity(inlineCapacity)
, m_offset(invalidOffset)
, m_dictionaryKind(NoneDictionaryKind)
, m_isPinnedPropertyTable(false)
@@ -183,7 +182,6 @@ Structure::Structure(JSGlobalData& globalData)
, m_classInfo(&s_info)
, m_transitionWatchpointSet(InitializedWatching)
, m_outOfLineCapacity(0)
- , m_inlineCapacity(0)
, m_offset(invalidOffset)
, m_dictionaryKind(NoneDictionaryKind)
, m_isPinnedPropertyTable(false)
@@ -206,7 +204,6 @@ Structure::Structure(JSGlobalData& globalData, const Structure* previous)
, m_classInfo(previous->m_classInfo)
, m_transitionWatchpointSet(InitializedWatching)
, m_outOfLineCapacity(previous->m_outOfLineCapacity)
- , m_inlineCapacity(previous->m_inlineCapacity)
, m_offset(invalidOffset)
, m_dictionaryKind(previous->m_dictionaryKind)
, m_isPinnedPropertyTable(false)
@@ -326,15 +323,11 @@ bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const
}
}
-bool Structure::needsSlowPutIndexing() const
+NonPropertyTransition Structure::suggestedIndexingTransition() const
{
- return anyObjectInChainMayInterceptIndexedAccesses()
- || globalObject()->isHavingABadTime();
-}
-
-NonPropertyTransition Structure::suggestedArrayStorageTransition() const
-{
- if (needsSlowPutIndexing())
+ ASSERT(!hasIndexedProperties(indexingType()));
+
+ if (anyObjectInChainMayInterceptIndexedAccesses() || globalObject()->isHavingABadTime())
return AllocateSlowPutArrayStorage;
return AllocateArrayStorage;
@@ -553,7 +546,6 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure*
transition->m_previous.set(globalData, transition, structure);
transition->m_attributesInPrevious = attributes;
transition->m_indexingType = indexingType;
- transition->m_offset = structure->m_offset;
if (structure->m_propertyTable) {
if (structure->m_isPinnedPropertyTable)
@@ -616,21 +608,20 @@ Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObj
ASSERT(m_propertyTable);
size_t propertyCount = m_propertyTable->size();
-
- // Holds our values compacted by insertion order.
Vector<JSValue> values(propertyCount);
-
- // Copies out our values from their hashed locations, compacting property table offsets as we go.
+
unsigned i = 0;
+ PropertyOffset firstOffset = firstPropertyOffsetFor(m_typeInfo.type());
PropertyTable::iterator end = m_propertyTable->end();
for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter, ++i) {
values[i] = object->getDirectOffset(iter->offset);
- iter->offset = propertyOffsetFor(i, m_inlineCapacity);
+ // Update property table to have the new property offsets
+ iter->offset = i + firstOffset;
}
- // Copies in our values to their compacted locations.
+ // Copy the original property values into their final locations
for (unsigned i = 0; i < propertyCount; i++)
- object->putDirectOffset(globalData, propertyOffsetFor(i, m_inlineCapacity), values[i]);
+ object->putDirectOffset(globalData, firstOffset + i, values[i]);
m_propertyTable->clearDeletedOffsets();
}
@@ -768,7 +759,7 @@ PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyNam
if (!m_propertyTable)
createPropertyMap();
- PropertyOffset newOffset = m_propertyTable->nextOffset(m_inlineCapacity);
+ PropertyOffset newOffset = m_propertyTable->nextOffset(m_typeInfo.type());
m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue));
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index f45e9f1d9..e77287b20 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -69,7 +69,7 @@ namespace JSC {
typedef JSCell Base;
- static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, PropertyOffset inlineCapacity = 0);
+ static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = 0);
protected:
void finishCreation(JSGlobalData& globalData)
@@ -128,8 +128,6 @@ namespace JSC {
Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
// These should be used with caution.
@@ -154,8 +152,7 @@ namespace JSC {
bool anyObjectInChainMayInterceptIndexedAccesses() const;
- bool needsSlowPutIndexing() const;
- NonPropertyTransition suggestedArrayStorageTransition() const;
+ NonPropertyTransition suggestedIndexingTransition() const;
JSGlobalObject* globalObject() const { return m_globalObject.get(); }
void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); }
@@ -180,6 +177,24 @@ namespace JSC {
ASSERT(structure()->classInfo() == &s_info);
return m_outOfLineCapacity;
}
+ unsigned outOfLineSizeForKnownFinalObject() const
+ {
+ ASSERT(m_typeInfo.type() == FinalObjectType);
+ if (m_propertyTable) {
+ unsigned totalSize = m_propertyTable->propertyStorageSize();
+ if (totalSize < static_cast<unsigned>(inlineStorageCapacity))
+ return 0;
+ return totalSize - inlineStorageCapacity;
+ }
+ return numberOfOutOfLineSlotsForLastOffset(m_offset);
+ }
+ unsigned outOfLineSizeForKnownNonFinalObject() const
+ {
+ ASSERT(m_typeInfo.type() != FinalObjectType);
+ if (m_propertyTable)
+ return m_propertyTable->propertyStorageSize();
+ return numberOfOutOfLineSlotsForLastOffset(m_offset);
+ }
unsigned outOfLineSize() const
{
ASSERT(structure()->classInfo() == &s_info);
@@ -194,20 +209,31 @@ namespace JSC {
}
bool hasInlineStorage() const
{
- return !!m_inlineCapacity;
+ return m_typeInfo.type() == FinalObjectType;
}
unsigned inlineCapacity() const
{
- return m_inlineCapacity;
+ if (hasInlineStorage())
+ return inlineStorageCapacity;
+ return 0;
}
- unsigned inlineSize() const
+ unsigned inlineSizeForKnownFinalObject() const
{
+ ASSERT(m_typeInfo.type() == FinalObjectType);
unsigned result;
if (m_propertyTable)
result = m_propertyTable->propertyStorageSize();
else
result = m_offset + 1;
- return std::min<unsigned>(result, m_inlineCapacity);
+ if (result > static_cast<unsigned>(inlineStorageCapacity))
+ return inlineStorageCapacity;
+ return result;
+ }
+ unsigned inlineSize() const
+ {
+ if (!hasInlineStorage())
+ return 0;
+ return inlineSizeForKnownFinalObject();
}
unsigned totalStorageSize() const
{
@@ -225,12 +251,16 @@ namespace JSC {
{
if (hasInlineStorage())
return 0;
- return firstOutOfLineOffset;
+ return inlineStorageCapacity;
}
PropertyOffset lastValidOffset() const
{
- if (m_propertyTable)
- return propertyOffsetFor(m_propertyTable->propertyStorageSize() - 1, m_inlineCapacity);
+ if (m_propertyTable) {
+ PropertyOffset size = m_propertyTable->propertyStorageSize();
+ if (!hasInlineStorage())
+ size += inlineStorageCapacity;
+ return size - 1;
+ }
return m_offset;
}
bool isValidOffset(PropertyOffset offset) const
@@ -351,7 +381,7 @@ namespace JSC {
private:
friend class LLIntOffsetsExtractor;
- JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, PropertyOffset inlineCapacity);
+ JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = 0);
Structure(JSGlobalData&);
Structure(JSGlobalData&, const Structure*);
@@ -427,8 +457,6 @@ namespace JSC {
mutable InlineWatchpointSet m_transitionWatchpointSet;
uint32_t m_outOfLineCapacity;
- uint8_t m_inlineCapacity;
- COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
// m_offset does not account for anonymous slots
PropertyOffset m_offset;
@@ -445,11 +473,22 @@ namespace JSC {
unsigned m_staticFunctionReified;
};
- inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity)
+ template <> inline void* allocateCell<Structure>(Heap& heap)
+ {
+#if ENABLE(GC_VALIDATION)
+ ASSERT(!heap.globalData()->isInitializingObject());
+ heap.globalData()->setInitializingObjectClass(&Structure::s_info);
+#endif
+ JSCell* result = static_cast<JSCell*>(heap.allocateStructure(sizeof(Structure)));
+ result->clearStructure();
+ return result;
+ }
+
+ inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType)
{
ASSERT(globalData.structureStructure);
ASSERT(classInfo);
- Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
+ Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType);
structure->finishCreation(globalData);
return structure;
}
@@ -589,6 +628,15 @@ namespace JSC {
ASSERT(m_structure || !globalData.structureStructure);
}
+ inline const ClassInfo* JSCell::classInfo() const
+ {
+#if ENABLE(GC_VALIDATION)
+ return m_structure.unvalidatedGet()->classInfo();
+#else
+ return m_structure->classInfo();
+#endif
+ }
+
} // namespace JSC
#endif // Structure_h
diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h
index 878f606b4..3b19d4cf1 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.h
+++ b/Source/JavaScriptCore/runtime/StructureChain.h
@@ -59,10 +59,6 @@ namespace JSC {
static ClassInfo s_info;
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
- static void destroy(JSCell*);
-
protected:
void finishCreation(JSGlobalData& globalData, Structure* head)
{
@@ -82,6 +78,7 @@ namespace JSC {
friend class LLIntOffsetsExtractor;
StructureChain(JSGlobalData&, Structure*);
+ static void destroy(JSCell*);
OwnArrayPtr<WriteBarrier<Structure> > m_vector;
};
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index 3ab7b2014..90cb6a4db 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -43,7 +43,6 @@ static const unsigned FirstInternalAttribute = 1 << 6; // Use for transitions th
// Support for attributes used to indicate transitions not related to properties.
// If any of these are used, the string portion of the key should be 0.
enum NonPropertyTransition {
- AllocateContiguous,
AllocateArrayStorage,
AllocateSlowPutArrayStorage,
SwitchToSlowPutArrayStorage,
@@ -58,18 +57,13 @@ inline unsigned toAttributes(NonPropertyTransition transition)
inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition transition)
{
switch (transition) {
- case AllocateContiguous:
- ASSERT(!hasIndexedProperties(oldType));
- return oldType | ContiguousShape;
case AllocateArrayStorage:
- ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType));
- return (oldType & ~IndexingShapeMask) | ArrayStorageShape;
+ return oldType | HasArrayStorage;
case AllocateSlowPutArrayStorage:
- ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType));
- return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
+ return oldType | HasSlowPutArrayStorage;
case SwitchToSlowPutArrayStorage:
- ASSERT(hasFastArrayStorage(oldType));
- return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
+ ASSERT(oldType & HasArrayStorage);
+ return (oldType & ~HasArrayStorage) | HasSlowPutArrayStorage;
case AddIndexedAccessors:
return oldType | MayHaveIndexedAccessors;
default:
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index debb76499..6063dbab4 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -344,16 +344,12 @@ namespace JSC {
class SharedSymbolTable : public JSCell, public SymbolTable {
public:
- typedef JSCell Base;
-
static SharedSymbolTable* create(JSGlobalData& globalData)
{
SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(globalData.heap)) SharedSymbolTable(globalData);
sharedSymbolTable->finishCreation(globalData);
return sharedSymbolTable;
}
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
@@ -400,7 +396,6 @@ namespace JSC {
OwnArrayPtr<SlowArgument> m_slowArguments;
};
-
} // namespace JSC
#endif // SymbolTable_h
diff --git a/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h b/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h
deleted file mode 100644
index 1ae4818be..000000000
--- a/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TypedArrayDescriptor_h
-#define TypedArrayDescriptor_h
-
-namespace JSC {
-
-struct ClassInfo;
-
-enum TypedArrayType {
- TypedArrayNone,
- TypedArrayInt8,
- TypedArrayInt16,
- TypedArrayInt32,
- TypedArrayUint8,
- TypedArrayUint8Clamped,
- TypedArrayUint16,
- TypedArrayUint32,
- TypedArrayFloat32,
- TypedArrayFloat64
-};
-
-struct TypedArrayDescriptor {
- TypedArrayDescriptor()
- : m_classInfo(0)
- , m_storageOffset(0)
- , m_lengthOffset(0)
- {
- }
- TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset)
- : m_classInfo(classInfo)
- , m_storageOffset(storageOffset)
- , m_lengthOffset(lengthOffset)
- {
- }
- const ClassInfo* m_classInfo;
- size_t m_storageOffset;
- size_t m_lengthOffset;
-};
-
-enum TypedArraySignedness {
- SignedTypedArray,
- UnsignedTypedArray
-};
-enum TypedArrayRounding {
- TruncateRounding,
- ClampRounding
-};
-
-} // namespace JSC
-
-#endif // TypedArrayDescriptor_h
-
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index 52e5e2946..6926165a7 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -63,7 +63,7 @@ public:
{
typename MapType::iterator end = m_map.end();
for (typename MapType::iterator ptr = m_map.begin(); ptr != end; ++ptr)
- WeakSet::deallocate(ptr->value);
+ WeakSet::deallocate(ptr->second);
m_map.clear();
}
@@ -80,8 +80,8 @@ public:
ASSERT_UNUSED(globalData, globalData.apiLock().currentThreadIsHoldingLock());
typename MapType::AddResult result = m_map.add(key, 0);
if (!result.isNewEntry)
- WeakSet::deallocate(result.iterator->value);
- result.iterator->value = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key));
+ WeakSet::deallocate(result.iterator->second);
+ result.iterator->second = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key));
}
void remove(const KeyType& key)