Changeset 211102 in webkit
- Timestamp:
- Jan 24, 2017, 1:22:42 PM (10 years ago)
- Location:
- branches/safari-603-branch/Source/JavaScriptCore
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
runtime/Butterfly.h (modified) (1 diff)
-
runtime/ButterflyInlines.h (modified) (1 diff)
-
runtime/IntlObject.cpp (modified) (3 diffs)
-
runtime/JSArray.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-603-branch/Source/JavaScriptCore/ChangeLog
r211099 r211102 1 2017-01-24 Matthew Hanson <matthew_hanson@apple.com> 2 3 Merge r211043. rdar://problem/30134434 4 5 2017-01-23 Michael Saboff <msaboff@apple.com> 6 7 IntlObject uses JSArray::tryCreateUninitialized in an unsafe way 8 https://bugs.webkit.org/show_bug.cgi?id=167288 9 10 Reviewed by Filip Pizlo. 11 12 Refactored the following "create" methods into a "tryCreate" method and a 13 "create" wrapper: JSArray::create(), Butterfly::create() and 14 createArrayButterfly(). 15 16 Changed IntlObject.cpp to use JSArray::tryCreate() as it is simpler to use 17 by not requiring the caller to be GC savey. The performance benefits of 18 tryCreateUninitialized() are not needed by the IntlObject c++ code. 19 20 Did not add a new test as the bug caused LayoutTests/js/intl.html to fail 21 reliably with the JSC option values scribbleFreeCells=true, 22 collectContinuously=true and JSC_useGenerationalGC=false. 23 24 * runtime/Butterfly.h: 25 * runtime/ButterflyInlines.h: 26 (JSC::Butterfly::tryCreate): Added. 27 (JSC::Butterfly::create): 28 * runtime/IntlObject.cpp: 29 (JSC::canonicalizeLocaleList): 30 (JSC::lookupSupportedLocales): 31 (JSC::intlObjectFuncGetCanonicalLocales): 32 * runtime/JSArray.h: 33 (JSC::createContiguousArrayButterfly): Deleted. 34 (JSC::tryCreateArrayButterfly): Added. 35 (JSC::createArrayButterfly): 36 (JSC::JSArray::tryCreate): Added. 37 (JSC::JSArray::create): 38 1 39 2017-01-24 Matthew Hanson <matthew_hanson@apple.com> 2 40 -
branches/safari-603-branch/Source/JavaScriptCore/runtime/Butterfly.h
r206525 r211102 112 112 static Butterfly* createUninitialized(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); 113 113 114 static Butterfly* tryCreate(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes); 114 115 static Butterfly* create(VM&, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes); 115 116 static Butterfly* create(VM&, JSCell* intendedOwner, Structure*); -
branches/safari-603-branch/Source/JavaScriptCore/runtime/ButterflyInlines.h
r210868 r211102 68 68 } 69 69 70 inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) 71 { 72 Butterfly* result = createUninitialized( 73 vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, 74 indexingPayloadSizeInBytes); 70 inline Butterfly* Butterfly::tryCreate(VM& vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) 71 { 72 size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); 73 void* base = vm.auxiliarySpace.tryAllocate(size); 74 if (!base) 75 return nullptr; 76 Butterfly* result = fromBase(base, preCapacity, propertyCapacity); 75 77 if (hasIndexingHeader) 76 78 *result->indexingHeader() = indexingHeader; 77 79 memset(result->propertyStorage() - propertyCapacity, 0, propertyCapacity * sizeof(EncodedJSValue)); 80 return result; 81 } 82 83 inline Butterfly* Butterfly::create(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes) 84 { 85 Butterfly* result = tryCreate(vm, intendedOwner, preCapacity, propertyCapacity, hasIndexingHeader, indexingHeader, indexingPayloadSizeInBytes); 86 87 RELEASE_ASSERT(result); 78 88 return result; 79 89 } -
branches/safari-603-branch/Source/JavaScriptCore/runtime/IntlObject.cpp
r209229 r211102 549 549 if (locales.isString()) { 550 550 // a. Let aLocales be CreateArrayFromList(«locales»). 551 JSArray* localesArray = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 1); 551 JSArray* localesArray = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 1); 552 if (!localesArray) { 553 throwOutOfMemoryError(&state, scope); 554 RETURN_IF_EXCEPTION(scope, Vector<String>()); 555 } 556 552 557 localesArray->initializeIndex(vm, 0, locales); 553 558 // 4. Let O be ToObject(aLocales). … … 888 893 // 3. Let subset be an empty List. 889 894 JSGlobalObject* globalObject = state.jsCallee()->globalObject(); 890 JSArray* subset = JSArray::tryCreate Uninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0);895 JSArray* subset = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0); 891 896 if (!subset) { 892 897 throwOutOfMemoryError(&state, scope); … … 1032 1037 // 2. Return CreateArrayFromList(ll). 1033 1038 JSGlobalObject* globalObject = state->jsCallee()->globalObject(); 1034 JSArray* localeArray = JSArray::tryCreate Uninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), localeList.size());1039 JSArray* localeArray = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), localeList.size()); 1035 1040 if (!localeArray) { 1036 1041 throwOutOfMemoryError(state, scope); -
branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArray.h
r210659 r211102 53 53 54 54 public: 55 static JSArray* tryCreate(VM&, Structure*, unsigned initialLength = 0); 55 56 static JSArray* create(VM&, Structure*, unsigned initialLength = 0); 56 57 static JSArray* createWithButterfly(VM&, GCDeferralContext*, Structure*, Butterfly*); 57 58 58 59 // tryCreateUninitialized is used for fast construction of arrays whose size and 59 // contents are known at time of creation. Clients of this interface must: 60 // contents are known at time of creation. This should be considered a private API. 61 // Clients of this interface must: 60 62 // - null-check the result (indicating out of memory, or otherwise unable to allocate vector). 61 63 // - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength. 64 // - Provide a valid GCDefferalContext* if they might garbage collect when initializing properties, 65 // otherwise the caller can provide a null GCDefferalContext*. 66 // 62 67 JS_EXPORT_PRIVATE static JSArray* tryCreateUninitialized(VM&, GCDeferralContext*, Structure*, unsigned initialLength); 63 68 static JSArray* tryCreateUninitialized(VM& vm, Structure* structure, unsigned initialLength) … … 184 189 }; 185 190 186 inline Butterfly* createContiguousArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned length, unsigned& vectorLength) 187 { 188 IndexingHeader header; 189 vectorLength = Butterfly::optimalContiguousVectorLength( 190 intendedOwner ? intendedOwner->structure(vm) : 0, length); 191 header.setVectorLength(vectorLength); 192 header.setPublicLength(length); 193 Butterfly* result = Butterfly::create( 194 vm, intendedOwner, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue)); 195 return result; 196 } 197 198 inline Butterfly* createArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength) 199 { 200 Butterfly* butterfly = Butterfly::create( 191 inline Butterfly* tryCreateArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength) 192 { 193 Butterfly* butterfly = Butterfly::tryCreate( 201 194 vm, intendedOwner, 0, 0, true, baseIndexingHeaderForArrayStorage(initialLength), 202 195 ArrayStorage::sizeFor(BASE_ARRAY_STORAGE_VECTOR_LEN)); 196 if (!butterfly) 197 return nullptr; 203 198 ArrayStorage* storage = butterfly->arrayStorage(); 204 199 storage->m_sparseMap.clear(); … … 208 203 } 209 204 205 inline Butterfly* createArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength) 206 { 207 Butterfly* result = tryCreateArrayButterfly(vm, intendedOwner, initialLength); 208 RELEASE_ASSERT(result); 209 return result; 210 } 211 210 212 Butterfly* createArrayButterflyInDictionaryIndexingMode( 211 213 VM&, JSCell* intendedOwner, unsigned initialLength); 212 214 213 inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLength) 214 { 215 inline JSArray* JSArray::tryCreate(VM& vm, Structure* structure, unsigned initialLength) 216 { 217 unsigned outOfLineStorage = structure->outOfLineCapacity(); 218 215 219 Butterfly* butterfly; 216 if (LIKELY(!hasAnyArrayStorage(structure->indexingType()))) { 220 IndexingType indexingType = structure->indexingType(); 221 if (LIKELY(!hasAnyArrayStorage(indexingType))) { 217 222 ASSERT( 218 hasUndecided(structure->indexingType()) 219 || hasInt32(structure->indexingType()) 220 || hasDouble(structure->indexingType()) 221 || hasContiguous(structure->indexingType())); 222 unsigned vectorLength; 223 butterfly = createContiguousArrayButterfly(vm, 0, initialLength, vectorLength); 224 if (hasDouble(structure->indexingType())) 223 hasUndecided(indexingType) 224 || hasInt32(indexingType) 225 || hasDouble(indexingType) 226 || hasContiguous(indexingType)); 227 228 if (initialLength > MAX_STORAGE_VECTOR_LENGTH) 229 return 0; 230 231 unsigned vectorLength = Butterfly::optimalContiguousVectorLength(structure, initialLength); 232 void* temp = vm.auxiliarySpace.tryAllocate(nullptr, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue))); 233 if (!temp) 234 return nullptr; 235 butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage); 236 butterfly->setVectorLength(vectorLength); 237 butterfly->setPublicLength(initialLength); 238 if (hasDouble(indexingType)) 225 239 clearArray(butterfly->contiguousDouble().data(), vectorLength); 226 240 else … … 228 242 } else { 229 243 ASSERT( 230 structure->indexingType() == ArrayWithSlowPutArrayStorage 231 || structure->indexingType() == ArrayWithArrayStorage); 232 butterfly = createArrayButterfly(vm, 0, initialLength); 244 indexingType == ArrayWithSlowPutArrayStorage 245 || indexingType == ArrayWithArrayStorage); 246 butterfly = tryCreateArrayButterfly(vm, 0, initialLength); 247 if (!butterfly) 248 return nullptr; 233 249 for (unsigned i = 0; i < BASE_ARRAY_STORAGE_VECTOR_LEN; ++i) 234 250 butterfly->arrayStorage()->m_vector[i].clear(); … … 236 252 237 253 return createWithButterfly(vm, nullptr, structure, butterfly); 254 } 255 256 inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLength) 257 { 258 JSArray* result = JSArray::tryCreate(vm, structure, initialLength); 259 RELEASE_ASSERT(result); 260 261 return result; 238 262 } 239 263
Note:
See TracChangeset
for help on using the changeset viewer.