Changeset 11773 in webkit for trunk/JavaScriptCore
- Timestamp:
- Dec 27, 2005, 1:24:14 AM (19 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r11763 r11773 1 2005-12-26 Maciej Stachowiak <[email protected]> 2 3 Reviewed by Darin and Geoff. 4 5 Changes by me and Anders. 6 7 - mostly fixed REGRESSION: 5-10% performance regression on JS iBench from getter/setter change 8 http://bugzilla.opendarwin.org/show_bug.cgi?id=6083 9 10 - also fixed some warnings reported by -Winline 11 12 * JavaScriptCorePrefix.h: Move new and delete definitions higher so there 13 aren't conflicts with use in standard C++ headers 14 * kjs/object.cpp: 15 (KJS::throwSetterError): Moved this piece of put into a seprate function 16 to avoid the PIC branch. 17 (KJS::JSObject::put): Use hasGetterSetterProperties to avoid expensive stuff 18 when not needed. Also use GetterSetter properties attribute. 19 (KJS::JSObject::deleteProperty): Recompute whether any properties are getter/setter 20 properties any more, if this one was one. 21 (KJS::JSObject::defineGetter): Let the PropertyMap know that it has getter/setter 22 properties now (and use the new attribute). 23 (KJS::JSObject::defineSetter): Ditto. 24 (KJS::JSObject::fillGetterPropertySlot): Out-of-line helper for getOwnPropertySlot, 25 to avoid global variable access in the hot code path. 26 * kjs/object.h: 27 (KJS::): Added GetterSetter attribute. 28 (KJS::JSCell::isObject): Moved lower to be after inline methods it uses. 29 (KJS::JSValue::isObject): ditto 30 (KJS::JSObject::getOwnPropertySlot): try to avoid impact of getters and setters 31 as much as possible in the case where they are not being used 32 * kjs/property_map.cpp: 33 (KJS::PropertyMap::containsGettersOrSetters): New method to help with this 34 * kjs/property_map.h: 35 (KJS::PropertyMap::hasGetterSetterProperties): Ditto 36 (KJS::PropertyMap::setHasGetterSetterProperties): Ditto 37 (KJS::PropertyMap::PropertyMap): Added a crazy hack to store the 38 global "has getter/setter properties" flag in the property map 39 single entry, to avoid making objects any bigger. 40 * kjs/value.h: Moved some things to object.h to make -Winline happier 41 1 42 2005-12-24 Maciej Stachowiak <[email protected]> 2 43 -
trunk/JavaScriptCore/JavaScriptCorePrefix.h
r10701 r11773 1 #ifdef __cplusplus 2 #define new ("if you use new/delete make sure to include config.h at the top of the file"()) 3 #define delete ("if you use new/delete make sure to include config.h at the top of the file"()) 4 #endif 5 1 6 #ifdef __cplusplus 2 7 #define NULL __null … … 4 9 #define NULL ((void *)0) 5 10 #endif 11 12 #include "config.h" 6 13 7 14 #include <assert.h> … … 41 48 #include <typeinfo> 42 49 43 #ifdef __cplusplus44 #define new ("if you use new/delete make sure to include config.h at the top of the file"())45 #define delete ("if you use new/delete make sure to include config.h at the top of the file"())46 50 #endif 47 #endif -
trunk/JavaScriptCore/kjs/object.cpp
r11566 r11773 191 191 } 192 192 193 static void throwSetterError(ExecState *exec) 194 { 195 throwError(exec, TypeError, "setting a property that has only a getter"); 196 } 197 193 198 // ECMA 8.6.2.2 194 199 void JSObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) … … 216 221 JSObject *obj = this; 217 222 while (true) { 218 if (JSValue *gs = obj->_prop.get(propertyName)) { 219 if (gs->type() == GetterSetterType) { 223 JSValue *gs; 224 int attributes; 225 if (obj->_prop.hasGetterSetterProperties() && (gs = obj->_prop.get(propertyName, attributes))) { 226 if (attributes & GetterSetter) { 220 227 JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter(); 221 228 222 229 if (!setterFunc) { 223 throw Error(exec, TypeError, "setting a property that has only a getter");230 throwSetterError(exec); 224 231 return; 225 232 } … … 237 244 } 238 245 239 if (!obj->_proto || !obj->_proto->isObject())246 if (!obj->_proto->isObject()) 240 247 break; 241 248 … … 288 295 return false; 289 296 _prop.remove(propertyName); 297 if (attributes & GetterSetter) 298 _prop.setHasGetterSetterProperties(_prop.containsGettersOrSetters()); 290 299 return true; 291 300 } … … 371 380 } else { 372 381 gs = new GetterSetterImp; 373 putDirect(propertyName, gs); 374 } 375 382 putDirect(propertyName, gs, GetterSetter); 383 } 384 385 _prop.setHasGetterSetterProperties(true); 376 386 gs->setGetter(getterFunc); 377 387 } … … 387 397 gs = new GetterSetterImp; 388 398 putDirect(propertyName, gs); 389 } 390 399 putDirect(propertyName, gs, GetterSetter); 400 } 401 402 _prop.setHasGetterSetterProperties(true); 391 403 gs->setSetter(setterFunc); 392 404 } … … 519 531 { 520 532 _prop.put(propertyName, jsNumber(value), attr); 533 } 534 535 void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue **location) 536 { 537 GetterSetterImp *gs = static_cast<GetterSetterImp *>(*location); 538 JSObject *getterFunc = gs->getGetter(); 539 if (getterFunc) 540 slot.setGetterSlot(this, getterFunc); 541 else 542 slot.setUndefined(this); 521 543 } 522 544 -
trunk/JavaScriptCore/kjs/object.h
r11566 r11773 51 51 // ECMA 262-3 8.6.1 52 52 // Property attributes 53 enum Attribute { None = 0, 54 ReadOnly = 1 << 1, // property can be only read, not written 55 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) 56 DontDelete = 1 << 3, // property can't be deleted 57 Internal = 1 << 4, // an internal property, set to bypass checks 58 Function = 1 << 5 }; // property is a function - only used by static hashtables 53 enum Attribute { None = 0, 54 ReadOnly = 1 << 1, // property can be only read, not written 55 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) 56 DontDelete = 1 << 3, // property can't be deleted 57 Internal = 1 << 4, // an internal property, set to bypass checks 58 Function = 1 << 5, // property is a function - only used by static hashtables 59 GetterSetter = 1 << 6 }; // property is a getter or setter 59 60 60 61 /** … … 503 504 void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0); 504 505 void putDirect(const Identifier &propertyName, int value, int attr = 0); 505 506 507 void fillGetterPropertySlot(PropertySlot& slot, JSValue **location); 508 506 509 void defineGetter(ExecState *exec, const Identifier& propertyName, JSObject *getterFunc); 507 510 void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc); … … 567 570 JSObject *throwError(ExecState *, ErrorType, const char *message); 568 571 JSObject *throwError(ExecState *, ErrorType); 569 570 inline bool JSCell::isObject(const ClassInfo *info) const571 {572 return isObject() && static_cast<const JSObject *>(this)->inherits(info);573 }574 572 575 573 inline JSObject::JSObject(JSObject *proto) … … 613 611 } 614 612 613 // this method is here to be after the inline declaration of JSObject::inherits 614 inline bool JSCell::isObject(const ClassInfo *info) const 615 { 616 return isObject() && static_cast<const JSObject *>(this)->inherits(info); 617 } 618 619 // this method is here to be after the inline declaration of JSCell::isObject 620 inline bool JSValue::isObject(const ClassInfo *c) const 621 { 622 return !SimpleNumber::is(this) && downcast()->isObject(c); 623 } 624 615 625 // It may seem crazy to inline a function this large but it makes a big difference 616 626 // since this is function very hot in variable lookup … … 633 643 // but it makes a big difference to property lookup that derived classes can inline their 634 644 // base class call to this. 635 inlinebool JSObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)645 ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 636 646 { 637 647 if (JSValue **location = getDirectLocation(propertyName)) { 638 if ((*location)->type() == GetterSetterType) { 639 GetterSetterImp *gs = static_cast<GetterSetterImp *>(*location); 640 JSObject *getterFunc = gs->getGetter(); 641 if (getterFunc) 642 slot.setGetterSlot(this, getterFunc); 643 else 644 slot.setUndefined(this); 645 } else { 648 if (_prop.hasGetterSetterProperties() && location[0]->type() == GetterSetterType) 649 fillGetterPropertySlot(slot, location); 650 else 646 651 slot.setValueSlot(this, location); 647 }648 652 return true; 649 653 } -
trunk/JavaScriptCore/kjs/property_map.cpp
r11763 r11773 567 567 } 568 568 569 bool PropertyMap::containsGettersOrSetters() const 570 { 571 if (!_table) { 572 #if USE_SINGLE_ENTRY 573 return _singleEntry.attributes & GetterSetter; 574 #endif 575 return false; 576 } 577 578 for (int i = 0; i != _table->size; ++i) { 579 if (_table->entries[i].attributes & GetterSetter) 580 return true; 581 } 582 583 return false; 584 } 585 569 586 void PropertyMap::addEnumerablesToReferenceList(ReferenceList &list, JSObject *base) const 570 587 { -
trunk/JavaScriptCore/kjs/property_map.h
r11527 r11773 61 61 UString::Rep *key; 62 62 JSValue *value; 63 int attributes; 63 short attributes; 64 short globalGetterSetterFlag; 64 65 int index; 65 66 }; … … 88 89 void restore(const SavedProperties &p); 89 90 91 bool hasGetterSetterProperties() const { return _singleEntry.globalGetterSetterFlag; } 92 void setHasGetterSetterProperties(bool f) { _singleEntry.globalGetterSetterFlag = f; } 93 94 bool containsGettersOrSetters() const; 90 95 private: 91 96 static bool keysMatch(const UString::Rep *, const UString::Rep *); … … 106 111 }; 107 112 108 inline PropertyMap::PropertyMap() : _table( NULL)113 inline PropertyMap::PropertyMap() : _table(0) 109 114 { 115 _singleEntry.globalGetterSetterFlag = 0; 110 116 } 111 117 -
trunk/JavaScriptCore/kjs/value.h
r11566 r11773 314 314 } 315 315 316 inline bool JSValue::isObject(const ClassInfo *c) const317 {318 return !SimpleNumber::is(this) && downcast()->isObject(c);319 }320 321 316 inline bool JSValue::getBoolean(bool& v) const 322 317 {
Note:
See TracChangeset
for help on using the changeset viewer.