Changeset 48068 in webkit for trunk/JavaScriptCore
- Timestamp:
- Sep 4, 2009, 12:03:33 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r48067 r48068 1 2009-09-04 Darin Adler <[email protected]> 2 3 Reviewed by Geoff Garen. 4 5 DateInstance object collected on ARM JIT (JSValue: WTF_USE_JSVALUE32) 6 https://bugs.webkit.org/show_bug.cgi?id=28909 7 8 Part two. 9 10 Make some improvements to garbage collection code: 11 12 1) Create a runtime assertion that catches any classes that 13 override markChildren but have the HasDefaultMark bit set. 14 2) Remove checks of the mark bit outside the MarkStack::append 15 function; they are redundant. 16 3) Improve the efficiency of the asObject and asArray functions 17 when called on JSCell* to avoid a round trip to JSValue. 18 4) Make more callers use the checked asCell and asObject 19 casting functions rather than unchecked casts. 20 5) Removed the JSCell::marked function and other GC-related 21 functions because these operations are no longer things that 22 code other than the core GC code needs to do directly. Fixed 23 callers that were calling them. 24 25 * runtime/Collector.cpp: 26 (JSC::Heap::markConservatively): Removed unneeded call to MarkStack::drain. 27 (JSC::Heap::markProtectedObjects): Removed unneeded check of the mark 28 bit and call to MarkStack::drain. 29 (JSC::Heap::collect): Removed unneeded checks of the mark bit and also 30 changed call to SmallStrings::mark to call markChildren instead to match 31 the rest of the objects. 32 (JSC::typeName): Removed unneeded cast to JSObject*. 33 34 * runtime/JSArray.h: 35 (JSC::asArray): Added an overload for JSCell* and changed the JSValue 36 version to call it. Removed some unneeded casts. 37 (JSC::JSArray::markChildrenDirect): Marked this function inline. It's in 38 a header, and if not marked inline this could lead to linking problems. 39 (JSC::MarkStack::markChildren): Added. This helper function is used by 40 the drain function to avoid repating code. Also added the code here to 41 check fro default mark violations in debug code. If a markChildren 42 function adds something to the mark stack, but the type info claimed 43 hasDefaultMark was true, then we will get an assertion now. Also fixed 44 the assertion about the mark bit to use the Heap function directly 45 because we don't have a JSCell::marked function any more. 46 (JSC::MarkStack::drain): Changed a local variable from "v" to "value", 47 and from "currentCell" to "cell". Changed to call markChildren in two 48 places instead of repeating a chain of if statements twice. Changed 49 code that reads and writes the mark bit to use Heap::isCellMarked and 50 Heap::markCell so we can eliminate the JSCell::marked and 51 JSCell::markCellDirect functions. 52 53 * runtime/JSCell.h: Removed JSCell's markCellDirect and marked member 54 functions. Added a comment explaining that asCell should be deprecated 55 in favor of the JSValue asCell member function. 56 (JSC::MarkStack::append): Added the assertion that catches callers 57 that have set the HasDefaultMark bit incorrectly. Changed 58 code that reads and writes the mark bit to use Heap::isCellMarked and 59 Heap::markCell so we can eliminate the JSCell::marked and 60 JSCell::markCellDirect functions. Moved the overload of 61 MarkStack::append for JSValue here so it can call through to the cell 62 version. The old version had a copy of all the code instead, but that 63 repeated the conversion from JSValue to JSCell* and the check for 64 whether a value is a cell multiple times. 65 (JSC::Structure::markAggregate): Moved this function here to avoid 66 dependencies for Structure.h, since this calls MarkStack::append. 67 68 * runtime/JSObject.cpp: 69 (JSC::JSObject::markChildren): Added code to clear 70 m_isCheckingForDefaultMarkViolation so the marking done by JSObject 71 doesn't trigger the assertion. 72 73 * runtime/JSValue.h: Moved some stray includes that were outside the 74 header guard inside it. Not sure how that happened! Removed the 75 GC-related member functions markChildren, hasChildren, marked, and 76 markDirect. 77 78 * runtime/JSWrapperObject.h: Made markChildren private. 79 (JSC::JSWrapperObject::createStructure): Added. Fixes a bug where the 80 HasDefaultMark bit was set. 81 82 * runtime/MarkStack.h: Added m_isCheckingForDefaultMarkViolation and 83 initialized it to false. Moved the append function body from here to 84 JSCell.h. Added a declaration of a private markChildren function used 85 inside the drain function. 86 87 * runtime/SmallStrings.cpp: 88 (JSC::SmallStrings::markChildren): Changed the name and style of this 89 function to match other functions. This allows us to share the normal 90 mark stack code path. 91 92 * runtime/SmallStrings.h: Changed the name and interface of mark to 93 the more-normal markChildren style. 94 95 * runtime/Structure.h: Moved the body of markAggregate into the 96 JSCell.h to avoid a circular dependency with JSCell.h. 97 1 98 2009-09-04 Darin Adler <[email protected]> 2 99 … … 47 144 version to call it. 48 145 (JSC::JSValue::get): Use asObject to avoid a direct static_cast. 49 50 * runtime/JSValue.h: Moved some stray includes that were outside the51 header guard inside it. Not sure how that happened! Removed the52 GC-related member functions markChildren, hasChildren, marked, and53 markDirect.54 146 55 147 * runtime/JSWrapperObject.h: Made markChildren private. -
trunk/JavaScriptCore/runtime/Collector.cpp
r47842 r48068 748 748 for (size_t block = 0; block < usedPrimaryBlocks; block++) { 749 749 if ((primaryBlocks[block] == blockAddr) & (offset <= lastCellOffset)) { 750 if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree != 0) {750 if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree) { 751 751 markStack.append(reinterpret_cast<JSCell*>(xAsBits)); 752 752 markStack.drain(); … … 1012 1012 ProtectCountSet::iterator end = m_protectedValues.end(); 1013 1013 for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) { 1014 JSCell* val = it->first; 1015 if (!val->marked()) { 1016 markStack.append(val); 1017 markStack.drain(); 1018 } 1014 markStack.append(it->first); 1015 markStack.drain(); 1019 1016 } 1020 1017 … … 1148 1145 if (m_markListSet && m_markListSet->size()) 1149 1146 MarkedArgumentBuffer::markLists(markStack, *m_markListSet); 1150 if (m_globalData->exception && !m_globalData->exception.marked())1147 if (m_globalData->exception) 1151 1148 markStack.append(m_globalData->exception); 1152 1149 m_globalData->interpreter->registerFile().markCallFrames(markStack, this); 1153 m_globalData->smallStrings.mark ();1150 m_globalData->smallStrings.markChildren(markStack); 1154 1151 if (m_globalData->functionCodeBlockBeingReparsed) 1155 1152 m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack); … … 1255 1252 return "gettersetter"; 1256 1253 ASSERT(cell->isObject()); 1257 const ClassInfo* info = static_cast<JSObject*>(cell)->classInfo();1254 const ClassInfo* info = cell->classInfo(); 1258 1255 return info ? info->className : "Object"; 1259 1256 } -
trunk/JavaScriptCore/runtime/JSArray.h
r47812 r48068 122 122 JSArray* constructArray(ExecState*, const ArgList& values); 123 123 124 inline JSArray* asArray(JSCell* cell) 125 { 126 ASSERT(cell->inherits(&JSArray::info)); 127 return static_cast<JSArray*>(cell); 128 } 129 124 130 inline JSArray* asArray(JSValue value) 125 131 { 126 ASSERT(asObject(value)->inherits(&JSArray::info)); 127 return static_cast<JSArray*>(asObject(value)); 128 } 129 130 inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; } 132 return asArray(value.asCell()); 133 } 134 135 inline bool isJSArray(JSGlobalData* globalData, JSValue v) 136 { 137 return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; 138 } 131 139 inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; } 132 140 133 void JSArray::markChildrenDirect(MarkStack& markStack) { 141 inline void JSArray::markChildrenDirect(MarkStack& markStack) 142 { 134 143 JSObject::markChildrenDirect(markStack); 135 144 136 145 ArrayStorage* storage = m_storage; 137 146 138 147 unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength); 139 148 markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); 140 149 141 150 if (SparseArrayValueMap* map = storage->m_sparseValueMap) { 142 151 SparseArrayValueMap::iterator end = map->end(); … … 144 153 markStack.append(it->second); 145 154 } 155 } 156 157 inline void MarkStack::markChildren(JSCell* cell) 158 { 159 ASSERT(Heap::isCellMarked(cell)); 160 if (cell->structure()->typeInfo().hasDefaultMark()) { 161 #ifdef NDEBUG 162 asObject(cell)->markChildrenDirect(*this); 163 #else 164 ASSERT(!m_isCheckingForDefaultMarkViolation); 165 m_isCheckingForDefaultMarkViolation = true; 166 cell->markChildren(*this); 167 ASSERT(m_isCheckingForDefaultMarkViolation); 168 m_isCheckingForDefaultMarkViolation = false; 169 #endif 170 return; 171 } 172 if (cell->vptr() == m_jsArrayVPtr) { 173 asArray(cell)->markChildrenDirect(*this); 174 return; 175 } 176 cell->markChildren(*this); 146 177 } 147 178 … … 158 189 findNextUnmarkedNullValue: 159 190 ASSERT(current.m_values != end); 160 JSValue v = *current.m_values;191 JSValue value = *current.m_values; 161 192 current.m_values++; 162 163 if (!v || v.marked()) { 193 194 JSCell* cell; 195 if (!value || !value.isCell() || Heap::isCellMarked(cell = value.asCell())) { 164 196 if (current.m_values == end) { 165 197 m_markSets.removeLast(); … … 168 200 goto findNextUnmarkedNullValue; 169 201 } 170 171 JSCell* currentCell = v.asCell(); 172 currentCell->markCellDirect(); 173 if (currentCell->structure()->typeInfo().type() < CompoundType) { 202 203 Heap::markCell(cell); 204 if (cell->structure()->typeInfo().type() < CompoundType) { 174 205 if (current.m_values == end) { 175 206 m_markSets.removeLast(); … … 178 209 goto findNextUnmarkedNullValue; 179 210 } 180 211 181 212 if (current.m_values == end) 182 213 m_markSets.removeLast(); 183 214 184 if (currentCell->structure()->typeInfo().hasDefaultMark()) 185 static_cast<JSObject*>(currentCell)->markChildrenDirect(*this); 186 else if (currentCell->vptr() == m_jsArrayVPtr) 187 static_cast<JSArray*>(currentCell)->markChildrenDirect(*this); 188 else 189 currentCell->markChildren(*this); 215 markChildren(cell); 190 216 } 191 while (!m_values.isEmpty()) { 192 JSCell* current = m_values.removeLast(); 193 ASSERT(current->marked()); 194 if (current->structure()->typeInfo().hasDefaultMark()) 195 static_cast<JSObject*>(current)->markChildrenDirect(*this); 196 else if (current->vptr() == m_jsArrayVPtr) 197 static_cast<JSArray*>(current)->markChildrenDirect(*this); 198 else 199 current->markChildren(*this); 200 } 217 while (!m_values.isEmpty()) 218 markChildren(m_values.removeLast()); 201 219 } 202 220 } -
trunk/JavaScriptCore/runtime/JSCell.h
r47799 r48068 24 24 #define JSCell_h 25 25 26 #include "Collector.h" 27 #include "JSImmediate.h" 28 #include "JSValue.h" 29 #include "MarkStack.h" 30 #include "Structure.h" 26 31 #include <wtf/Noncopyable.h> 27 #include "Structure.h"28 #include "JSValue.h"29 #include "JSImmediate.h"30 #include "Collector.h"31 32 32 33 namespace JSC { … … 88 89 void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; } 89 90 90 void markCellDirect();91 91 virtual void markChildren(MarkStack&); 92 bool marked() const;93 92 94 93 // Object operations, with the toObject operation included. … … 114 113 }; 115 114 115 // FIXME: We should deprecate this and just use JSValue::asCell() instead. 116 116 JSCell* asCell(JSValue); 117 117 … … 157 157 } 158 158 159 inline bool JSCell::marked() const160 {161 return Heap::isCellMarked(this);162 }163 164 inline void JSCell::markCellDirect()165 {166 Heap::markCell(this);167 }168 169 159 inline void JSCell::markChildren(MarkStack&) 170 160 { 171 ASSERT(marked());172 161 } 173 162 … … 236 225 } 237 226 return false; 238 }239 240 inline void JSValue::markDirect()241 {242 ASSERT(!marked());243 asCell()->markCellDirect();244 }245 246 inline void JSValue::markChildren(MarkStack& markStack)247 {248 ASSERT(marked());249 asCell()->markChildren(markStack);250 }251 252 inline bool JSValue::marked() const253 {254 return !isCell() || asCell()->marked();255 227 } 256 228 … … 342 314 return JSValue(); 343 315 } 344 345 inline bool JSValue::hasChildren() const346 {347 return asCell()->structure()->typeInfo().type() >= CompoundType;348 }349 350 316 351 317 inline JSObject* JSValue::toObject(ExecState* exec) const … … 361 327 ALWAYS_INLINE void MarkStack::append(JSCell* cell) 362 328 { 329 ASSERT(!m_isCheckingForDefaultMarkViolation); 363 330 ASSERT(cell); 364 if ( cell->marked())331 if (Heap::isCellMarked(cell)) 365 332 return; 366 cell->markCellDirect();333 Heap::markCell(cell); 367 334 if (cell->structure()->typeInfo().type() >= CompoundType) 368 335 m_values.append(cell); 336 } 337 338 ALWAYS_INLINE void MarkStack::append(JSValue value) 339 { 340 ASSERT(value); 341 if (value.isCell()) 342 append(value.asCell()); 343 } 344 345 inline void Structure::markAggregate(MarkStack& markStack) 346 { 347 markStack.append(m_prototype); 369 348 } 370 349 -
trunk/JavaScriptCore/runtime/JSObject.cpp
r47780 r48068 39 39 #include <wtf/Assertions.h> 40 40 41 42 41 namespace JSC { 43 42 … … 46 45 void JSObject::markChildren(MarkStack& markStack) 47 46 { 47 #ifndef NDEBUG 48 bool wasCheckingForDefaultMarkViolation = markStack.m_isCheckingForDefaultMarkViolation; 49 markStack.m_isCheckingForDefaultMarkViolation = false; 50 #endif 51 48 52 markChildrenDirect(markStack); 53 54 #ifndef NDEBUG 55 markStack.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; 56 #endif 49 57 } 50 58 -
trunk/JavaScriptCore/runtime/JSValue.h
r47288 r48068 21 21 */ 22 22 23 #include <stddef.h> // for size_t24 #include <stdint.h>25 26 23 #ifndef JSValue_h 27 24 #define JSValue_h … … 30 27 #include "ConstructData.h" 31 28 #include <math.h> 29 #include <stddef.h> // for size_t 30 #include <stdint.h> 32 31 #include <wtf/AlwaysInline.h> 33 32 #include <wtf/Assertions.h> … … 43 42 class JSObject; 44 43 class JSString; 45 class MarkStack;46 44 class PropertySlot; 47 45 class PutPropertySlot; … … 172 170 // signle precision float is not a representation used in JS or JSC). 173 171 float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); } 174 175 // Garbage collection.176 void markChildren(MarkStack&);177 bool hasChildren() const;178 bool marked() const;179 void markDirect();180 172 181 173 // Object operations, with the toObject operation included. -
trunk/JavaScriptCore/runtime/MarkStack.h
r47267 r48068 28 28 29 29 #include "JSValue.h" 30 31 30 #include <wtf/Noncopyable.h> 32 31 33 32 namespace JSC { 33 34 34 class JSGlobalData; 35 35 class Register; … … 41 41 MarkStack(void* jsArrayVPtr) 42 42 : m_jsArrayVPtr(jsArrayVPtr) 43 #ifndef NDEBUG 44 , m_isCheckingForDefaultMarkViolation(false) 45 #endif 43 46 { 44 47 } 45 48 46 ALWAYS_INLINE void append(JSValue value) 47 { 48 ASSERT(value); 49 if (value.marked()) 50 return; 51 value.markDirect(); 52 if (value.hasChildren()) 53 m_values.append(value.asCell()); 54 } 55 56 ALWAYS_INLINE void append(JSCell* cell); 49 ALWAYS_INLINE void append(JSValue); 50 ALWAYS_INLINE void append(JSCell*); 57 51 58 52 ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) … … 77 71 78 72 private: 73 void markChildren(JSCell*); 74 79 75 struct MarkSet { 80 76 MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties) … … 181 177 MarkStackArray<JSCell*> m_values; 182 178 static size_t s_pageSize; 179 180 #ifndef NDEBUG 181 public: 182 bool m_isCheckingForDefaultMarkViolation; 183 #endif 183 184 }; 184 185 } -
trunk/JavaScriptCore/runtime/SmallStrings.cpp
r47022 r48068 83 83 } 84 84 85 void SmallStrings::mark ()85 void SmallStrings::markChildren(MarkStack& markStack) 86 86 { 87 if (m_emptyString && !m_emptyString->marked())88 m _emptyString->markCellDirect();87 if (m_emptyString) 88 markStack.append(m_emptyString); 89 89 for (unsigned i = 0; i < numCharactersToStore; ++i) { 90 if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())91 m _singleCharacterStrings[i]->markCellDirect();90 if (m_singleCharacterStrings[i]) 91 markStack.append(m_singleCharacterStrings[i]); 92 92 } 93 93 } -
trunk/JavaScriptCore/runtime/SmallStrings.h
r45891 r48068 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.2 * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 34 34 class JSGlobalData; 35 35 class JSString; 36 36 class MarkStack; 37 37 class SmallStringsStorage; 38 38 … … 57 57 UString::Rep* singleCharacterStringRep(unsigned char character); 58 58 59 void mark ();59 void markChildren(MarkStack&); 60 60 61 61 unsigned count() const; -
trunk/JavaScriptCore/runtime/Structure.h
r47605 r48068 30 30 #include "JSType.h" 31 31 #include "JSValue.h" 32 #include "MarkStack.h"33 32 #include "PropertyMapHashTable.h" 34 33 #include "StructureChain.h" … … 47 46 namespace JSC { 48 47 48 class MarkStack; 49 49 class PropertyNameArray; 50 50 class PropertyNameArrayData; … … 74 74 ~Structure(); 75 75 76 void markAggregate(MarkStack& markStack) 77 { 78 markStack.append(m_prototype); 79 } 76 void markAggregate(MarkStack&); 80 77 81 78 // These should be used with caution.
Note:
See TracChangeset
for help on using the changeset viewer.