Changeset 78732 in webkit for trunk/Source/JavaScriptCore/runtime/JSObject.h
- Timestamp:
- Feb 16, 2011, 1:35:19 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSObject.h
r77269 r78732 81 81 82 82 public: 83 explicit JSObject(NonNullPassRefPtr<Structure>);84 85 83 virtual void markChildren(MarkStack&); 86 84 ALWAYS_INLINE void markChildrenDirect(MarkStack& markStack); … … 216 214 217 215 void allocatePropertyStorage(size_t oldSize, size_t newSize); 218 void allocatePropertyStorageInline(size_t oldSize, size_t newSize);219 216 bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } 220 217 221 static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; 222 static const unsigned nonInlineBaseStorageCapacity = 16; 223 224 static PassRefPtr<Structure> createStructure(JSValue prototype) 225 { 226 return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 227 } 218 static const unsigned baseExternalStorageCapacity = 16; 228 219 229 220 void flattenDictionaryObject(JSGlobalData& globalData) … … 247 238 return locationForOffset(index)->get(); 248 239 } 240 241 static size_t offsetOfInlineStorage(); 249 242 250 243 protected: 251 244 static const unsigned StructureFlags = 0; 252 245 253 246 void putThisToAnonymousValue(unsigned index) 254 247 { 255 248 locationForOffset(index)->setWithoutWriteBarrier(this); 256 249 } 257 250 251 // To instantiate objects you likely want JSFinalObject, below. 252 // To create derived types you likely want JSNonFinalObject, below. 253 JSObject(NonNullPassRefPtr<Structure>, PropertyStorage inlineStorage); 254 258 255 private: 259 256 // Nobody should ever ask any of these questions on something already known to be a JSObject. … … 266 263 void isString(); 267 264 268 ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }269 PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }265 ConstPropertyStorage propertyStorage() const { return m_propertyStorage; } 266 PropertyStorage propertyStorage() { return m_propertyStorage; } 270 267 271 268 const WriteBarrierBase<Unknown>* locationForOffset(size_t offset) const … … 288 285 Structure* createInheritorID(); 289 286 290 union { 291 PropertyStorage m_externalStorage; 292 WriteBarrierBase<Unknown> m_inlineStorage[inlineStorageCapacity]; 293 }; 294 287 PropertyStorage m_propertyStorage; 295 288 RefPtr<Structure> m_inheritorID; 296 289 }; 297 290 291 292 #if USE(JSVALUE32_64) 293 #define JSNonFinalObject_inlineStorageCapacity 4 294 #define JSFinalObject_inlineStorageCapacity 6 295 #else 296 #define JSNonFinalObject_inlineStorageCapacity 2 297 #define JSFinalObject_inlineStorageCapacity 4 298 #endif 299 300 COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineStorageCapacity), final_storage_is_at_least_as_large_as_non_final); 301 302 // JSNonFinalObject is a type of JSObject that has some internal storage, 303 // but also preserves some space in the collector cell for additional 304 // data members in derived types. 305 class JSNonFinalObject : public JSObject { 306 friend class JSObject; 307 308 public: 309 explicit JSNonFinalObject(NonNullPassRefPtr<Structure> structure) 310 : JSObject(structure, m_inlineStorage) 311 { 312 ASSERT(OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage) % sizeof(double) == 0); 313 } 314 315 static PassRefPtr<Structure> createStructure(JSValue prototype) 316 { 317 return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 318 } 319 320 private: 321 WriteBarrierBase<Unknown> m_inlineStorage[JSNonFinalObject_inlineStorageCapacity]; 322 }; 323 324 // JSFinalObject is a type of JSObject that contains sufficent internal 325 // storage to fully make use of the colloctor cell containing it. 326 class JSFinalObject : public JSObject { 327 friend class JSObject; 328 329 public: 330 static JSFinalObject* create(ExecState* exec, NonNullPassRefPtr<Structure> structure) 331 { 332 return new (exec) JSFinalObject(structure); 333 } 334 335 static PassRefPtr<Structure> createStructure(JSValue prototype) 336 { 337 return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 338 } 339 340 private: 341 explicit JSFinalObject(NonNullPassRefPtr<Structure> structure) 342 : JSObject(structure, m_inlineStorage) 343 { 344 ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double) == 0); 345 } 346 347 static const unsigned StructureFlags = JSObject::StructureFlags | IsJSFinalObject; 348 349 WriteBarrierBase<Unknown> m_inlineStorage[JSFinalObject_inlineStorageCapacity]; 350 }; 351 352 inline size_t JSObject::offsetOfInlineStorage() 353 { 354 ASSERT(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) == OBJECT_OFFSETOF(JSNonFinalObject, m_inlineStorage)); 355 return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage); 356 } 357 358 inline JSObject* constructEmptyObject(ExecState* exec, NonNullPassRefPtr<Structure> structure) 359 { 360 return JSFinalObject::create(exec, structure); 361 } 362 363 inline PassRefPtr<Structure> createEmptyObjectStructure(JSValue prototype) 364 { 365 return JSFinalObject::createStructure(prototype); 366 } 367 298 368 inline JSObject* asObject(JSCell* cell) 299 369 { … … 307 377 } 308 378 309 inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure )379 inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure, PropertyStorage inlineStorage) 310 380 : JSCell(structure.releaseRef()) // ~JSObject balances this ref() 311 { 312 ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity); 381 , m_propertyStorage(inlineStorage) 382 { 383 ASSERT(m_structure->propertyStorageCapacity() < baseExternalStorageCapacity); 313 384 ASSERT(m_structure->isEmpty()); 314 385 ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype())); 315 ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0);316 386 } 317 387 … … 320 390 ASSERT(m_structure); 321 391 if (!isUsingInlineStorage()) 322 delete [] m_ externalStorage;392 delete [] m_propertyStorage; 323 393 m_structure->deref(); 324 394 } … … 364 434 inline bool Structure::isUsingInlineStorage() const 365 435 { 366 return (propertyStorageCapacity() == JSObject::inlineStorageCapacity);436 return propertyStorageCapacity() < JSObject::baseExternalStorageCapacity; 367 437 } 368 438 … … 728 798 } 729 799 730 ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize)731 {732 ASSERT(newSize > oldSize);733 734 // It's important that this function not rely on m_structure, since735 // we might be in the middle of a transition.736 bool wasInline = (oldSize == JSObject::inlineStorageCapacity);737 738 PropertyStorage oldPropertyStorage = (wasInline ? m_inlineStorage : m_externalStorage);739 PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];740 741 for (unsigned i = 0; i < oldSize; ++i)742 newPropertyStorage[i] = oldPropertyStorage[i];743 744 if (!wasInline)745 delete [] oldPropertyStorage;746 747 m_externalStorage = newPropertyStorage;748 }749 750 800 ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) 751 801 {
Note:
See TracChangeset
for help on using the changeset viewer.