Changeset 2748 in webkit for trunk/JavaScriptCore
- Timestamp:
- Nov 18, 2002, 10:20:58 PM (23 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r2747 r2748 1 2002-11-18 Maciej Stachowiak <[email protected]> 2 3 Change List to completely avoid going through the GC 4 allocator. 3.6% performance improvement on JavaScript iBench. 5 6 * kjs/internal.cpp: 7 (InterpreterImp::mark): Don't mark the empty list. 8 9 For all the methods below I basically lifted the ListImp version 10 up to the List method with minor tweaks. 11 12 * kjs/types.cpp: 13 (ListIterator::ListIterator): 14 (List::List): 15 (List::operator=): 16 (List::~List): 17 (List::mark): 18 (List::append): 19 (List::prepend): 20 (List::appendList): 21 (List::prependList): 22 (List::removeFirst): 23 (List::removeLast): 24 (List::remove): 25 (List::clear): 26 (List::clearInternal): 27 (List::copy): 28 (List::begin): 29 (List::end): 30 (List::isEmpty): 31 (List::size): 32 (List::at): 33 (List::operator[]): 34 (List::empty): 35 (List::erase): 36 (List::refAll): 37 (List::derefAll): 38 (List::swap): 39 (List::globalClear): 40 * kjs/types.h: 41 1 42 2002-11-18 Maciej Stachowiak <[email protected]> 2 43 -
trunk/JavaScriptCore/ChangeLog-2002-12-03
r2747 r2748 1 2002-11-18 Maciej Stachowiak <[email protected]> 2 3 Change List to completely avoid going through the GC 4 allocator. 3.6% performance improvement on JavaScript iBench. 5 6 * kjs/internal.cpp: 7 (InterpreterImp::mark): Don't mark the empty list. 8 9 For all the methods below I basically lifted the ListImp version 10 up to the List method with minor tweaks. 11 12 * kjs/types.cpp: 13 (ListIterator::ListIterator): 14 (List::List): 15 (List::operator=): 16 (List::~List): 17 (List::mark): 18 (List::append): 19 (List::prepend): 20 (List::appendList): 21 (List::prependList): 22 (List::removeFirst): 23 (List::removeLast): 24 (List::remove): 25 (List::clear): 26 (List::clearInternal): 27 (List::copy): 28 (List::begin): 29 (List::end): 30 (List::isEmpty): 31 (List::size): 32 (List::at): 33 (List::operator[]): 34 (List::empty): 35 (List::erase): 36 (List::refAll): 37 (List::derefAll): 38 (List::swap): 39 (List::globalClear): 40 * kjs/types.h: 41 1 42 2002-11-18 Maciej Stachowiak <[email protected]> 2 43 -
trunk/JavaScriptCore/ChangeLog-2003-10-25
r2747 r2748 1 2002-11-18 Maciej Stachowiak <[email protected]> 2 3 Change List to completely avoid going through the GC 4 allocator. 3.6% performance improvement on JavaScript iBench. 5 6 * kjs/internal.cpp: 7 (InterpreterImp::mark): Don't mark the empty list. 8 9 For all the methods below I basically lifted the ListImp version 10 up to the List method with minor tweaks. 11 12 * kjs/types.cpp: 13 (ListIterator::ListIterator): 14 (List::List): 15 (List::operator=): 16 (List::~List): 17 (List::mark): 18 (List::append): 19 (List::prepend): 20 (List::appendList): 21 (List::prependList): 22 (List::removeFirst): 23 (List::removeLast): 24 (List::remove): 25 (List::clear): 26 (List::clearInternal): 27 (List::copy): 28 (List::begin): 29 (List::end): 30 (List::isEmpty): 31 (List::size): 32 (List::at): 33 (List::operator[]): 34 (List::empty): 35 (List::erase): 36 (List::refAll): 37 (List::derefAll): 38 (List::swap): 39 (List::globalClear): 40 * kjs/types.h: 41 1 42 2002-11-18 Maciej Stachowiak <[email protected]> 2 43 -
trunk/JavaScriptCore/kjs/internal.cpp
r2741 r2748 668 668 if (BooleanImp::staticFalse && !BooleanImp::staticFalse->marked()) 669 669 BooleanImp::staticFalse->mark(); 670 List::markEmptyList();671 670 //fprintf( stderr, "InterpreterImp::mark this=%p global.imp()=%p\n", this, global.imp() ); 672 671 if (global.imp()) -
trunk/JavaScriptCore/kjs/types.cpp
r2747 r2748 40 40 41 41 namespace KJS { 42 // --------------------------------------------------------------------------- 43 // Internal type impls 44 // --------------------------------------------------------------------------- 45 46 /** 47 * @internal 48 */ 42 49 43 class ListNode { 50 44 friend class List; 51 friend class ListImp;52 45 friend class ListIterator; 53 ListNode(Value val, ListNode *p, ListNode *n) 46 protected: 47 ListNode(const Value &val, ListNode *p, ListNode *n) 54 48 : member(val.imp()), prev(p), next(n) {}; 55 49 ValueImp *member; … … 57 51 }; 58 52 59 class ListImp : public ValueImp { 60 friend class ListIterator; 53 class ListHookNode : public ListNode { 61 54 friend class List; 62 friend class InterpreterImp; 63 friend class ObjectImp; 64 private: 65 ListImp(); 66 ~ListImp(); 67 68 Type type() const { return ListType; } 69 70 virtual void mark(); 71 72 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const; 73 bool toBoolean(ExecState *exec) const; 74 double toNumber(ExecState *exec) const; 75 UString toString(ExecState *exec) const; 76 Object toObject(ExecState *exec) const; 77 78 void append(const Value& val); 79 void prepend(const Value& val); 80 void appendList(const List& lst); 81 void prependList(const List& lst); 82 void removeFirst(); 83 void removeLast(); 84 void remove(const Value &val); 85 void clear(); 86 ListImp *copy() const; 87 ListIterator begin() const { return ListIterator(hook->next); } 88 ListIterator end() const { return ListIterator(hook); } 89 // bool isEmpty() const { return (hook->prev == hook); } 90 bool isEmpty() const; 91 int size() const; 92 Value at(int i) const; 93 Value operator[](int i) const { return at(i); } 94 static ListImp* empty(); 95 96 #ifdef KJS_DEBUG_MEM 97 static int count; 98 #endif 99 private: 100 void erase(ListNode *n); 101 ListNode *hook; 102 static ListImp *emptyList; 55 56 ListHookNode() : ListNode(Value(), NULL, NULL), refcount(1) { prev = this; next = this; } 57 int refcount; 103 58 }; 104 105 } 59 } 106 60 107 61 108 62 // ------------------------------ ListIterator --------------------------------- 109 63 110 //d dont add ListIterator();111 112 64 ListIterator::ListIterator(ListNode *n) : node(n) 113 65 { … … 115 67 116 68 ListIterator::ListIterator(const List &l) 117 : node(l. imp->hook->next)69 : node(l.hook->next) 118 70 { 119 71 } … … 170 122 171 123 List::List(bool needsMarking) 172 : m_needsMarking(needsMarking) 173 { 174 imp = m_needsMarking ? ListImp::empty() : new ListImp(); 175 imp->setGcAllowed(); 176 177 if (!m_needsMarking) { 178 imp->ref(); 124 : hook(new ListHookNode()), 125 m_needsMarking(needsMarking) 126 { 127 if (!m_needsMarking) { 128 refAll(); 179 129 } 180 130 } … … 182 132 183 133 List::List(const List& l) 184 : m_needsMarking(false) 134 : hook(l.hook), 135 m_needsMarking(false) 185 136 { 186 imp = l.imp; 187 188 if (!m_needsMarking) { 189 imp->ref(); 190 } 191 } 192 193 List::List(ListImp *p_imp) 194 : m_needsMarking(false) 195 { 196 imp = p_imp; 197 imp->setGcAllowed(); 198 199 if (!m_needsMarking) { 200 imp->ref(); 201 } 202 } 203 137 hook->refcount++; 138 if (!m_needsMarking) { 139 refAll(); 140 } 141 } 204 142 205 143 List& List::operator=(const List& l) 206 144 { 207 if (!m_needsMarking) { 208 l.imp->ref(); 209 imp->deref(); 210 } 211 212 imp = l.imp; 145 List tmp(l); 146 147 tmp.swap(*this); 213 148 214 149 return *this; … … 218 153 { 219 154 if (!m_needsMarking) { 220 imp->deref(); 155 derefAll(); 156 } 157 158 hook->refcount--; 159 if (hook->refcount == 0) { 160 clearInternal(); 161 delete hook; 221 162 } 222 163 } 223 164 224 165 void List::mark() 225 {226 if (!imp->marked()) {227 imp->mark();228 }229 }230 231 void List::append(const Value& val)232 {233 imp->append(val);234 }235 236 void List::prepend(const Value& val)237 {238 imp->prepend(val);239 }240 241 void List::appendList(const List& lst)242 {243 imp->appendList(lst);244 }245 246 void List::prependList(const List& lst)247 {248 imp->prependList(lst);249 }250 251 void List::removeFirst()252 {253 imp->removeFirst();254 }255 256 void List::removeLast()257 {258 imp->removeLast();259 }260 261 void List::remove(const Value &val)262 {263 imp->remove(val);264 }265 266 void List::clear()267 {268 imp->clear();269 }270 271 List List::copy() const272 {273 return imp->copy();274 }275 276 ListIterator List::begin() const277 {278 return imp->begin();279 }280 281 ListIterator List::end() const282 {283 return imp->end();284 }285 286 bool List::isEmpty() const287 {288 return imp->isEmpty();289 }290 291 int List::size() const292 {293 return imp->size();294 }295 296 Value List::at(int i) const297 {298 return imp->at(i);299 }300 301 Value List::operator[](int i) const302 {303 return imp->at(i);304 }305 306 const List List::empty()307 {308 return ListImp::empty();309 }310 311 #ifdef KJS_DEBUG_MEM312 void List::globalClear()313 {314 delete ListImp::emptyList;315 ListImp::emptyList = 0L;316 }317 #endif318 319 void List::markEmptyList()320 {321 if (ListImp::emptyList && !ListImp::emptyList->marked())322 ListImp::emptyList->mark();323 }324 325 326 // ------------------------------ ListImp --------------------------------------327 328 #ifdef KJS_DEBUG_MEM329 int ListImp::count = 0;330 #endif331 332 Value ListImp::toPrimitive(ExecState */*exec*/, Type /*preferredType*/) const333 {334 // invalid for List335 assert(false);336 return Value();337 }338 339 bool ListImp::toBoolean(ExecState */*exec*/) const340 {341 // invalid for List342 assert(false);343 return false;344 }345 346 double ListImp::toNumber(ExecState */*exec*/) const347 {348 // invalid for List349 assert(false);350 return 0;351 }352 353 UString ListImp::toString(ExecState */*exec*/) const354 {355 // invalid for List356 assert(false);357 return UString::null;358 }359 360 Object ListImp::toObject(ExecState */*exec*/) const361 {362 // invalid for List363 assert(false);364 return Object();365 }366 367 ListImp::ListImp()368 {369 #ifdef KJS_DEBUG_MEM370 count++;371 #endif372 373 hook = new ListNode(Null(), 0L, 0L);374 hook->next = hook;375 hook->prev = hook;376 //fprintf(stderr,"ListImp::ListImp %p hook=%p\n",this,hook);377 }378 379 ListImp::~ListImp()380 {381 //fprintf(stderr,"ListImp::~ListImp %p\n",this);382 #ifdef KJS_DEBUG_MEM383 count--;384 #endif385 386 clear();387 delete hook;388 389 if ( emptyList == this )390 emptyList = 0L;391 }392 393 void ListImp::mark()394 166 { 395 167 ListNode *n = hook->next; … … 399 171 n = n->next; 400 172 } 401 ValueImp::mark(); 402 } 403 404 void ListImp::append(const Value& obj) 405 { 406 ListNode *n = new ListNode(obj, hook->prev, hook); 173 } 174 175 void List::append(const Value& val) 176 { 177 ListNode *n = new ListNode(val, hook->prev, hook); 178 if (!m_needsMarking) { 179 n->member->ref(); 180 } 407 181 hook->prev->next = n; 408 182 hook->prev = n; 409 183 } 410 184 411 void ListImp::prepend(const Value& obj) 412 { 413 ListNode *n = new ListNode(obj, hook, hook->next); 185 void List::prepend(const Value& val) 186 { 187 ListNode *n = new ListNode(val, hook, hook->next); 188 if (!m_needsMarking) { 189 n->member->ref(); 190 } 414 191 hook->next->prev = n; 415 192 hook->next = n; 416 193 } 417 194 418 void List Imp::appendList(const List& lst)195 void List::appendList(const List& lst) 419 196 { 420 197 ListIterator it = lst.begin(); … … 426 203 } 427 204 428 void List Imp::prependList(const List& lst)205 void List::prependList(const List& lst) 429 206 { 430 207 ListIterator it = lst.end(); … … 436 213 } 437 214 438 void List Imp::removeFirst()215 void List::removeFirst() 439 216 { 440 217 erase(hook->next); 441 218 } 442 219 443 void List Imp::removeLast()220 void List::removeLast() 444 221 { 445 222 erase(hook->prev); 446 223 } 447 224 448 void List Imp::remove(const Value &obj)449 { 450 if ( obj.isNull())225 void List::remove(const Value &val) 226 { 227 if (val.isNull()) 451 228 return; 452 229 ListNode *n = hook->next; 453 230 while (n != hook) { 454 if (n->member == obj.imp()) {231 if (n->member == val.imp()) { 455 232 erase(n); 456 233 return; … … 460 237 } 461 238 462 void ListImp::clear() 239 240 void List::clear() 241 { 242 if (!m_needsMarking) { 243 derefAll(); 244 } 245 clearInternal(); 246 } 247 248 void List::clearInternal() 463 249 { 464 250 ListNode *n = hook->next; … … 472 258 } 473 259 474 List Imp *ListImp::copy() const475 { 476 List Imp* newList = new ListImp;260 List List::copy() const 261 { 262 List newList; 477 263 478 264 ListIterator e = end(); … … 480 266 481 267 while(it != e) { 482 newList ->append(*it);268 newList.append(*it); 483 269 ++it; 484 270 } 485 271 486 //fprintf( stderr, "ListImp::copy returning newList=%p\n", newList );487 272 return newList; 488 273 } 489 274 490 void ListImp::erase(ListNode *n) 491 { 492 if (n != hook) { 493 n->next->prev = n->prev; 494 n->prev->next = n->next; 495 delete n; 496 } 497 } 498 499 bool ListImp::isEmpty() const 275 ListIterator List::begin() const 276 { 277 return ListIterator(hook->next); 278 } 279 280 ListIterator List::end() const 281 { 282 return ListIterator(hook); 283 } 284 285 bool List::isEmpty() const 500 286 { 501 287 return (hook->prev == hook); 502 288 } 503 289 504 int List Imp::size() const290 int List::size() const 505 291 { 506 292 int s = 0; … … 512 298 } 513 299 514 Value List Imp::at(int i) const300 Value List::at(int i) const 515 301 { 516 302 if (i < 0 || i >= size()) … … 525 311 } 526 312 527 ListImp *ListImp::emptyList = 0L; 528 529 ListImp *ListImp::empty() 530 { 531 if (!emptyList) 532 emptyList = new ListImp(); 533 return emptyList; 534 } 535 313 Value List::operator[](int i) const 314 { 315 return at(i); 316 } 317 318 const List List::empty() 319 { 320 return List(); 321 } 322 323 324 void List::erase(ListNode *n) 325 { 326 if (n != hook) { 327 if (!m_needsMarking) { 328 n->member->deref(); 329 } 330 n->next->prev = n->prev; 331 n->prev->next = n->next; 332 delete n; 333 } 334 } 335 336 void List::refAll() 337 { 338 ListNode *n = hook->next; 339 340 while (n != hook) { 341 n->member->ref(); 342 n = n->next; 343 } 344 } 345 346 void List::derefAll() 347 { 348 ListNode *n = hook->next; 349 350 while (n != hook) { 351 n->member->deref(); 352 n = n->next; 353 } 354 } 355 356 void List::swap(List &other) 357 { 358 if (m_needsMarking && !other.m_needsMarking) { 359 refAll(); 360 other.derefAll(); 361 } else if (!m_needsMarking && other.m_needsMarking) { 362 other.refAll(); 363 derefAll(); 364 } 365 366 ListHookNode *tmp = hook; 367 hook = other.hook; 368 other.hook = tmp; 369 } 370 371 #ifdef KJS_DEBUG_MEM 372 void List::globalClear() 373 { 374 } 375 #endif 376 -
trunk/JavaScriptCore/kjs/types.h
r2744 r2748 36 36 class ListIterator; 37 37 class ListNode; 38 class ListHookNode; 38 39 39 40 /** … … 42 43 class ListIterator { 43 44 friend class List; 44 friend class ListImp;45 45 ListIterator(); 46 46 ListIterator(ListNode *n); … … 195 195 #endif 196 196 void mark(); 197 static void markEmptyList();198 197 private: 199 List(ListImp *); 200 201 ListImp *imp; 198 199 void erase(ListNode *n); 200 void clearInternal(); 201 void refAll(); 202 void derefAll(); 203 void swap(List &other); 204 205 ListHookNode *hook; 202 206 bool m_needsMarking; 203 friend class ListNode;204 207 }; 205 208
Note:
See TracChangeset
for help on using the changeset viewer.