Changeset 44076 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- May 22, 2009, 6:48:32 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSActivation.cpp
r43603 r44076 119 119 120 120 // FIXME: Make this function honor ReadOnly (const) and DontEnum 121 void JSActivation::putWithAttributes(ExecState* , const Identifier& propertyName, JSValue value, unsigned attributes)121 void JSActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) 122 122 { 123 123 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); … … 131 131 ASSERT(!hasGetterSetterProperties()); 132 132 PutPropertySlot slot; 133 putDirect(propertyName, value, attributes, true, slot);133 JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot); 134 134 } 135 135 -
trunk/JavaScriptCore/runtime/JSGlobalObject.cpp
r43226 r44076 171 171 JSValue valueAfter = getDirect(propertyName); 172 172 if (valueAfter) 173 putDirect(propertyName, valueAfter, attributes);173 JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes); 174 174 } 175 175 } … … 240 240 d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype); 241 241 242 d()->methodCallDummy = constructEmptyObject(exec); 243 242 244 ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get()); 243 245 d()->errorStructure = ErrorInstance::createStructure(errorPrototype); … … 254 256 // Constructors 255 257 256 JS ValueobjectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);257 JS ValuefunctionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);258 JS ValuearrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);259 JS ValuestringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);260 JS ValuebooleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);261 JS ValuenumberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);262 JS ValuedateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);258 JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype); 259 JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype); 260 JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype); 261 JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype); 262 JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype); 263 JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype); 264 JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype); 263 265 264 266 d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype); … … 275 277 d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype); 276 278 277 d()->objectPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);278 d()->functionPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);279 d()->arrayPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);280 d()->booleanPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);281 d()->stringPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);282 d()->numberPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);283 d()->datePrototype->putDirect WithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);284 d()->regExpPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);285 errorPrototype->putDirect WithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);279 d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum); 280 d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum); 281 d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum); 282 d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum); 283 d()->stringPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum); 284 d()->numberPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum); 285 d()->datePrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum); 286 d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum); 287 errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum); 286 288 287 289 evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum); … … 296 298 // FIXME: These properties could be handled by a static hash table. 297 299 298 putDirect WithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);299 putDirect WithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);300 putDirect WithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);301 putDirect WithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);302 putDirect WithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);303 putDirect WithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);304 putDirect WithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);305 putDirect WithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);306 putDirect WithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);307 putDirect WithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);308 putDirect WithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);309 putDirect WithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);310 putDirect WithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);311 putDirect WithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);312 putDirect WithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);300 putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum); 301 putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum); 302 putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum); 303 putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum); 304 putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum); 305 putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum); 306 putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum); 307 putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum); 308 putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum); 309 putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor); 310 putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor); 311 putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor); 312 putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor); 313 putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor); 314 putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor); 313 315 314 316 // Set global values. … … 388 390 markIfNeeded(d()->regExpPrototype); 389 391 392 markIfNeeded(d()->methodCallDummy); 393 390 394 markIfNeeded(d()->errorStructure); 391 395 -
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r43220 r44076 80 80 , datePrototype(0) 81 81 , regExpPrototype(0) 82 , methodCallDummy(0) 82 83 { 83 84 } … … 120 121 DatePrototype* datePrototype; 121 122 RegExpPrototype* regExpPrototype; 123 124 JSObject* methodCallDummy; 122 125 123 126 RefPtr<Structure> argumentsStructure; … … 202 205 RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; } 203 206 207 JSObject* methodCallDummy() const { return d()->methodCallDummy; } 208 204 209 Structure* argumentsStructure() const { return d()->argumentsStructure.get(); } 205 210 Structure* arrayStructure() const { return d()->arrayStructure.get(); } -
trunk/JavaScriptCore/runtime/JSObject.cpp
r43551 r44076 130 130 prototype = obj->prototype(); 131 131 if (prototype.isNull()) { 132 putDirect (propertyName, value, 0, true, slot);132 putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); 133 133 return; 134 134 } … … 136 136 137 137 unsigned attributes; 138 if ((m_structure->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly) 138 JSCell* specificValue; 139 if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) 139 140 return; 140 141 … … 166 167 } 167 168 168 putDirect (propertyName, value, 0, true, slot);169 putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); 169 170 return; 170 171 } … … 176 177 } 177 178 178 void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes) 179 { 180 putDirect(propertyName, value, attributes); 179 void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 180 { 181 putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot); 182 } 183 184 void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) 185 { 186 putDirectInternal(exec->globalData(), propertyName, value, attributes); 181 187 } 182 188 … … 202 208 { 203 209 unsigned attributes; 204 if (m_structure->get(propertyName, attributes) != WTF::notFound) { 210 JSCell* specificValue; 211 if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) { 205 212 if ((attributes & DontDelete)) 206 213 return false; … … 305 312 PutPropertySlot slot; 306 313 GetterSetter* getterSetter = new (exec) GetterSetter; 307 putDirect (propertyName, getterSetter, None, true, slot);314 putDirectInternal(exec->globalData(), propertyName, getterSetter, None, true, slot); 308 315 309 316 // putDirect will change our Structure if we add a new property. For … … 332 339 PutPropertySlot slot; 333 340 GetterSetter* getterSetter = new (exec) GetterSetter; 334 putDirect (propertyName, getterSetter, None, true, slot);341 putDirectInternal(exec->globalData(), propertyName, getterSetter, None, true, slot); 335 342 336 343 // putDirect will change our Structure if we add a new property. For … … 414 421 bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const 415 422 { 416 if (m_structure->get(propertyName, attributes) != WTF::notFound) 423 JSCell* specificValue; 424 if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) 417 425 return true; 418 426 … … 427 435 } 428 436 437 bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const 438 { 439 unsigned attributes; 440 if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) 441 return true; 442 443 // This could be a function within the static table? - should probably 444 // also look in the hash? This currently should not be a problem, since 445 // we've currently always call 'get' first, which should have populated 446 // the normal storage. 447 return false; 448 } 449 429 450 void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) 430 451 { … … 486 507 void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr) 487 508 { 488 putDirect (Identifier(exec, function->name(&exec->globalData())), function, attr);509 putDirectFunction(Identifier(exec, function->name(&exec->globalData())), function, attr); 489 510 } 490 511 491 512 void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr) 492 513 { 493 putDirect WithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);514 putDirectFunctionWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr); 494 515 } 495 516 -
trunk/JavaScriptCore/runtime/JSObject.h
r43692 r44076 33 33 #include "ScopeChain.h" 34 34 #include "Structure.h" 35 #include "JSGlobalData.h" 35 36 36 37 namespace JSC { 38 39 inline JSCell* getJSFunction(JSGlobalData& globalData, JSValue value) 40 { 41 if (value.isCell() && (value.asCell()->vptr() == globalData.jsFunctionVPtr)) 42 return value.asCell(); 43 return 0; 44 } 37 45 38 46 class InternalFunction; … … 94 102 virtual void put(ExecState*, unsigned propertyName, JSValue value); 95 103 104 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot); 96 105 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes); 97 106 virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValue value, unsigned attributes); … … 123 132 124 133 virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; 134 bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const; 125 135 126 136 // This get function only looks at the property map. … … 144 154 JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes) 145 155 { 146 size_t offset = m_structure->get(propertyName, attributes); 156 JSCell* specificFunction; 157 size_t offset = m_structure->get(propertyName, attributes, specificFunction); 147 158 return offset != WTF::notFound ? locationForOffset(offset) : 0; 148 159 } … … 169 180 bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); } 170 181 182 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 171 183 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0); 172 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 184 185 void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0); 186 void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 173 187 void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0); 188 174 189 void putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attr = 0); 190 void putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attr = 0); 175 191 void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0); 176 192 … … 208 224 209 225 private: 226 void putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*); 227 void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 228 void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0); 229 210 230 bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 211 231 … … 397 417 } 398 418 399 inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attr) 400 { 401 PutPropertySlot slot; 402 putDirect(propertyName, value, attr, false, slot); 403 } 404 405 inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 419 inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction) 406 420 { 407 421 ASSERT(value); … … 410 424 if (m_structure->isDictionary()) { 411 425 unsigned currentAttributes; 412 size_t offset = m_structure->get(propertyName, currentAttributes); 426 JSCell* currentSpecificFunction; 427 size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction); 413 428 if (offset != WTF::notFound) { 414 429 if (checkReadOnly && currentAttributes & ReadOnly) … … 420 435 421 436 size_t currentCapacity = m_structure->propertyStorageCapacity(); 422 offset = m_structure->addPropertyWithoutTransition(propertyName, attributes );437 offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction); 423 438 if (currentCapacity != m_structure->propertyStorageCapacity()) 424 439 allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); … … 426 441 ASSERT(offset < m_structure->propertyStorageCapacity()); 427 442 putDirectOffset(offset, value); 428 slot.setNewProperty(this, offset); 443 // See comment on setNewProperty call below. 444 if (!specificFunction) 445 slot.setNewProperty(this, offset); 429 446 return; 430 447 } … … 432 449 size_t offset; 433 450 size_t currentCapacity = m_structure->propertyStorageCapacity(); 434 if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, offset)) {451 if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) { 435 452 if (currentCapacity != structure->propertyStorageCapacity()) 436 453 allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); … … 439 456 setStructure(structure.release()); 440 457 putDirectOffset(offset, value); 441 slot.setNewProperty(this, offset); 442 slot.setWasTransition(true); 458 // See comment on setNewProperty call below. 459 if (!specificFunction) 460 slot.setNewProperty(this, offset); 443 461 return; 444 462 } 445 463 446 464 unsigned currentAttributes; 447 offset = m_structure->get(propertyName, currentAttributes); 465 JSCell* currentSpecificFunction; 466 offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction); 448 467 if (offset != WTF::notFound) { 449 468 if (checkReadOnly && currentAttributes & ReadOnly) 450 469 return; 470 471 if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) { 472 setStructure(Structure::changeFunctionTransition(m_structure, propertyName)); 473 putDirectOffset(offset, value); 474 // Function transitions are not currently cachable, so leave the slot in an uncachable state. 475 return; 476 } 451 477 putDirectOffset(offset, value); 452 478 slot.setExistingProperty(this, offset); … … 454 480 } 455 481 456 RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, offset);482 RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset); 457 483 if (currentCapacity != structure->propertyStorageCapacity()) 458 484 allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); … … 461 487 setStructure(structure.release()); 462 488 putDirectOffset(offset, value); 463 slot.setNewProperty(this, offset); 464 slot.setWasTransition(true); 489 // Function transitions are not currently cachable, so leave the slot in an uncachable state. 490 if (!specificFunction) 491 slot.setNewProperty(this, offset); 492 } 493 494 inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 495 { 496 ASSERT(value); 497 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 498 499 putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value)); 500 } 501 502 inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes) 503 { 504 PutPropertySlot slot; 505 putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value)); 506 } 507 508 inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 509 { 510 ASSERT(value); 511 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 512 513 putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0); 514 } 515 516 inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes) 517 { 518 PutPropertySlot slot; 519 putDirectInternal(propertyName, value, attributes, false, slot, 0); 520 } 521 522 inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 523 { 524 putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value); 525 } 526 527 inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr) 528 { 529 PutPropertySlot slot; 530 putDirectInternal(propertyName, value, attr, false, slot, value); 465 531 } 466 532 … … 468 534 { 469 535 size_t currentCapacity = m_structure->propertyStorageCapacity(); 470 size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes); 536 size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0); 537 if (currentCapacity != m_structure->propertyStorageCapacity()) 538 allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); 539 putDirectOffset(offset, value); 540 } 541 542 inline void JSObject::putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attributes) 543 { 544 size_t currentCapacity = m_structure->propertyStorageCapacity(); 545 size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value); 471 546 if (currentCapacity != m_structure->propertyStorageCapacity()) 472 547 allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); -
trunk/JavaScriptCore/runtime/Lookup.cpp
r43225 r44076 72 72 if (!location) { 73 73 InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function()); 74 thisObj->putDirect(propertyName, function, entry->attributes()); 74 75 thisObj->putDirectFunction(propertyName, function, entry->attributes()); 75 76 location = thisObj->getDirectLocation(propertyName); 76 77 } -
trunk/JavaScriptCore/runtime/Lookup.h
r43220 r44076 230 230 return false; 231 231 232 if (entry->attributes() & Function) // function: put as override property 233 thisObj->putDirect(propertyName, value); 234 else if (!(entry->attributes() & ReadOnly)) 232 if (entry->attributes() & Function) { // function: put as override property 233 if (LIKELY(value.isCell())) 234 thisObj->putDirectFunction(propertyName, value.asCell()); 235 else 236 thisObj->putDirect(propertyName, value); 237 } else if (!(entry->attributes() & ReadOnly)) 235 238 entry->propertyPutter()(exec, thisObj, value); 236 239 -
trunk/JavaScriptCore/runtime/PropertyMapHashTable.h
r39502 r44076 31 31 unsigned offset; 32 32 unsigned attributes; 33 JSCell* specificValue; 33 34 unsigned index; 34 35 35 PropertyMapEntry(UString::Rep* key, unsigned attributes )36 PropertyMapEntry(UString::Rep* key, unsigned attributes, JSCell* specificValue) 36 37 : key(key) 37 38 , offset(0) 38 39 , attributes(attributes) 40 , specificValue(specificValue) 39 41 , index(0) 40 42 { 41 43 } 42 44 43 PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, unsigned index)45 PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index) 44 46 : key(key) 45 47 , offset(offset) 46 48 , attributes(attributes) 49 , specificValue(specificValue) 47 50 , index(index) 48 51 { -
trunk/JavaScriptCore/runtime/PutPropertySlot.h
r37938 r44076 33 33 34 34 class JSObject; 35 class JSFunction; 35 36 36 37 class PutPropertySlot { 37 38 public: 38 enum Type { Invalid, ExistingProperty, NewProperty };39 enum Type { Uncachable, ExistingProperty, NewProperty }; 39 40 40 41 PutPropertySlot() 41 : m_type( Invalid)42 : m_type(Uncachable) 42 43 , m_base(0) 43 , m_wasTransition(false)44 44 { 45 45 } … … 62 62 JSObject* base() const { return m_base; } 63 63 64 bool isCacheable() const { return m_type != Invalid; }64 bool isCacheable() const { return m_type != Uncachable; } 65 65 size_t cachedOffset() const { 66 66 ASSERT(isCacheable()); 67 67 return m_offset; 68 68 } 69 70 bool wasTransition() const { return m_wasTransition; }71 void setWasTransition(bool wasTransition) { m_wasTransition = wasTransition; }72 69 private: 73 70 Type m_type; 74 71 JSObject* m_base; 75 bool m_wasTransition;76 72 size_t m_offset; 77 73 }; -
trunk/JavaScriptCore/runtime/Structure.cpp
r43122 r44076 124 124 : m_typeInfo(typeInfo) 125 125 , m_prototype(prototype) 126 , m_specificValueInPrevious(0) 126 127 , m_propertyTable(0) 127 128 , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) … … 159 160 m_previous->m_transitions.singleTransition = 0; 160 161 } else { 161 ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m _attributesInPrevious)));162 m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m _attributesInPrevious));162 ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious)))); 163 m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious))); 163 164 } 164 165 } … … 280 281 structure = structures[i]; 281 282 structure->m_nameInPrevious->ref(); 282 PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, ++m_propertyTable->lastIndexUsed);283 PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed); 283 284 insertIntoPropertyMapHashTable(entry); 284 285 } … … 327 328 } 328 329 329 PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)330 PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) 330 331 { 331 332 ASSERT(!structure->m_isDictionary); … … 334 335 if (structure->m_usingSingleTransitionSlot) { 335 336 Structure* existingTransition = structure->m_transitions.singleTransition; 336 if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) { 337 if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() 338 && existingTransition->m_attributesInPrevious == attributes 339 && existingTransition->m_specificValueInPrevious == specificValue) { 340 337 341 ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset); 338 342 offset = structure->m_transitions.singleTransition->m_offset; … … 340 344 } 341 345 } else { 342 if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {346 if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), make_pair(attributes, specificValue)))) { 343 347 ASSERT(existingTransition->m_offset != noOffset); 344 348 offset = existingTransition->m_offset; … … 350 354 } 351 355 352 PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)356 PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) 353 357 { 354 358 ASSERT(!structure->m_isDictionary); 355 359 ASSERT(structure->typeInfo().type() == ObjectType); 356 ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));360 ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); 357 361 358 362 if (structure->transitionCount() > s_maxTransitionLength) { 359 363 RefPtr<Structure> transition = toDictionaryTransition(structure); 360 offset = transition->put(propertyName, attributes );364 offset = transition->put(propertyName, attributes, specificValue); 361 365 if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) 362 366 transition->growPropertyStorageCapacity(); … … 365 369 366 370 RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); 371 367 372 transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; 368 373 transition->m_previous = structure; 369 374 transition->m_nameInPrevious = propertyName.ustring().rep(); 370 375 transition->m_attributesInPrevious = attributes; 376 transition->m_specificValueInPrevious = specificValue; 371 377 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 372 378 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; … … 386 392 } 387 393 388 offset = transition->put(propertyName, attributes );394 offset = transition->put(propertyName, attributes, specificValue); 389 395 if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) 390 396 transition->growPropertyStorageCapacity(); … … 402 408 StructureTransitionTable* transitionTable = new StructureTransitionTable; 403 409 structure->m_transitions.table = transitionTable; 404 transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition);405 } 406 structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());410 transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), make_pair(existingTransition->m_attributesInPrevious, existingTransition->m_specificValueInPrevious)), existingTransition); 411 } 412 structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), make_pair(attributes, specificValue)), transition.get()); 407 413 return transition.release(); 408 414 } … … 431 437 transition->m_propertyTable = structure->copyPropertyTable(); 432 438 transition->m_isPinnedPropertyTable = true; 439 440 return transition.release(); 441 } 442 443 PassRefPtr<Structure> Structure::changeFunctionTransition(Structure* structure, const Identifier& replaceFunction) 444 { 445 RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo()); 446 447 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 448 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 449 450 // Don't set m_offset, as one can not transition to this. 451 452 structure->materializePropertyMapIfNecessary(); 453 transition->m_propertyTable = structure->copyPropertyTable(); 454 transition->m_isPinnedPropertyTable = true; 455 456 bool removed = transition->despecifyFunction(replaceFunction); 457 ASSERT_UNUSED(removed, removed); 433 458 434 459 return transition.release(); … … 482 507 } 483 508 484 size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes )509 size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) 485 510 { 486 511 ASSERT(!m_transitions.singleTransition); … … 489 514 490 515 m_isPinnedPropertyTable = true; 491 size_t offset = put(propertyName, attributes );516 size_t offset = put(propertyName, attributes, specificValue); 492 517 if (propertyStorageSize() > propertyStorageCapacity()) 493 518 growPropertyStorageCapacity(); … … 565 590 } 566 591 567 size_t Structure::get(const Identifier& propertyName, unsigned& attributes) 568 { 569 ASSERT(!propertyName.isNull()); 570 592 size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue) 593 { 571 594 materializePropertyMapIfNecessary(); 572 595 if (!m_propertyTable) 573 596 return notFound; 574 597 575 UString::Rep* rep = propertyName._ustring.rep();576 577 598 unsigned i = rep->computedHash(); 578 599 … … 587 608 if (rep == m_propertyTable->entries()[entryIndex - 1].key) { 588 609 attributes = m_propertyTable->entries()[entryIndex - 1].attributes; 610 specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue; 589 611 return m_propertyTable->entries()[entryIndex - 1].offset; 590 612 } … … 609 631 if (rep == m_propertyTable->entries()[entryIndex - 1].key) { 610 632 attributes = m_propertyTable->entries()[entryIndex - 1].attributes; 633 specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue; 611 634 return m_propertyTable->entries()[entryIndex - 1].offset; 612 635 } … … 614 637 } 615 638 616 size_t Structure::put(const Identifier& propertyName, unsigned attributes) 639 bool Structure::despecifyFunction(const Identifier& propertyName) 640 { 641 ASSERT(!propertyName.isNull()); 642 643 materializePropertyMapIfNecessary(); 644 if (!m_propertyTable) 645 return false; 646 647 UString::Rep* rep = propertyName._ustring.rep(); 648 649 unsigned i = rep->computedHash(); 650 651 #if DUMP_PROPERTYMAP_STATS 652 ++numProbes; 653 #endif 654 655 unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; 656 if (entryIndex == emptyEntryIndex) 657 return false; 658 659 if (rep == m_propertyTable->entries()[entryIndex - 1].key) { 660 ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue); 661 m_propertyTable->entries()[entryIndex - 1].specificValue = 0; 662 return true; 663 } 664 665 #if DUMP_PROPERTYMAP_STATS 666 ++numCollisions; 667 #endif 668 669 unsigned k = 1 | doubleHash(rep->computedHash()); 670 671 while (1) { 672 i += k; 673 674 #if DUMP_PROPERTYMAP_STATS 675 ++numRehashes; 676 #endif 677 678 entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; 679 if (entryIndex == emptyEntryIndex) 680 return false; 681 682 if (rep == m_propertyTable->entries()[entryIndex - 1].key) { 683 ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue); 684 m_propertyTable->entries()[entryIndex - 1].specificValue = 0; 685 return true; 686 } 687 } 688 } 689 690 size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) 617 691 { 618 692 ASSERT(!propertyName.isNull()); … … 684 758 m_propertyTable->entries()[entryIndex - 1].key = rep; 685 759 m_propertyTable->entries()[entryIndex - 1].attributes = attributes; 760 m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue; 686 761 m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed; 687 762 … … 756 831 m_propertyTable->entries()[entryIndex - 1].key = 0; 757 832 m_propertyTable->entries()[entryIndex - 1].attributes = 0; 833 m_propertyTable->entries()[entryIndex - 1].specificValue = 0; 758 834 m_propertyTable->entries()[entryIndex - 1].offset = 0; 759 835 -
trunk/JavaScriptCore/runtime/Structure.h
r43432 r44076 62 62 static void dumpStatistics(); 63 63 64 static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);65 static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);64 static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); 65 static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); 66 66 static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset); 67 67 static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype); 68 static PassRefPtr<Structure> changeFunctionTransition(Structure*, const Identifier&); 68 69 static PassRefPtr<Structure> getterSetterTransition(Structure*); 69 70 static PassRefPtr<Structure> toDictionaryTransition(Structure*); … … 79 80 80 81 // These should be used with caution. 81 size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes );82 size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); 82 83 size_t removePropertyWithoutTransition(const Identifier& propertyName); 83 84 void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; } … … 99 100 100 101 size_t get(const Identifier& propertyName); 101 size_t get(const Identifier& propertyName, unsigned& attributes); 102 size_t get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue); 103 size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) 104 { 105 ASSERT(!propertyName.isNull()); 106 return get(propertyName._ustring.rep(), attributes, specificValue); 107 } 108 102 109 void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); 103 110 … … 107 114 bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } 108 115 116 JSCell* specificValue() { return m_specificValueInPrevious; } 117 109 118 private: 110 119 Structure(JSValue prototype, const TypeInfo&); 111 120 112 size_t put(const Identifier& propertyName, unsigned attributes );121 size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); 113 122 size_t remove(const Identifier& propertyName); 114 123 void getEnumerableNamesFromPropertyTable(PropertyNameArray&); … … 123 132 void checkConsistency(); 124 133 134 bool despecifyFunction(const Identifier&); 135 125 136 PropertyMapHashTable* copyPropertyTable(); 126 137 void materializePropertyMap(); … … 160 171 StructureTransitionTable* table; 161 172 } m_transitions; 173 JSCell* m_specificValueInPrevious; 162 174 163 175 RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData; -
trunk/JavaScriptCore/runtime/StructureTransitionTable.h
r38440 r44076 38 38 39 39 struct StructureTransitionTableHash { 40 typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;40 typedef std::pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> > Key; 41 41 static unsigned hash(const Key& p) 42 42 { … … 54 54 struct StructureTransitionTableHashTraits { 55 55 typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits; 56 typedef WTF::GenericHashTraits<unsigned> SecondTraits; 57 typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType; 56 typedef WTF::GenericHashTraits<unsigned> SecondFirstTraits; 57 typedef WTF::GenericHashTraits<JSCell*> SecondSecondTraits; 58 typedef std::pair<FirstTraits::TraitType, std::pair<SecondFirstTraits::TraitType, SecondSecondTraits::TraitType> > TraitType; 58 59 59 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && Second Traits::emptyValueIsZero;60 static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }60 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondFirstTraits::emptyValueIsZero && SecondSecondTraits::emptyValueIsZero; 61 static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), std::make_pair(SecondFirstTraits::emptyValue(), SecondSecondTraits::emptyValue())); } 61 62 62 static const bool needsDestruction = FirstTraits::needsDestruction || Second Traits::needsDestruction;63 static const bool needsDestruction = FirstTraits::needsDestruction || SecondFirstTraits::needsDestruction || SecondSecondTraits::needsDestruction; 63 64 64 65 static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
Note:
See TracChangeset
for help on using the changeset viewer.