[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75
aroben at apple.com
aroben at apple.com
Thu Oct 29 20:31:13 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 991d580bdfdc6528b710cea0855bb91d6fe6f384
Author: aroben at apple.com <aroben at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Sep 21 14:45:23 2009 +0000
Revert r48573, as it caused many assertion failures
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index c70a5cb..9fab7b8 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -18,64 +18,6 @@
(JSC::JITThunks::JITThunks):
* jit/JITStubs.h:
-2009-09-20 Oliver Hunt <oliver at apple.com>
-
- Reviewed by Maciej Stachowiak.
-
- SNES is too slow
- https://bugs.webkit.org/show_bug.cgi?id=29534
-
- The problem was that the emulator used multiple classes with
- more properties than our dictionary cutoff allowed, this resulted
- in more or less all critical logic inside the emulator requiring
- uncached property access.
-
- Rather than simply bumping the dictionary cutoff, this patch
- recognises that there are two ways to create a "dictionary"
- structure. Either by adding a large number of properties, or
- by removing a property. In the case of adding properties we
- know all the existing properties will maintain their existing
- offsets, so we could cache access to those properties, if we
- know they won't be removed.
-
- To make this possible, this patch adds the logic required to
- distinguish a dictionary created by addition from one created
- by removal. With this logic in place we can now cache access
- to objects with large numbers of properties.
-
- SNES performance improved by more than 6x.
-
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::resolveGlobal):
- (JSC::Interpreter::tryCachePutByID):
- (JSC::Interpreter::tryCacheGetByID):
- * jit/JITStubs.cpp:
- (JSC::JITThunks::tryCachePutByID):
- (JSC::JITThunks::tryCacheGetByID):
- (JSC::DEFINE_STUB_FUNCTION):
- * runtime/BatchedTransitionOptimizer.h:
- (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
- * runtime/JSObject.cpp:
- (JSC::JSObject::removeDirect):
- * runtime/Structure.cpp:
- (JSC::Structure::Structure):
- (JSC::Structure::getEnumerablePropertyNames):
- (JSC::Structure::despecifyDictionaryFunction):
- (JSC::Structure::addPropertyTransitionToExistingStructure):
- (JSC::Structure::addPropertyTransition):
- (JSC::Structure::removePropertyTransition):
- (JSC::Structure::toDictionaryTransition):
- (JSC::Structure::toCacheableDictionaryTransition):
- (JSC::Structure::toUncacheableDictionaryTransition):
- (JSC::Structure::fromDictionaryTransition):
- (JSC::Structure::removePropertyWithoutTransition):
- * runtime/Structure.h:
- (JSC::Structure::isDictionary):
- (JSC::Structure::isUncacheableDictionary):
- (JSC::Structure::):
- * runtime/StructureChain.cpp:
- (JSC::StructureChain::isCacheable):
-
2009-09-19 Oliver Hunt <oliver at apple.com>
Reviewed by Maciej Stachowiak.
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 624832c..dda667e 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -169,7 +169,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
+ if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
if (vPC[4].u.structure)
vPC[4].u.structure->deref();
globalObject->structure()->ref();
@@ -953,7 +953,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
JSCell* baseCell = asCell(baseValue);
Structure* structure = baseCell->structure();
- if (structure->isUncacheableDictionary()) {
+ if (structure->isDictionary()) {
vPC[0] = getOpcode(op_put_by_id_generic);
return;
}
@@ -1040,7 +1040,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
Structure* structure = asCell(baseValue)->structure();
- if (structure->isUncacheableDictionary()) {
+ if (structure->isDictionary()) {
vPC[0] = getOpcode(op_get_by_id_generic);
return;
}
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index f197526..1e960d5 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -679,7 +679,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
JSCell* baseCell = asCell(baseValue);
Structure* structure = baseCell->structure();
- if (structure->isUncacheableDictionary()) {
+ if (structure->isDictionary()) {
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
return;
}
@@ -743,7 +743,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
JSCell* baseCell = asCell(baseValue);
Structure* structure = baseCell->structure();
- if (structure->isUncacheableDictionary()) {
+ if (structure->isDictionary()) {
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
@@ -1154,7 +1154,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
JSObject* slotBaseObject;
if (baseValue.isCell()
&& slot.isCacheable()
- && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary()
+ && !(structure = asCell(baseValue)->structure())->isDictionary()
&& (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
&& specific
) {
@@ -1228,7 +1228,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
if (baseValue.isCell()
&& slot.isCacheable()
- && !asCell(baseValue)->structure()->isUncacheableDictionary()
+ && !asCell(baseValue)->structure()->isDictionary()
&& slot.slotBase() == baseValue) {
CodeBlock* codeBlock = callFrame->codeBlock();
@@ -1299,7 +1299,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
CHECK_FOR_EXCEPTION();
- if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) {
+ if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
return JSValue::encode(result);
}
@@ -2188,7 +2188,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
- if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
+ if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
if (globalResolveInfo.structure)
globalResolveInfo.structure->deref();
diff --git a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index 929a5e7..b9f738f 100644
--- a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -38,7 +38,7 @@ namespace JSC {
: m_object(object)
{
if (!m_object->structure()->isDictionary())
- m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure()));
+ m_object->setStructure(Structure::toDictionaryTransition(m_object->structure()));
}
~BatchedTransitionOptimizer()
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
index 74af4b1..8c14fdd 100644
--- a/JavaScriptCore/runtime/JSObject.cpp
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -471,7 +471,7 @@ JSObject* JSObject::unwrappedObject()
void JSObject::removeDirect(const Identifier& propertyName)
{
size_t offset;
- if (m_structure->isUncacheableDictionary()) {
+ if (m_structure->isDictionary()) {
offset = m_structure->removePropertyWithoutTransition(propertyName);
if (offset != WTF::notFound)
putDirectOffset(offset, jsUndefined());
diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp
index 05e539f..34c27b7 100644
--- a/JavaScriptCore/runtime/Structure.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -127,7 +127,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
, m_propertyTable(0)
, m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
, m_offset(noOffset)
- , m_dictionaryKind(NoneDictionaryKind)
+ , m_isDictionary(false)
, m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(false)
, m_attributesInPrevious(0)
@@ -290,7 +290,7 @@ void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray
void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
{
- bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary());
+ bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary);
if (shouldCache && m_cachedPropertyNameArrayData) {
if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
@@ -349,7 +349,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
materializePropertyMapIfNecessary();
- ASSERT(isDictionary());
+ ASSERT(m_isDictionary);
ASSERT(m_propertyTable);
unsigned i = rep->computedHash();
@@ -391,7 +391,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
{
- ASSERT(!structure->isDictionary());
+ ASSERT(!structure->m_isDictionary);
ASSERT(structure->typeInfo().type() == ObjectType);
if (Structure* existingTransition = structure->table.get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) {
@@ -405,12 +405,12 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
{
- ASSERT(!structure->isDictionary());
+ ASSERT(!structure->m_isDictionary);
ASSERT(structure->typeInfo().type() == ObjectType);
ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
if (structure->transitionCount() > s_maxTransitionLength) {
- RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
ASSERT(structure != transition);
offset = transition->put(propertyName, attributes, specificValue);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
@@ -454,9 +454,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
{
- ASSERT(!structure->isUncacheableDictionary());
+ ASSERT(!structure->m_isDictionary);
- RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure);
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
offset = transition->remove(propertyName);
@@ -554,35 +554,25 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
return transition.release();
}
-PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind)
+PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
{
- ASSERT(!structure->isDictionary());
-
+ ASSERT(!structure->m_isDictionary);
+
RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
- transition->m_dictionaryKind = kind;
+ transition->m_isDictionary = true;
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
-
+
structure->materializePropertyMapIfNecessary();
transition->m_propertyTable = structure->copyPropertyTable();
transition->m_isPinnedPropertyTable = true;
-
- return transition.release();
-}
-
-PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure)
-{
- return toDictionaryTransition(structure, CachedDictionaryKind);
-}
-PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure)
-{
- return toDictionaryTransition(structure, UncachedDictionaryKind);
+ return transition.release();
}
PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
{
- ASSERT(structure->isDictionary());
+ ASSERT(structure->m_isDictionary);
// Since dictionary Structures are not shared, and no opcodes specialize
// for them, we don't need to allocate a new Structure when transitioning
@@ -591,7 +581,7 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
// FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
// deleted offsets vector) before transitioning from dictionary.
if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
- structure->m_dictionaryKind = NoneDictionaryKind;
+ structure->m_isDictionary = false;
return structure;
}
@@ -610,7 +600,7 @@ size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, u
size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
{
- ASSERT(isUncacheableDictionary());
+ ASSERT(m_isDictionary);
materializePropertyMapIfNecessary();
diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h
index ed9f6e5..f7cb04b 100644
--- a/JavaScriptCore/runtime/Structure.h
+++ b/JavaScriptCore/runtime/Structure.h
@@ -70,8 +70,7 @@ namespace JSC {
static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&);
static PassRefPtr<Structure> addAnonymousSlotsTransition(Structure*, unsigned count);
static PassRefPtr<Structure> getterSetterTransition(Structure*);
- static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*);
- static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*);
+ static PassRefPtr<Structure> toDictionaryTransition(Structure*);
static PassRefPtr<Structure> fromDictionaryTransition(Structure*);
~Structure();
@@ -82,9 +81,8 @@ namespace JSC {
size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t removePropertyWithoutTransition(const Identifier& propertyName);
void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; }
-
- bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
- bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
+
+ bool isDictionary() const { return m_isDictionary; }
const TypeInfo& typeInfo() const { return m_typeInfo; }
@@ -129,13 +127,6 @@ namespace JSC {
private:
Structure(JSValue prototype, const TypeInfo&);
-
- typedef enum {
- NoneDictionaryKind = 0,
- CachedDictionaryKind = 1,
- UncachedDictionaryKind = 2
- } DictionaryKind;
- static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind);
size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t remove(const Identifier& propertyName);
@@ -196,7 +187,7 @@ namespace JSC {
size_t m_propertyStorageCapacity;
signed char m_offset;
- unsigned m_dictionaryKind : 2;
+ bool m_isDictionary : 1;
bool m_isPinnedPropertyTable : 1;
bool m_hasGetterSetterProperties : 1;
#if COMPILER(WINSCW)
diff --git a/JavaScriptCore/runtime/StructureChain.cpp b/JavaScriptCore/runtime/StructureChain.cpp
index 6e8a0ee..eb57a5a 100644
--- a/JavaScriptCore/runtime/StructureChain.cpp
+++ b/JavaScriptCore/runtime/StructureChain.cpp
@@ -51,7 +51,6 @@ 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())
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list