From 20d145e087df462c3020938ded724f99d9656639 Mon Sep 17 00:00:00 2001 From: mjs Date: Tue, 12 Apr 2005 22:18:35 +0000 Subject: [PATCH] Reviewed by John. Avoid using protect count hash table so much for 5.6% JS iBench speedup - Avoid using protected values hash for the two most common cases - Bump up ListImp high water mark, new testing shows 508 ListImps are created during JS iBench. Net result is a 5.6% speedup on JavaScript iBench * kjs/collector.cpp: (KJS::Collector::collect): mark protected lists as appropriate. * kjs/context.h: * kjs/list.cpp: (KJS::ListImp::markValues): Moved implementation from List::markValues (KJS::List::markProtectedLists): Implemented - scan pool and overflow list. (KJS::allocateListImp): link lists outside the pool into a separate doubly linked list to be able to mark protected lists (KJS::deallocateListImp): do the corresponding delinking (KJS::List::derefValues): do nothing in conservative GC mode (KJS::List::refValues): do nothing in conservative GC mode (KJS::List::markValues): call ListImp version (KJS::List::append): * kjs/list.h: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9003 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- JavaScriptCore/ChangeLog | 28 ++++++++ JavaScriptCore/kjs/collector.cpp | 9 +-- JavaScriptCore/kjs/context.h | 9 ++- JavaScriptCore/kjs/list.cpp | 120 +++++++++++++++++++------------ JavaScriptCore/kjs/list.h | 2 + 5 files changed, 112 insertions(+), 56 deletions(-) diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 0addb168d604..4bdb15ab3572 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,31 @@ +2005-04-11 Maciej Stachowiak + + Reviewed by John. + + Avoid using protect count hash table so much for 5.6% JS iBench speedup + + - Avoid using protected values hash for the two most common cases + - Bump up ListImp high water mark, new testing shows 508 ListImps are + created during JS iBench. + + Net result is a 5.6% speedup on JavaScript iBench + + * kjs/collector.cpp: + (KJS::Collector::collect): mark protected lists as appropriate. + * kjs/context.h: + * kjs/list.cpp: + (KJS::ListImp::markValues): Moved implementation from List::markValues + (KJS::List::markProtectedLists): Implemented - scan pool and overflow + list. + (KJS::allocateListImp): link lists outside the pool into a separate + doubly linked list to be able to mark protected lists + (KJS::deallocateListImp): do the corresponding delinking + (KJS::List::derefValues): do nothing in conservative GC mode + (KJS::List::refValues): do nothing in conservative GC mode + (KJS::List::markValues): call ListImp version + (KJS::List::append): + * kjs/list.h: + === Safari-412 === === Safari-411 === diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp index 2c7113ebe4c3..5b89fe052dac 100644 --- a/JavaScriptCore/kjs/collector.cpp +++ b/JavaScriptCore/kjs/collector.cpp @@ -23,17 +23,11 @@ #include "value.h" #include "internal.h" +#include "list.h" #if APPLE_CHANGES #include #include -#endif - -#include -#include -#include - -#if APPLE_CHANGES #include #include #include @@ -372,6 +366,7 @@ bool Collector::collect() markStackObjectsConservatively(); markProtectedObjects(); + List::markProtectedLists(); #endif #if TEST_CONSERVATIVE_GC diff --git a/JavaScriptCore/kjs/context.h b/JavaScriptCore/kjs/context.h index 5b29d2167952..3ad2a1064d92 100644 --- a/JavaScriptCore/kjs/context.h +++ b/JavaScriptCore/kjs/context.h @@ -59,11 +59,14 @@ namespace KJS { ContextImp *_callingContext; FunctionImp *_function; const List *_arguments; - ProtectedObject activation; + // because ContextImp is always allocated on the stack, + // there is no need to protect various pointers from conservative + // GC since they will be caught by the conservative sweep anyway! + Object activation; ScopeChain scope; - ProtectedObject variable; - ProtectedObject thisVal; + Object variable; + Object thisVal; LabelStack ls; CodeType codeType; diff --git a/JavaScriptCore/kjs/list.cpp b/JavaScriptCore/kjs/list.cpp index faa0bcefa04e..d77844328275 100644 --- a/JavaScriptCore/kjs/list.cpp +++ b/JavaScriptCore/kjs/list.cpp @@ -28,7 +28,7 @@ namespace KJS { // tunable parameters -const int poolSize = 384; +const int poolSize = 512; const int inlineValuesSize = 4; @@ -42,14 +42,19 @@ struct ListImp : ListImpBase ValueImp **overflow; ListImp *nextInFreeList; + ListImp *nextInOutsideList; + ListImp *prevInOutsideList; #if DUMP_STATISTICS int sizeHighWaterMark; #endif + + void markValues(); }; static ListImp pool[poolSize]; static ListImp *poolFreeList; +static ListImp *outsidePoolList; static int poolUsed; #if DUMP_STATISTICS @@ -86,6 +91,49 @@ ListStatisticsExitLogger::~ListStatisticsExitLogger() #endif + +inline void ListImp::markValues() +{ + int inlineSize = MIN(size, inlineValuesSize); + for (int i = 0; i != inlineSize; ++i) { + if (!values[i]->marked()) { + values[i]->mark(); + } + } + + int overflowSize = size - inlineSize; + for (int i = 0; i != overflowSize; ++i) { + if (!overflow[i]->marked()) { + overflow[i]->mark(); + } + } +} + +void List::markProtectedLists() +{ +#if TEST_CONSERVATIVE_GC || USE_CONSERVATIVE_GC + int seen = 0; + for (int i = 0; i < poolSize; i++) { + if (seen >= poolUsed) + break; + + if (pool[i].state == usedInPool) { + seen++; + if (pool[i].valueRefCount > 0) { + pool[i].markValues(); + } + } + } + + for (ListImp *l = outsidePoolList; l; l = l->nextInOutsideList) { + if (l->valueRefCount > 0) { + l->markValues(); + } + } +#endif +} + + static inline ListImp *allocateListImp() { // Find a free one in the pool. @@ -99,6 +147,14 @@ static inline ListImp *allocateListImp() ListImp *imp = new ListImp; imp->state = usedOnHeap; + // link into outside pool list + if (outsidePoolList) { + outsidePoolList->prevInOutsideList = imp; + } + imp->nextInOutsideList = outsidePoolList; + imp->prevInOutsideList = NULL; + outsidePoolList = imp; + return imp; } @@ -110,6 +166,19 @@ static inline void deallocateListImp(ListImp *imp) poolFreeList = imp; poolUsed--; } else { + // unlink from outside pool list + if (!imp->prevInOutsideList) { + outsidePoolList = imp->nextInOutsideList; + if (outsidePoolList) { + outsidePoolList->prevInOutsideList = NULL; + } + } else { + imp->prevInOutsideList->nextInOutsideList = imp->nextInOutsideList; + if (imp->nextInOutsideList) { + imp->nextInOutsideList->prevInOutsideList = imp->prevInOutsideList; + } + } + delete imp; } } @@ -153,82 +222,44 @@ List::List(bool needsMarking) : _impBase(allocateListImp()), _needsMarking(needs void List::derefValues() { +#if !USE_CONSERVATIVE_GC ListImp *imp = static_cast(_impBase); int size = imp->size; int inlineSize = MIN(size, inlineValuesSize); -#if !USE_CONSERVATIVE_GC for (int i = 0; i != inlineSize; ++i) imp->values[i]->deref(); -#endif -#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC - for (int i = 0; i != inlineSize; ++i) - gcUnprotect(imp->values[i]); -#endif - int overflowSize = size - inlineSize; ValueImp **overflow = imp->overflow; -#if !USE_CONSERVATIVE_GC - for (int i = 0; i != overflowSize; ++i) - overflow[i]->deref(); -#endif -#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC for (int i = 0; i != overflowSize; ++i) - gcUnprotect(overflow[i]); + overflow[i]->deref(); #endif } void List::refValues() { +#if !USE_CONSERVATIVE_GC ListImp *imp = static_cast(_impBase); int size = imp->size; int inlineSize = MIN(size, inlineValuesSize); -#if !USE_CONSERVATIVE_GC for (int i = 0; i != inlineSize; ++i) imp->values[i]->ref(); -#endif -#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC - for (int i = 0; i != inlineSize; ++i) - gcProtect(imp->values[i]); -#endif int overflowSize = size - inlineSize; ValueImp **overflow = imp->overflow; -#if !USE_CONSERVATIVE_GC for (int i = 0; i != overflowSize; ++i) overflow[i]->ref(); #endif -#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC - for (int i = 0; i != overflowSize; ++i) - gcProtect(overflow[i]); -#endif } void List::markValues() { - ListImp *imp = static_cast(_impBase); - - int size = imp->size; - - int inlineSize = MIN(size, inlineValuesSize); - for (int i = 0; i != inlineSize; ++i) { - if (!imp->values[i]->marked()) { - imp->values[i]->mark(); - } - } - - int overflowSize = size - inlineSize; - ValueImp **overflow = imp->overflow; - for (int i = 0; i != overflowSize; ++i) { - if (!overflow[i]->marked()) { - overflow[i]->mark(); - } - } + static_cast(_impBase)->markValues(); } void List::release() @@ -279,9 +310,6 @@ void List::append(ValueImp *v) if (imp->valueRefCount > 0) { #if !USE_CONSERVATIVE_GC v->ref(); -#endif -#if USE_CONSERVATIVE_GC | TEST_CONSERVATIVE_GC - gcProtect(v); #endif } diff --git a/JavaScriptCore/kjs/list.h b/JavaScriptCore/kjs/list.h index 38ef813391bf..130d6a739856 100644 --- a/JavaScriptCore/kjs/list.h +++ b/JavaScriptCore/kjs/list.h @@ -120,6 +120,8 @@ namespace KJS { static const List &empty(); void mark() { if (_impBase->valueRefCount == 0) markValues(); } + + static void markProtectedLists(); private: ListImpBase *_impBase; bool _needsMarking; -- 2.36.0