diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime')
61 files changed, 569 insertions, 527 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h index 5be84a2..9b674a2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h @@ -85,9 +85,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + private: void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp index 0237fd4..fb44494 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -50,7 +50,7 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, NonNullPassRefPtr<Structure> putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum); } -static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) +static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) { // a single numeric argument denotes the array size (!) if (args.size() == 1 && args.at(0).isNumber()) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp index 86e3f1b..7a89447 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -149,10 +149,11 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - if (!thisValue.inherits(&JSArray::info)) + bool isRealArray = isJSArray(&exec->globalData(), thisValue); + if (!isRealArray && !thisValue.inherits(&JSArray::info)) return throwError(exec, TypeError); - JSObject* thisObj = asArray(thisValue); - + JSArray* thisObj = asArray(thisValue); + HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) { if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth) @@ -163,34 +164,48 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue if (alreadyVisited) return jsEmptyString(exec); // return an empty string, avoiding infinite recursion. - Vector<UChar, 256> strBuffer; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); + unsigned totalSize = length ? length - 1 : 0; + Vector<RefPtr<UString::Rep>, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { - if (k >= 1) - strBuffer.append(','); - if (!strBuffer.data()) { - JSObject* error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - break; - } - - JSValue element = thisObj->get(exec, k); + JSValue element; + if (isRealArray && thisObj->canGetIndex(k)) + element = thisObj->getIndex(k); + else + element = thisObj->get(exec, k); + if (element.isUndefinedOrNull()) continue; - + UString str = element.toString(exec); - strBuffer.append(str.data(), str.size()); - + strBuffer[k] = str.rep(); + totalSize += str.size(); + if (!strBuffer.data()) { JSObject* error = Error::create(exec, GeneralError, "Out of memory"); exec->setException(error); } - + if (exec->hadException()) break; } arrayVisitedElements.remove(thisObj); - return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0)); + if (!totalSize) + return jsEmptyString(exec); + Vector<UChar> buffer; + buffer.reserveCapacity(totalSize); + if (!buffer.data()) + return throwError(exec, GeneralError, "Out of memory"); + + for (unsigned i = 0; i < length; i++) { + if (i) + buffer.append(','); + if (RefPtr<UString::Rep> rep = strBuffer[i]) + buffer.append(rep->data(), rep->size()); + } + ASSERT(buffer.size() == totalSize); + unsigned finalSize = buffer.size(); + return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false)); } JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h index 28f796a..69c2e51 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp index 01e36c4..a69115c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp @@ -1043,16 +1043,6 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack) #endif } -void Heap::setGCProtectNeedsLocking() -{ - // Most clients do not need to call this, with the notable exception of WebCore. - // Clients that use shared heap have JSLock protection, while others are supposed - // to do explicit locking. WebCore violates this contract in Database code, - // which calls gcUnprotect from a secondary thread. - if (!m_protectedValuesMutex) - m_protectedValuesMutex.set(new Mutex); -} - void Heap::protect(JSValue k) { ASSERT(k); @@ -1061,13 +1051,7 @@ void Heap::protect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.add(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::unprotect(JSValue k) @@ -1078,28 +1062,16 @@ void Heap::unprotect(JSValue k) if (!k.isCell()) return; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - m_protectedValues.remove(k.asCell()); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } void Heap::markProtectedObjects(MarkStack& markStack) { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) { markStack.append(it->first); markStack.drain(); } - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); } template <HeapType heapType> size_t Heap::sweep() @@ -1291,9 +1263,6 @@ size_t Heap::globalObjectCount() size_t Heap::protectedGlobalObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - size_t count = 0; if (JSGlobalObject* head = m_globalData->head) { JSGlobalObject* o = head; @@ -1304,23 +1273,12 @@ size_t Heap::protectedGlobalObjectCount() } while (o != head); } - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return count; } size_t Heap::protectedObjectCount() { - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - - size_t result = m_protectedValues.size(); - - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - - return result; + return m_protectedValues.size(); } static const char* typeName(JSCell* cell) @@ -1342,16 +1300,10 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts() { HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; - if (m_protectedValuesMutex) - m_protectedValuesMutex->lock(); - ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) counts->add(typeName(it->first)); - if (m_protectedValuesMutex) - m_protectedValuesMutex->unlock(); - return counts; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h index 0ecff19..9ca9d18 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h @@ -71,14 +71,6 @@ namespace JSC { void destroy(); -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - // We can inline these functions because everything is compiled as - // one file, so the heapAllocate template definitions are available. - // However, allocateNumber is used via jsNumberCell outside JavaScriptCore. - // Thus allocateNumber needs to provide a non-inline version too. - void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); } - void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); } -#endif void* allocateNumber(size_t); void* allocate(size_t); @@ -96,7 +88,6 @@ namespace JSC { }; Statistics statistics() const; - void setGCProtectNeedsLocking(); void protect(JSValue); void unprotect(JSValue); @@ -151,7 +142,6 @@ namespace JSC { CollectorHeap primaryHeap; CollectorHeap numberHeap; - OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking(). ProtectCountSet m_protectedValues; HashSet<MarkedArgumentBuffer*>* m_markListSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp index 6b479ae..4cd58f5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.cpp @@ -22,6 +22,8 @@ #include "config.h" #include "DateInstance.h" +#include "JSGlobalObject.h" + #include <math.h> #include <wtf/DateMath.h> #include <wtf/MathExtras.h> @@ -45,6 +47,13 @@ DateInstance::DateInstance(NonNullPassRefPtr<Structure> structure) { } +DateInstance::DateInstance(ExecState* exec, double time) + : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) + , m_cache(0) +{ + setInternalValue(jsNumber(exec, timeClip(time))); +} + DateInstance::~DateInstance() { delete m_cache; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h index c8edc2f..36d90b1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h @@ -31,6 +31,7 @@ namespace JSC { class DateInstance : public JSWrapperObject { public: + DateInstance(ExecState*, double); explicit DateInstance(NonNullPassRefPtr<Structure>); virtual ~DateInstance(); @@ -41,7 +42,7 @@ namespace JSC { bool getTime(double& milliseconds, int& offset) const; bool getUTCTime(double& milliseconds) const; - static const ClassInfo info; + static JS_EXPORTDATA const ClassInfo info; void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h index caed2d4..5fe4f47 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h @@ -39,8 +39,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | DateInstance::StructureFlags; + }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp index cc18b95..5bead90 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -66,6 +66,11 @@ JSValue createStackOverflowError(ExecState* exec) return createError(exec, RangeError, "Maximum call stack size exceeded."); } +JSValue createTypeError(ExecState* exec, const char* message) +{ + return createError(exec, TypeError, message); +} + JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h index 4c5bec1..e739d09 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h @@ -44,6 +44,7 @@ namespace JSC { JSValue createInterruptedExecutionException(JSGlobalData*); JSValue createStackOverflowError(ExecState*); + JSValue createTypeError(ExecState*, const char* message); JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*); JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull); JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h index 0e38549..d1d6a1d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h index 73dd854..68e9ea3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h @@ -50,7 +50,7 @@ namespace JSC { void setSetter(JSObject* setter) { m_setter = setter; } static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(GetterSetterType)); + return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren)); } private: virtual bool isGetterSetter() const; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h index b62ad3e..389b1c3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GlobalEvalFunction.h @@ -37,9 +37,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | PrototypeFunction::StructureFlags; + private: virtual void markChildren(MarkStack&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h index fdd5cc1..de9a1d6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h @@ -42,10 +42,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; + InternalFunction(NonNullPassRefPtr<Structure> structure) : JSObject(structure) { } InternalFunction(JSGlobalData*, NonNullPassRefPtr<Structure>, const Identifier&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h index 88a8493..aca550e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSAPIValueWrapper.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames)); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h index 583b988..ee98191 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h @@ -66,7 +66,10 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: struct JSActivationData : public JSVariableObjectData { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp index c471dac..fd9e7b2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -136,9 +136,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure) unsigned initialCapacity = 0; m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_vectorLength = initialCapacity; - - m_fastAccessCutoff = 0; + m_vectorLength = initialCapacity; checkConsistency(); } @@ -150,7 +148,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialLength; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = 0; m_storage->m_sparseValueMap = 0; m_storage->lazyCreationData = 0; @@ -159,8 +157,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) for (size_t i = 0; i < initialCapacity; ++i) vector[i] = JSValue(); - m_fastAccessCutoff = 0; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue)); @@ -173,7 +169,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); m_storage->m_length = initialCapacity; - m_storage->m_vectorLength = initialCapacity; + m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = initialCapacity; m_storage->m_sparseValueMap = 0; @@ -182,8 +178,6 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) m_storage->m_vector[i] = *it; - m_fastAccessCutoff = initialCapacity; - checkConsistency(); Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); @@ -207,7 +201,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot return false; } - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (valueSlot) { slot.setValueSlot(&valueSlot); @@ -253,8 +247,8 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper if (isArrayIndex) { if (i >= m_storage->m_length) return false; - if (i < m_storage->m_vectorLength) { - JSValue value = m_storage->m_vector[i]; + if (i < m_vectorLength) { + JSValue& value = m_storage->m_vector[i]; if (value) { descriptor.setDescriptor(value, 0); return true; @@ -305,7 +299,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) m_storage->m_length = length; } - if (i < m_storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[i]; if (valueSlot) { valueSlot = value; @@ -313,8 +307,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value) return; } valueSlot = value; - if (++m_storage->m_numValuesInVector == m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; checkConsistency(); return; } @@ -352,8 +345,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu if (increaseVectorLength(i + 1)) { storage = m_storage; storage->m_vector[i] = value; - if (++storage->m_numValuesInVector == storage->m_length) - m_fastAccessCutoff = storage->m_length; + ++storage->m_numValuesInVector; checkConsistency(); } else throwOutOfMemoryError(exec); @@ -363,7 +355,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu // Decide how many values it would be best to move from the map. unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; unsigned newVectorLength = increasedVectorLength(i + 1); - for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) + for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) newNumValuesInVector += map->contains(j); if (i >= MIN_SPARSE_ARRAY_INDEX) newNumValuesInVector -= map->contains(i); @@ -386,7 +378,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu return; } - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); @@ -404,7 +396,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu storage->m_vector[i] = value; - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; storage->m_numValuesInVector = newNumValuesInVector; m_storage = storage; @@ -431,7 +423,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) ArrayStorage* storage = m_storage; - if (i < storage->m_vectorLength) { + if (i < m_vectorLength) { JSValue& valueSlot = storage->m_vector[i]; if (!valueSlot) { checkConsistency(); @@ -439,8 +431,6 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) } valueSlot = JSValue(); --storage->m_numValuesInVector; - if (m_fastAccessCutoff > i) - m_fastAccessCutoff = i; checkConsistency(); return true; } @@ -472,7 +462,7 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(storage->m_length, m_vectorLength); for (unsigned i = 0; i < usedVectorLength; ++i) { if (storage->m_vector[i]) propertyNames.add(Identifier::from(exec, i)); @@ -494,7 +484,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) ArrayStorage* storage = m_storage; - unsigned vectorLength = storage->m_vectorLength; + unsigned vectorLength = m_vectorLength; ASSERT(newLength > vectorLength); ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); unsigned newVectorLength = increasedVectorLength(newLength); @@ -503,7 +493,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) return false; Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - storage->m_vectorLength = newVectorLength; + m_vectorLength = newVectorLength; for (unsigned i = vectorLength; i < newVectorLength; ++i) storage->m_vector[i] = JSValue(); @@ -521,10 +511,7 @@ void JSArray::setLength(unsigned newLength) unsigned length = m_storage->m_length; if (newLength < length) { - if (m_fastAccessCutoff > newLength) - m_fastAccessCutoff = newLength; - - unsigned usedVectorLength = min(length, storage->m_vectorLength); + unsigned usedVectorLength = min(length, m_vectorLength); for (unsigned i = newLength; i < usedVectorLength; ++i) { JSValue& valueSlot = storage->m_vector[i]; bool hadValue = valueSlot; @@ -563,20 +550,13 @@ JSValue JSArray::pop() JSValue result; - if (m_fastAccessCutoff > length) { - JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - ASSERT(result); - valueSlot = JSValue(); - --m_storage->m_numValuesInVector; - m_fastAccessCutoff = length; - } else if (length < m_storage->m_vectorLength) { + if (length < m_vectorLength) { JSValue& valueSlot = m_storage->m_vector[length]; - result = valueSlot; - valueSlot = JSValue(); - if (result) + if (valueSlot) { --m_storage->m_numValuesInVector; - else + result = valueSlot; + valueSlot = JSValue(); + } else result = jsUndefined(); } else { result = jsUndefined(); @@ -604,11 +584,10 @@ void JSArray::push(ExecState* exec, JSValue value) { checkConsistency(); - if (m_storage->m_length < m_storage->m_vectorLength) { - ASSERT(!m_storage->m_vector[m_storage->m_length]); + if (m_storage->m_length < m_vectorLength) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -618,8 +597,8 @@ void JSArray::push(ExecState* exec, JSValue value) if (!map || map->isEmpty()) { if (increaseVectorLength(m_storage->m_length + 1)) { m_storage->m_vector[m_storage->m_length] = value; - if (++m_storage->m_numValuesInVector == ++m_storage->m_length) - m_fastAccessCutoff = m_storage->m_length; + ++m_storage->m_numValuesInVector; + ++m_storage->m_length; checkConsistency(); return; } @@ -837,7 +816,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (!m_storage->m_length) return; - unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items tree.abstractor().m_exec = exec; @@ -886,7 +865,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_storage->m_vectorLength) { + if (newUsedVectorLength > m_vectorLength) { // Check that it is possible to allocate an array large enough to hold all the entries. if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) { throwOutOfMemoryError(exec); @@ -926,7 +905,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) m_storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; m_storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -934,10 +912,16 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - args.append(getIndex(i)); + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + args.append(v); + } + for (; i < m_storage->m_length; ++i) args.append(get(exec, i)); } @@ -946,12 +930,17 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz { ASSERT(m_storage->m_length == maxSize); UNUSED_PARAM(maxSize); - unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff); + JSValue* vector = m_storage->m_vector; + unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); unsigned i = 0; - for (; i < fastAccessLength; ++i) - buffer[i] = getIndex(i); - uint32_t size = m_storage->m_length; - for (; i < size; ++i) + for (; i < vectorEnd; ++i) { + JSValue& v = vector[i]; + if (!v) + break; + buffer[i] = v; + } + + for (; i < m_storage->m_length; ++i) buffer[i] = get(exec, i); } @@ -961,7 +950,7 @@ unsigned JSArray::compactForSorting() ArrayStorage* storage = m_storage; - unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength); unsigned numDefined = 0; unsigned numUndefined = 0; @@ -985,7 +974,7 @@ unsigned JSArray::compactForSorting() if (SparseArrayValueMap* map = storage->m_sparseValueMap) { newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->m_vectorLength) { + if (newUsedVectorLength > m_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(newUsedVectorLength)) @@ -1006,7 +995,6 @@ unsigned JSArray::compactForSorting() for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) storage->m_vector[i] = JSValue(); - m_fastAccessCutoff = newUsedVectorLength; storage->m_numValuesInVector = newUsedVectorLength; checkConsistency(SortConsistencyCheck); @@ -1032,30 +1020,27 @@ void JSArray::checkConsistency(ConsistencyCheckType type) if (type == SortConsistencyCheck) ASSERT(!m_storage->m_sparseValueMap); - ASSERT(m_fastAccessCutoff <= m_storage->m_length); - ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector); - unsigned numValuesInVector = 0; - for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) { + for (unsigned i = 0; i < m_vectorLength; ++i) { if (JSValue value = m_storage->m_vector[i]) { ASSERT(i < m_storage->m_length); if (type != DestructorConsistencyCheck) value->type(); // Likely to crash if the object was deallocated. ++numValuesInVector; } else { - ASSERT(i >= m_fastAccessCutoff); if (type == SortConsistencyCheck) ASSERT(i >= m_storage->m_numValuesInVector); } } ASSERT(numValuesInVector == m_storage->m_numValuesInVector); + ASSERT(numValuesInVector <= m_storage->m_length); if (m_storage->m_sparseValueMap) { SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end(); for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) { unsigned index = it->first; ASSERT(index < m_storage->m_length); - ASSERT(index >= m_storage->m_vectorLength); + ASSERT(index >= m_vectorLength); ASSERT(index <= MAX_ARRAY_INDEX); ASSERT(it->second); if (type != DestructorConsistencyCheck) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h index 12768a4..8c22451 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h @@ -29,7 +29,6 @@ namespace JSC { struct ArrayStorage { unsigned m_length; - unsigned m_vectorLength; unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily. @@ -63,18 +62,24 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(); - bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; } + bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } JSValue getIndex(unsigned i) { ASSERT(canGetIndex(i)); return m_storage->m_vector[i]; } - bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; } - JSValue setIndex(unsigned i, JSValue v) + bool canSetIndex(unsigned i) { return i < m_vectorLength; } + void setIndex(unsigned i, JSValue v) { ASSERT(canSetIndex(i)); - return m_storage->m_vector[i] = v; + JSValue& x = m_storage->m_vector[i]; + if (!x) { + ++m_storage->m_numValuesInVector; + if (i >= m_storage->m_length) + m_storage->m_length = i + 1; + } + x = v; } void fillArgList(ExecState*, MarkedArgumentBuffer&); @@ -82,12 +87,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } inline void markChildrenDirect(MarkStack& markStack); protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); @@ -110,7 +116,7 @@ namespace JSC { enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - unsigned m_fastAccessCutoff; + unsigned m_vectorLength; ArrayStorage* m_storage; }; @@ -139,7 +145,7 @@ namespace JSC { ArrayStorage* storage = m_storage; - unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); + unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); if (SparseArrayValueMap* map = storage->m_sparseValueMap) { @@ -152,7 +158,7 @@ namespace JSC { inline void MarkStack::markChildren(JSCell* cell) { ASSERT(Heap::isCellMarked(cell)); - if (cell->structure()->typeInfo().hasDefaultMark()) { + if (!cell->structure()->typeInfo().overridesMarkChildren()) { #ifdef NDEBUG asObject(cell)->markChildrenDirect(*this); #else diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp index 90d39f0..5e5003b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp @@ -45,7 +45,7 @@ JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) { - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark)); + PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); return result; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h index 006f4a2..fe6e124 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h @@ -91,6 +91,9 @@ namespace JSC { WTF::ByteArray* storage() const { return m_storage.get(); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; + private: enum VPtrStealingHackType { VPtrStealingHack }; JSByteArray(VPtrStealingHackType) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp index aa93252..fae056e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp @@ -78,11 +78,7 @@ extern const double Inf = NaNInf.doubles.Inf_Double; void* JSCell::operator new(size_t size, ExecState* exec) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocate(size); -#else return exec->heap()->allocate(size); -#endif } bool JSCell::getUInt32(uint32_t&) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h index 503c6c4..16a5131 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h @@ -112,14 +112,6 @@ namespace JSC { Structure* m_structure; }; - // FIXME: We should deprecate this and just use JSValue::asCell() instead. - JSCell* asCell(JSValue); - - inline JSCell* asCell(JSValue value) - { - return value.asCell(); - } - inline JSCell::JSCell(Structure* structure) : m_structure(structure) { @@ -162,11 +154,7 @@ namespace JSC { inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } // --- JSValue inlines ---------------------------- @@ -342,11 +330,6 @@ namespace JSC { append(value.asCell()); } - inline void Structure::markAggregate(MarkStack& markStack) - { - markStack.append(m_prototype); - } - inline Heap* Heap::heap(JSValue v) { if (!v.isCell()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h index a9ac63e..b4356c4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h @@ -61,7 +61,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } NativeFunction nativeFunction() @@ -72,6 +72,9 @@ namespace JSC { virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); + protected: + const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags; + private: JSFunction(NonNullPassRefPtr<Structure>); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp index 3bb281e..cf3f1d1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -89,7 +89,7 @@ static inline void markIfNeeded(MarkStack& markStack, JSValue v) static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) { if (s) - s->markAggregate(markStack); + markIfNeeded(markStack, s->storedPrototype()); } JSGlobalObject::~JSGlobalObject() @@ -394,6 +394,21 @@ void JSGlobalObject::markChildren(MarkStack& markStack) markIfNeeded(markStack, d()->methodCallDummy); markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->argumentsStructure); + markIfNeeded(markStack, d()->arrayStructure); + markIfNeeded(markStack, d()->booleanObjectStructure); + markIfNeeded(markStack, d()->callbackConstructorStructure); + markIfNeeded(markStack, d()->callbackFunctionStructure); + markIfNeeded(markStack, d()->callbackObjectStructure); + markIfNeeded(markStack, d()->dateStructure); + markIfNeeded(markStack, d()->emptyObjectStructure); + markIfNeeded(markStack, d()->errorStructure); + markIfNeeded(markStack, d()->functionStructure); + markIfNeeded(markStack, d()->numberObjectStructure); + markIfNeeded(markStack, d()->prototypeFunctionStructure); + markIfNeeded(markStack, d()->regExpMatchesArrayStructure); + markIfNeeded(markStack, d()->regExpStructure); + markIfNeeded(markStack, d()->stringObjectStructure); // No need to mark the other structures, because their prototypes are all // guaranteed to be referenced elsewhere. @@ -448,11 +463,7 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) { -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocate(size); -#else return globalData->heap.allocate(size); -#endif } void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h index 2106783..720d3a5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h @@ -267,10 +267,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; + struct GlobalPropertyInfo { GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) : identifier(i) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h index 0d9aca6..a271c4e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h @@ -62,10 +62,13 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; + // JSValue methods virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h index 6a48081..309488f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h @@ -68,23 +68,15 @@ namespace JSC { void* operator new(size_t size, ExecState* exec) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocateNumber(size); - #else return exec->heap()->allocateNumber(size); - #endif } void* operator new(size_t size, JSGlobalData* globalData) { - #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return globalData->heap.inlineAllocateNumber(size); - #else return globalData->heap.allocateNumber(size); - #endif } - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: JSNumberCell(JSGlobalData* globalData, double value) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h index 65c9803..ec3fa40 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSONObject.h @@ -41,11 +41,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } static void markStringifiers(MarkStack&, Stringifier*); + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp index db2a9b2..6932ded 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp @@ -42,6 +42,25 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSObject); +static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) +{ + // Add properties from the static hashtables of properties + for (; classInfo; classInfo = classInfo->parentClass) { + const HashTable* table = classInfo->propHashTable(exec); + if (!table) + continue; + table->initializeIfNeeded(exec); + ASSERT(table->table); + + int hashSizeMask = table->compactSize - 1; + const HashEntry* entry = table->table; + for (int i = 0; i <= hashSizeMask; ++i, ++entry) { + if (entry->key() && !(entry->attributes() & DontEnum)) + propertyNames.add(entry->key()); + } + } +} + void JSObject::markChildren(MarkStack& markStack) { #ifndef NDEBUG @@ -424,12 +443,29 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getEnumerablePropertyNames(exec, propertyNames, this); + getOwnPropertyNames(exec, propertyNames); + + if (prototype().isNull()) + return; + + JSObject* prototype = asObject(this->prototype()); + while(1) { + if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { + prototype->getPropertyNames(exec, propertyNames); + break; + } + prototype->getOwnPropertyNames(exec, propertyNames); + JSValue nextProto = prototype->prototype(); + if (nextProto.isNull()) + break; + prototype = asObject(nextProto); + } } void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) { - m_structure->getOwnEnumerablePropertyNames(exec, propertyNames, this); + m_structure->getEnumerablePropertyNames(propertyNames); + getEnumerablePropertyNames(exec, classInfo(), propertyNames); } bool JSObject::toBoolean(ExecState*) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h index 84b5f4b..1dbab94 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h @@ -207,10 +207,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = 0; + void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { @@ -368,7 +370,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - if (structure()->typeInfo().hasStandardGetOwnPropertySlot()) + if (!structure()->typeInfo().overridesGetOwnPropertySlot()) return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot); return getOwnPropertySlot(exec, propertyName, slot); } @@ -682,7 +684,7 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) { JSCell::markChildren(markStack); - m_structure->markAggregate(markStack); + markStack.append(prototype()); PropertyStorage storage = propertyStorage(); size_t storageSize = m_structure->propertyStorageSize(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index e08a3d9..2cd9f75 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -29,26 +29,56 @@ #include "config.h" #include "JSPropertyNameIterator.h" +#include "JSGlobalObject.h" + namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); -JSPropertyNameIterator::~JSPropertyNameIterator() +JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) { + ASSERT(!o->structure()->enumerationCache() || + o->structure()->enumerationCache()->cachedStructure() != o->structure() || + o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); + + PropertyNameArray propertyNames(exec); + o->getPropertyNames(exec, propertyNames); + JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data()); + + if (o->structure()->isDictionary()) + return jsPropertyNameIterator; + + if (o->structure()->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + + size_t count = normalizePrototypeChain(exec, o); + StructureChain* structureChain = o->structure()->prototypeChain(exec); + RefPtr<Structure>* structure = structureChain->head(); + for (size_t i = 0; i < count; ++i) { + if (structure[i]->typeInfo().overridesGetPropertyNames()) + return jsPropertyNameIterator; + } + + jsPropertyNameIterator->setCachedPrototypeChain(structureChain); + jsPropertyNameIterator->setCachedStructure(o->structure()); + o->structure()->setEnumerationCache(jsPropertyNameIterator); + return jsPropertyNameIterator; } -void JSPropertyNameIterator::markChildren(MarkStack& markStack) +JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i) { - JSCell::markChildren(markStack); - if (m_object) - markStack.append(m_object); + JSValue& identifier = m_jsStrings[i]; + if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec)) + return identifier; + + if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value()))) + return JSValue(); + return identifier; } -void JSPropertyNameIterator::invalidate() +void JSPropertyNameIterator::markChildren(MarkStack& markStack) { - ASSERT(m_position == m_end); - m_object = 0; - m_data.clear(); + markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h index d2849a8..0559e0b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -31,6 +31,7 @@ #include "JSObject.h" #include "JSString.h" +#include "Operations.h" #include "PropertyNameArray.h" namespace JSC { @@ -39,73 +40,51 @@ namespace JSC { class JSObject; class JSPropertyNameIterator : public JSCell { - public: - static JSPropertyNameIterator* create(ExecState*, JSValue); - - virtual ~JSPropertyNameIterator(); - - virtual void markChildren(MarkStack&); + friend class JIT; - JSValue next(ExecState*); - void invalidate(); + public: + static JSPropertyNameIterator* create(ExecState*, JSObject*); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren)); } + + virtual void markChildren(MarkStack&); + + JSValue get(ExecState*, JSObject*, size_t i); + size_t size() { return m_jsStringsSize; } + + void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } + Structure* cachedStructure() { return m_cachedStructure; } + + void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } + StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } + private: - JSPropertyNameIterator(ExecState*); - JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData); + JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData); - JSObject* m_object; - RefPtr<PropertyNameArrayData> m_data; - PropertyNameArrayData::const_iterator m_position; - PropertyNameArrayData::const_iterator m_end; + Structure* m_cachedStructure; + RefPtr<StructureChain> m_cachedPrototypeChain; + size_t m_jsStringsSize; + OwnArrayPtr<JSValue> m_jsStrings; }; -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec) +inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData) : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(0) - , m_position(0) - , m_end(0) + , m_cachedStructure(0) + , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) + , m_jsStrings(new JSValue[m_jsStringsSize]) { + PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); + for (size_t i = 0; i < m_jsStringsSize; ++i) + m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring()); } -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData) - : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_object(object) - , m_data(propertyNameArrayData) - , m_position(m_data->begin()) - , m_end(m_data->end()) -{ -} - -inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v) +inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache) { - if (v.isUndefinedOrNull()) - return new (exec) JSPropertyNameIterator(exec); - - JSObject* o = v.toObject(exec); - PropertyNameArray propertyNames(exec); - o->getPropertyNames(exec, propertyNames); - return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData()); -} - -inline JSValue JSPropertyNameIterator::next(ExecState* exec) -{ - if (m_position == m_end) - return JSValue(); - - if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec)) - return jsOwnedString(exec, (*m_position++).ustring()); - - do { - if (m_object->hasProperty(exec, *m_position)) - return jsOwnedString(exec, (*m_position++).ustring()); - m_position++; - } while (m_position != m_end); - - return JSValue(); + ASSERT(!isDictionary()); + m_enumerationCache = enumerationCache; } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h index 5eb0e4b..2542878 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -57,7 +57,10 @@ namespace JSC{ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; private: JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp index 91ddaeb..20ba868 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp @@ -139,45 +139,4 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); } -JSString* jsString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s); -} - -JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) -{ - ASSERT(offset <= static_cast<unsigned>(s.size())); - ASSERT(length <= static_cast<unsigned>(s.size())); - ASSERT(offset + length <= static_cast<unsigned>(s.size())); - if (!length) - return globalData->smallStrings.emptyString(globalData); - if (length == 1) { - UChar c = s.data()[offset]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); -} - -JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) -{ - int size = s.size(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.data()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h index 1e46551..39dfe75 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h @@ -92,7 +92,7 @@ namespace JSC { bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); } JSString* getIndex(JSGlobalData*, unsigned); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } private: enum VPtrStealingHackType { VPtrStealingHack }; @@ -169,6 +169,47 @@ namespace JSC { return jsSingleCharacterSubstring(globalData, m_value, i); } + inline JSString* jsString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s); + } + + inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) + { + ASSERT(offset <= static_cast<unsigned>(s.size())); + ASSERT(length <= static_cast<unsigned>(s.size())); + ASSERT(offset + length <= static_cast<unsigned>(s.size())); + if (!length) + return globalData->smallStrings.emptyString(globalData); + if (length == 1) { + UChar c = s.data()[offset]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length)); + } + + inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) + { + int size = s.size(); + if (!size) + return globalData->smallStrings.emptyString(globalData); + if (size == 1) { + UChar c = s.data()[0]; + if (c <= 0xFF) + return globalData->smallStrings.singleCharacterString(globalData, c); + } + return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); + } + inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h index 279510b..7c89600 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSTypeInfo.h @@ -40,9 +40,9 @@ namespace JSC { static const unsigned OverridesHasInstance = 1 << 2; static const unsigned ImplementsDefaultHasInstance = 1 << 3; static const unsigned NeedsThisConversion = 1 << 4; - static const unsigned HasStandardGetOwnPropertySlot = 1 << 5; - static const unsigned HasDefaultMark = 1 << 6; - static const unsigned HasDefaultGetPropertyNames = 1 << 7; + static const unsigned OverridesGetOwnPropertySlot = 1 << 5; + static const unsigned OverridesMarkChildren = 1 << 6; + static const unsigned OverridesGetPropertyNames = 1 << 7; class TypeInfo { friend class JIT; @@ -63,9 +63,9 @@ namespace JSC { bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; } bool overridesHasInstance() const { return m_flags & OverridesHasInstance; } bool needsThisConversion() const { return m_flags & NeedsThisConversion; } - bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; } - bool hasDefaultMark() const { return m_flags & HasDefaultMark; } - bool hasDefaultGetPropertyNames() const { return m_flags & HasDefaultGetPropertyNames; } + bool overridesGetOwnPropertySlot() const { return m_flags & OverridesGetOwnPropertySlot; } + bool overridesMarkChildren() const { return m_flags & OverridesMarkChildren; } + bool overridesGetPropertyNames() const { return m_flags & OverridesGetPropertyNames; } unsigned flags() const { return m_flags; } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 39a4093..699c1cd 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -110,7 +110,10 @@ char* JSValue::description() { static const size_t size = 32; static char description[size]; - if (isInt32()) + + if (!*this) + snprintf(description, size, "<JSValue()>"); + else if (isInt32()) snprintf(description, size, "Int32: %d", asInt32()); else if (isDouble()) snprintf(description, size, "Double: %lf", asDouble()); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h index 58e74b1..1063cdc 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h @@ -213,7 +213,8 @@ namespace JSC { enum { FalseTag = 0xfffffffc }; enum { NullTag = 0xfffffffb }; enum { UndefinedTag = 0xfffffffa }; - enum { DeletedValueTag = 0xfffffff9 }; + enum { EmptyValueTag = 0xfffffff9 }; + enum { DeletedValueTag = 0xfffffff8 }; enum { LowestTag = DeletedValueTag }; @@ -372,6 +373,14 @@ namespace JSC { return static_cast<uint32_t>(val); } + // FIXME: We should deprecate this and just use JSValue::asCell() instead. + JSCell* asCell(JSValue); + + inline JSCell* asCell(JSValue value) + { + return value.asCell(); + } + ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const { if (isInt32()) @@ -427,7 +436,7 @@ namespace JSC { inline JSValue::JSValue() { - u.asBits.tag = CellTag; + u.asBits.tag = EmptyValueTag; u.asBits.payload = 0; } @@ -463,19 +472,26 @@ namespace JSC { inline JSValue::JSValue(JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(ptr); } inline JSValue::JSValue(const JSCell* ptr) { - u.asBits.tag = CellTag; + if (ptr) + u.asBits.tag = CellTag; + else + u.asBits.tag = EmptyValueTag; u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr)); } inline JSValue::operator bool() const { - return u.asBits.payload || tag() != CellTag; + ASSERT(tag() != DeletedValueTag); + return tag() != EmptyValueTag; } inline bool JSValue::operator==(const JSValue& other) const diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h index 66e78c3..d8b1479 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h @@ -60,10 +60,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags; // Subclasses of JSVariableObject can subclass this struct to add data // without increasing their own size (since there's a hard limit on the // size of a JSCell). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h index 723b75d..191ff3b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h @@ -38,7 +38,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames | HasDefaultMark)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } private: diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h index ba00057e0..ea09f54 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h @@ -47,7 +47,7 @@ namespace JSC { } ALWAYS_INLINE void append(JSValue); - ALWAYS_INLINE void append(JSCell*); + void append(JSCell*); ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h index fee5ec5..7f474b8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h @@ -37,8 +37,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; }; } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h index 908c55f..cf19b6f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h @@ -39,11 +39,14 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h index ca3923d..8223a90 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h @@ -30,17 +30,19 @@ namespace JSC { explicit NumberObject(NonNullPassRefPtr<Structure>); static const ClassInfo info; -#if USE(JSVALUE32) + static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + + protected: +#if USE(JSVALUE32) + static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; #else - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames)); - } + static const unsigned StructureFlags = JSWrapperObject::StructureFlags; #endif + private: virtual const ClassInfo* classInfo() const { return &info; } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp index a456423..837d5a6 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -125,6 +125,7 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, return description; } +// FIXME: Use the enumeration cache. JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args) { if (!args.at(0).isObject()) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h index 5da9e38..1aa68b3 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h @@ -224,15 +224,15 @@ namespace JSC { return jsAddSlowCase(callFrame, v1, v2); } - inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot) + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase) { - JSCell* cell = asCell(baseValue); + JSCell* cell = asCell(base); size_t count = 0; - while (slot.slotBase() != cell) { + while (slotBase != cell) { JSValue v = cell->structure()->prototypeForLookup(callFrame); - // If we didn't find slotBase in baseValue's prototype chain, then baseValue + // If we didn't find slotBase in base's prototype chain, then base // must be a proxy for another object. if (v.isNull()) @@ -252,6 +252,25 @@ namespace JSC { return count; } + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base) + { + size_t count = 0; + while (1) { + JSValue v = base->structure()->prototypeForLookup(callFrame); + if (v.isNull()) + return count; + + base = asCell(v); + + // Since we're accessing a prototype in a loop, it's a good bet that it + // should not be treated as a dictionary. + if (base->structure()->isDictionary()) + asObject(base)->setStructure(Structure::fromDictionaryTransition(base->structure())); + + ++count; + } + } + ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain) { ScopeChainIterator iter = scopeChain->begin(); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp index 0878e73..c28b6a4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -21,6 +21,9 @@ #include "config.h" #include "PropertyNameArray.h" +#include "Structure.h" +#include "StructureChain.h" + namespace JSC { static const size_t setThreshold = 20; @@ -44,7 +47,7 @@ void PropertyNameArray::add(UString::Rep* identifier) return; } - m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); + addKnownUnique(identifier); } } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h index afcc83f..3dbcc9d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h @@ -23,45 +23,35 @@ #include "CallFrame.h" #include "Identifier.h" -#include "Structure.h" #include <wtf/HashSet.h> +#include <wtf/OwnArrayPtr.h> #include <wtf/Vector.h> namespace JSC { + + class Structure; + class StructureChain; + // FIXME: Rename to PropertyNameArray. class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> { public: typedef Vector<Identifier, 20> PropertyNameVector; - typedef PropertyNameVector::const_iterator const_iterator; static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); } - const_iterator begin() const { return m_propertyNameVector.begin(); } - const_iterator end() const { return m_propertyNameVector.end(); } - PropertyNameVector& propertyNameVector() { return m_propertyNameVector; } - void setCachedStructure(Structure* structure) { m_cachedStructure = structure; } - Structure* cachedStructure() const { return m_cachedStructure; } - - void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } - StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } - private: PropertyNameArrayData() - : m_cachedStructure(0) { } PropertyNameVector m_propertyNameVector; - Structure* m_cachedStructure; - RefPtr<StructureChain> m_cachedPrototypeChain; }; + // FIXME: Rename to PropertyNameArrayBuilder. class PropertyNameArray { public: - typedef PropertyNameArrayData::const_iterator const_iterator; - PropertyNameArray(JSGlobalData* globalData) : m_data(PropertyNameArrayData::create()) , m_globalData(globalData) @@ -82,21 +72,18 @@ namespace JSC { void add(UString::Rep*); void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } - size_t size() const { return m_data->propertyNameVector().size(); } - Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; } - const_iterator begin() const { return m_data->begin(); } - const_iterator end() const { return m_data->end(); } - void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; } PropertyNameArrayData* data() { return m_data.get(); } - PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } - void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; } - bool shouldCache() const { return m_shouldCache; } + // FIXME: Remove these functions. + typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator; + size_t size() const { return m_data->propertyNameVector().size(); } + const_iterator begin() const { return m_data->propertyNameVector().begin(); } + const_iterator end() const { return m_data->propertyNameVector().end(); } private: typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h index 224164d..a0d5443 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h @@ -22,8 +22,8 @@ #ifndef Protect_h #define Protect_h -#include "JSCell.h" #include "Collector.h" +#include "JSValue.h" namespace JSC { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp index dbf2d44..c609e08 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -90,28 +90,6 @@ const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, @end */ -struct RegExpConstructorPrivate : FastAllocBase { - // Global search cache / settings - RegExpConstructorPrivate() - : lastNumSubPatterns(0) - , multiline(false) - , lastOvectorIndex(0) - { - } - - const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } - Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } - Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } - void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } - - UString input; - UString lastInput; - Vector<int, 32> ovector[2]; - unsigned lastNumSubPatterns : 30; - bool multiline : 1; - unsigned lastOvectorIndex : 1; -}; - RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype) : InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp")) , d(new RegExpConstructorPrivate) @@ -123,30 +101,6 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structur putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum); } -/* - To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular - expression matching through the performMatch function. We use cached results to calculate, - e.g., RegExp.lastMatch and RegExp.leftParen. -*/ -void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) -{ - position = r->match(s, startOffset, &d->tempOvector()); - - if (ovector) - *ovector = d->tempOvector().data(); - - if (position != -1) { - ASSERT(!d->tempOvector().isEmpty()); - - length = d->tempOvector()[1] - d->tempOvector()[0]; - - d->input = s; - d->lastInput = s; - d->changeLastOvector(); - d->lastNumSubPatterns = r->numSubpatterns(); - } -} - RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data) : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h index f8bccf4..f9ca9cf 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h @@ -22,6 +22,7 @@ #define RegExpConstructor_h #include "InternalFunction.h" +#include "RegExp.h" #include <wtf/OwnPtr.h> namespace JSC { @@ -30,13 +31,35 @@ namespace JSC { class RegExpPrototype; struct RegExpConstructorPrivate; + struct RegExpConstructorPrivate : FastAllocBase { + // Global search cache / settings + RegExpConstructorPrivate() + : lastNumSubPatterns(0) + , multiline(false) + , lastOvectorIndex(0) + { + } + + const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } + Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } + Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } + void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } + + UString input; + UString lastInput; + Vector<int, 32> ovector[2]; + unsigned lastNumSubPatterns : 30; + bool multiline : 1; + unsigned lastOvectorIndex : 1; + }; + class RegExpConstructor : public InternalFunction { public: RegExpConstructor(ExecState*, NonNullPassRefPtr<Structure>, RegExpPrototype*); static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); @@ -59,6 +82,9 @@ namespace JSC { JSValue getLeftContext(ExecState*) const; JSValue getRightContext(ExecState*) const; + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; + private: virtual ConstructType getConstructData(ConstructData&); virtual CallType getCallData(CallData&); @@ -78,6 +104,30 @@ namespace JSC { return static_cast<RegExpConstructor*>(asObject(value)); } + /* + To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular + expression matching through the performMatch function. We use cached results to calculate, + e.g., RegExp.lastMatch and RegExp.leftParen. + */ + inline void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) + { + position = r->match(s, startOffset, &d->tempOvector()); + + if (ovector) + *ovector = d->tempOvector().data(); + + if (position != -1) { + ASSERT(!d->tempOvector().isEmpty()); + + length = d->tempOvector()[1] - d->tempOvector()[0]; + + d->input = s; + d->lastInput = s; + d->changeLastOvector(); + d->lastNumSubPatterns = r->numSubpatterns(); + } + } + } // namespace JSC #endif // RegExpConstructor_h diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp index 877d7b6..679d072 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp @@ -159,7 +159,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args) } int position; - int length; + int length = 0; regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); if (position < 0) { d->lastIndex = 0; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h index f5a9340..3117c86 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h @@ -49,9 +49,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; + private: bool match(ExecState*, const ArgList&); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h index 944f6ba..84e1ad2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h @@ -48,10 +48,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags; StringObject(NonNullPassRefPtr<Structure>, JSString*); }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index 0cba83d..69e1939 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h @@ -44,9 +44,11 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags; + virtual bool toBoolean(ExecState*) const { return false; } }; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp index b57732a..a0713b8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp @@ -25,6 +25,7 @@ #include "CachedCall.h" #include "Error.h" #include "Executable.h" +#include "JSGlobalObjectFunctions.h" #include "JSArray.h" #include "JSFunction.h" #include "ObjectPrototype.h" @@ -72,6 +73,10 @@ static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSVa static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*, JSObject*, JSValue, const ArgList&); + } #include "StringPrototype.lut.h" @@ -117,6 +122,9 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec fontsize stringProtoFuncFontsize DontEnum|Function 1 anchor stringProtoFuncAnchor DontEnum|Function 1 link stringProtoFuncLink DontEnum|Function 1 + trim stringProtoFuncTrim DontEnum|Function 0 + trimLeft stringProtoFuncTrimLeft DontEnum|Function 0 + trimRight stringProtoFuncTrimRight DontEnum|Function 0 @end */ @@ -249,7 +257,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue return jsNull(); while (true) { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -290,7 +298,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue } else { do { int matchIndex; - int matchLen; + int matchLen = 0; int* ovector; regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); if (matchIndex < 0) @@ -485,7 +493,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); if (!(reg->global())) { // case without 'g' flag is handled like RegExp.prototype.exec @@ -535,7 +543,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; - int matchLength; + int matchLength = 0; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); return jsNumber(exec, pos); } @@ -899,4 +907,51 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th return jsNontrivialString(exec, UString(buffer, bufferSize, false)); } +enum { + TrimLeft = 1, + TrimRight = 2 +}; + +static inline bool isTrimWhitespace(UChar c) +{ + return isStrWhiteSpace(c) || c == 0x200b; +} + +static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind) +{ + UString str = thisValue.toThisString(exec); + int left = 0; + if (trimKind & TrimLeft) { + while (left < str.size() && isTrimWhitespace(str[left])) + left++; + } + int right = str.size(); + if (trimKind & TrimRight) { + while (right > left && isTrimWhitespace(str[right - 1])) + right--; + } + + // Don't gc allocate a new string if we don't have to. + if (left == 0 && right == str.size() && thisValue.isString()) + return thisValue; + + return jsString(exec, str.substr(left, right - left)); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft | TrimRight); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimLeft); +} + +JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) +{ + return trimString(exec, thisValue, TrimRight); +} + + } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp index 7209b5f..a11050f 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp @@ -28,9 +28,10 @@ #include "Identifier.h" #include "JSObject.h" +#include "JSPropertyNameIterator.h" +#include "Lookup.h" #include "PropertyNameArray.h" #include "StructureChain.h" -#include "Lookup.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/RefPtr.h> @@ -159,9 +160,9 @@ Structure::~Structure() m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); } - - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); + + if (m_enumerationCache) + m_enumerationCache->setCachedStructure(0); if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; @@ -282,59 +283,6 @@ void Structure::materializePropertyMap() } } -void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - getEnumerableNamesFromPropertyTable(propertyNames); - getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); -} - -void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) -{ - bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary()); - - if (shouldCache && m_cachedPropertyNameArrayData) { - if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { - propertyNames.setData(m_cachedPropertyNameArrayData); - return; - } - clearEnumerationCache(); - } - - baseObject->getOwnPropertyNames(exec, propertyNames); - - if (m_prototype.isObject()) { - propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. - JSObject* prototype = asObject(m_prototype); - while(1) { - if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames); - break; - } - prototype->getOwnPropertyNames(exec, propertyNames); - JSValue nextProto = prototype->prototype(); - if (!nextProto.isObject()) - break; - prototype = asObject(nextProto); - } - } - - if (shouldCache) { - StructureChain* protoChain = prototypeChain(exec); - m_cachedPropertyNameArrayData = propertyNames.data(); - if (!protoChain->isCacheable()) - return; - m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain); - m_cachedPropertyNameArrayData->setCachedStructure(this); - } -} - -void Structure::clearEnumerationCache() -{ - if (m_cachedPropertyNameArrayData) - m_cachedPropertyNameArrayData->setCachedStructure(0); - m_cachedPropertyNameArrayData.clear(); -} - void Structure::growPropertyStorageCapacity() { if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) @@ -598,25 +546,25 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = put(propertyName, attributes, specificValue); if (propertyStorageSize() > propertyStorageCapacity()) growPropertyStorageCapacity(); - clearEnumerationCache(); return offset; } size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) { ASSERT(isUncacheableDictionary()); + ASSERT(!m_enumerationCache); materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; size_t offset = remove(propertyName); - clearEnumerationCache(); return offset; } @@ -1057,7 +1005,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b) return 0; } -void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames) +void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -1114,25 +1062,6 @@ void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyN } } -void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) -{ - // Add properties from the static hashtables of properties - for (; classInfo; classInfo = classInfo->parentClass) { - const HashTable* table = classInfo->propHashTable(exec); - if (!table) - continue; - table->initializeIfNeeded(exec); - ASSERT(table->table); - - int hashSizeMask = table->compactSize - 1; - const HashEntry* entry = table->table; - for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && !(entry->attributes() & DontEnum)) - propertyNames.add(entry->key()); - } - } -} - #if DO_PROPERTYMAP_CONSTENCY_CHECK void Structure::checkConsistency() diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index ed9f6e5..2496c1b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -30,6 +30,8 @@ #include "JSType.h" #include "JSValue.h" #include "PropertyMapHashTable.h" +#include "PropertyNameArray.h" +#include "Protect.h" #include "StructureChain.h" #include "StructureTransitionTable.h" #include "JSTypeInfo.h" @@ -76,8 +78,6 @@ namespace JSC { ~Structure(); - void markAggregate(MarkStack&); - // These should be used with caution. size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t removePropertyWithoutTransition(const Identifier& propertyName); @@ -116,9 +116,6 @@ namespace JSC { return hasTransition(propertyName._ustring.rep(), attributes); } - void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); - bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } @@ -127,6 +124,10 @@ namespace JSC { JSCell* specificValue() { return m_specificValueInPrevious; } void despecifyDictionaryFunction(const Identifier& propertyName); + void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. + JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); } + void getEnumerablePropertyNames(PropertyNameArray&); + private: Structure(JSValue prototype, const TypeInfo&); @@ -140,8 +141,6 @@ namespace JSC { size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); void addAnonymousSlots(unsigned slotCount); - void getEnumerableNamesFromPropertyTable(PropertyNameArray&); - void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&); void expandPropertyMapHashTable(); void rehashPropertyMapHashTable(); @@ -162,8 +161,6 @@ namespace JSC { materializePropertyMap(); } - void clearEnumerationCache(); - signed char transitionCount() const { // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both. @@ -189,7 +186,7 @@ namespace JSC { StructureTransitionTable table; - RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; + ProtectedPtr<JSPropertyNameIterator> m_enumerationCache; PropertyMapHashTable* m_propertyTable; diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp index 6e8a0ee..085876c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp @@ -46,18 +46,4 @@ StructureChain::StructureChain(Structure* head) m_vector[i] = 0; } -bool StructureChain::isCacheable() const -{ - uint32_t i = 0; - - while (m_vector[i]) { - // Both classes of dictionary structure may change arbitrarily so we can't cache them - if (m_vector[i]->isDictionary()) - return false; - if (!m_vector[i++]->typeInfo().hasDefaultGetPropertyNames()) - return false; - } - return true; -} - } // namespace JSC diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h index c48749d..816b66d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h @@ -36,10 +36,11 @@ namespace JSC { class Structure; class StructureChain : public RefCounted<StructureChain> { + friend class JIT; + public: static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); } RefPtr<Structure>* head() { return m_vector.get(); } - bool isCacheable() const; private: StructureChain(Structure* head); |