Changeset 132745 in webkit for trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
- Timestamp:
- Oct 27, 2012, 11:13:23 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
r132162 r132745 33 33 namespace JSC { namespace DFG { 34 34 35 Array ::ModefromObserved(ArrayProfile* profile, Array::Action action, bool makeSafe)35 ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, bool makeSafe) 36 36 { 37 37 switch (profile->observedArrayModes()) { 38 38 case 0: 39 return Array ::Unprofiled;39 return ArrayMode(Array::Unprofiled); 40 40 case asArrayModes(NonArray): 41 41 if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) 42 return Array ::ToContiguous; // FIXME: we don't know whether to go to contiguous or array storage. We're making a static guess here. In future we should use exit profiling for this.43 return Array ::SelectUsingPredictions;42 return ArrayMode(Array::Contiguous, Array::NonArray, Array::OutOfBounds, Array::Convert); // FIXME: we don't know whether to go to contiguous or array storage. We're making a static guess here. In future we should use exit profiling for this. 43 return ArrayMode(Array::SelectUsingPredictions); 44 44 case asArrayModes(NonArrayWithContiguous): 45 return makeSafe ? Array::ContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::ContiguousToTail : Array::Contiguous);45 return ArrayMode(Array::Contiguous, Array::NonArray, Array::AsIs).withSpeculation(profile, makeSafe); 46 46 case asArrayModes(ArrayWithContiguous): 47 return makeSafe ? Array::ArrayWithContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::ArrayWithContiguousToTail : Array::ArrayWithContiguous);47 return ArrayMode(Array::Contiguous, Array::Array, Array::AsIs).withSpeculation(profile, makeSafe); 48 48 case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous): 49 return makeSafe ? Array::PossiblyArrayWithContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::PossiblyArrayWithContiguousToTail : Array::PossiblyArrayWithContiguous);49 return ArrayMode(Array::Contiguous, Array::PossiblyArray, Array::AsIs).withSpeculation(profile, makeSafe); 50 50 case asArrayModes(NonArrayWithArrayStorage): 51 return makeSafe ? Array::ArrayStorageOutOfBounds : (profile->mayStoreToHole() ? Array::ArrayStorageToHole : Array::ArrayStorage);51 return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::AsIs).withSpeculation(profile, makeSafe); 52 52 case asArrayModes(NonArrayWithSlowPutArrayStorage): 53 53 case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage): 54 return Array ::SlowPutArrayStorage;54 return ArrayMode(Array::SlowPutArrayStorage, Array::NonArray, Array::AsIs).withSpeculation(profile, makeSafe); 55 55 case asArrayModes(ArrayWithArrayStorage): 56 return makeSafe ? Array::ArrayWithArrayStorageOutOfBounds : (profile->mayStoreToHole() ? Array::ArrayWithArrayStorageToHole : Array::ArrayWithArrayStorage);56 return ArrayMode(Array::ArrayStorage, Array::Array, Array::AsIs).withSpeculation(profile, makeSafe); 57 57 case asArrayModes(ArrayWithSlowPutArrayStorage): 58 58 case asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): 59 return Array ::ArrayWithSlowPutArrayStorage;59 return ArrayMode(Array::SlowPutArrayStorage, Array::Array, Array::AsIs).withSpeculation(profile, makeSafe); 60 60 case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage): 61 return makeSafe ? Array::PossiblyArrayWithArrayStorageOutOfBounds : (profile->mayStoreToHole() ? Array::PossiblyArrayWithArrayStorageToHole : Array::PossiblyArrayWithArrayStorage);61 return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::AsIs).withSpeculation(profile, makeSafe); 62 62 case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): 63 63 case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): 64 return Array ::PossiblyArrayWithSlowPutArrayStorage;64 return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs).withSpeculation(profile, makeSafe); 65 65 case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): 66 return Array ::ToArrayStorage;66 return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::Convert).withSpeculation(profile, makeSafe); 67 67 case asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): 68 return Array ::ArrayToArrayStorage;68 return ArrayMode(Array::ArrayStorage, Array::Array, Array::Convert).withSpeculation(profile, makeSafe); 69 69 case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): 70 return Array ::PossiblyArrayToArrayStorage;70 return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::Convert).withSpeculation(profile, makeSafe); 71 71 case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous): 72 72 if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) 73 return Array ::ToContiguous;74 return Array ::SelectUsingPredictions;73 return ArrayMode(Array::Contiguous, Array::NonArray, Array::OutOfBounds, Array::Convert); 74 return ArrayMode(Array::SelectUsingPredictions); 75 75 case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): 76 76 case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage): 77 77 if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) 78 return Array ::ToArrayStorage;79 return Array ::SelectUsingPredictions;78 return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert); 79 return ArrayMode(Array::SelectUsingPredictions); 80 80 case asArrayModes(NonArray) | asArrayModes(NonArrayWithSlowPutArrayStorage): 81 81 case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage): 82 82 if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) 83 return Array ::ToSlowPutArrayStorage;84 return Array ::SelectUsingPredictions;83 return ArrayMode(Array::SlowPutArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert); 84 return ArrayMode(Array::SelectUsingPredictions); 85 85 default: 86 86 // We know that this is possibly a kind of array for which, though there is no … … 88 88 // the value profiles of the inputs. Hence, we leave it as undecided, and let 89 89 // the predictions propagator decide later. 90 return Array ::SelectUsingPredictions;91 } 92 } 93 94 Array ::Mode refineArrayMode(Array::Mode arrayMode, SpeculatedType base, SpeculatedType index)90 return ArrayMode(Array::SelectUsingPredictions); 91 } 92 } 93 94 ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index) const 95 95 { 96 96 if (!base || !index) { … … 99 99 // realized that the callsite could not have possibly executed. It may be worthwhile 100 100 // to fix that, but for now I'm leaving it as-is. 101 return Array ::ForceExit;101 return ArrayMode(Array::ForceExit); 102 102 } 103 103 104 104 if (!isInt32Speculation(index) || !isCellSpeculation(base)) 105 return Array ::Generic;106 107 if ( arrayMode== Array::Unprofiled) {105 return ArrayMode(Array::Generic); 106 107 if (type() == Array::Unprofiled) { 108 108 // If the indexing type wasn't recorded in the array profile but the values are 109 109 // base=cell property=int, then we know that this access didn't execute. 110 return Array ::ForceExit;111 } 112 113 if ( arrayMode!= Array::SelectUsingPredictions)114 return arrayMode;110 return ArrayMode(Array::ForceExit); 111 } 112 113 if (type() != Array::SelectUsingPredictions) 114 return *this; 115 115 116 116 if (isStringSpeculation(base)) 117 return Array ::String;117 return ArrayMode(Array::String); 118 118 119 119 if (isArgumentsSpeculation(base)) 120 return Array ::Arguments;120 return ArrayMode(Array::Arguments); 121 121 122 122 if (isInt8ArraySpeculation(base)) 123 return Array ::Int8Array;123 return ArrayMode(Array::Int8Array); 124 124 125 125 if (isInt16ArraySpeculation(base)) 126 return Array ::Int16Array;126 return ArrayMode(Array::Int16Array); 127 127 128 128 if (isInt32ArraySpeculation(base)) 129 return Array ::Int32Array;129 return ArrayMode(Array::Int32Array); 130 130 131 131 if (isUint8ArraySpeculation(base)) 132 return Array ::Uint8Array;132 return ArrayMode(Array::Uint8Array); 133 133 134 134 if (isUint8ClampedArraySpeculation(base)) 135 return Array ::Uint8ClampedArray;135 return ArrayMode(Array::Uint8ClampedArray); 136 136 137 137 if (isUint16ArraySpeculation(base)) 138 return Array ::Uint16Array;138 return ArrayMode(Array::Uint16Array); 139 139 140 140 if (isUint32ArraySpeculation(base)) 141 return Array ::Uint32Array;141 return ArrayMode(Array::Uint32Array); 142 142 143 143 if (isFloat32ArraySpeculation(base)) 144 return Array ::Float32Array;144 return ArrayMode(Array::Float32Array); 145 145 146 146 if (isFloat64ArraySpeculation(base)) 147 return Array ::Float64Array;148 149 return Array ::Generic;150 } 151 152 bool modeAlreadyChecked(AbstractValue& value, Array::Mode arrayMode)153 { 154 switch ( arrayMode) {147 return ArrayMode(Array::Float64Array); 148 149 return ArrayMode(Array::Generic); 150 } 151 152 bool ArrayMode::alreadyChecked(AbstractValue& value) const 153 { 154 switch (type()) { 155 155 case Array::Generic: 156 156 return true; … … 163 163 164 164 case Array::Contiguous: 165 case Array::ContiguousToTail: 166 case Array::ContiguousOutOfBounds: 167 case Array::PossiblyArrayWithContiguous: 168 case Array::PossiblyArrayWithContiguousToTail: 169 case Array::PossiblyArrayWithContiguousOutOfBounds: 170 case Array::ToContiguous: 165 if (arrayClass() == Array::Array) { 166 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithContiguous))) 167 return true; 168 return value.m_currentKnownStructure.hasSingleton() 169 && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()) 170 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); 171 } 171 172 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous))) 172 173 return true; … … 174 175 && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()); 175 176 176 case Array::ArrayWithContiguous:177 case Array::ArrayWithContiguousToTail:178 case Array::ArrayWithContiguousOutOfBounds:179 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithContiguous)))180 return true;181 return value.m_currentKnownStructure.hasSingleton()182 && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType())183 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);184 185 177 case Array::ArrayStorage: 186 case Array::ArrayStorageToHole:187 case Array::ArrayStorageOutOfBounds:188 case Array::PossiblyArrayWithArrayStorage:189 case Array::PossiblyArrayWithArrayStorageToHole:190 case Array::PossiblyArrayWithArrayStorageOutOfBounds:191 case Array::ToArrayStorage:192 case Array::PossiblyArrayToArrayStorage:178 if (arrayClass() == Array::Array) { 179 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage))) 180 return true; 181 return value.m_currentKnownStructure.hasSingleton() 182 && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) 183 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); 184 } 193 185 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage))) 194 186 return true; … … 197 189 198 190 case Array::SlowPutArrayStorage: 199 case Array::PossiblyArrayWithSlowPutArrayStorage: 200 case Array::ToSlowPutArrayStorage: 191 if (arrayClass() == Array::Array) { 192 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) 193 return true; 194 return value.m_currentKnownStructure.hasSingleton() 195 && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) 196 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); 197 } 201 198 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) 202 199 return true; … … 204 201 && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); 205 202 206 case Array::ArrayWithArrayStorage:207 case Array::ArrayWithArrayStorageToHole:208 case Array::ArrayWithArrayStorageOutOfBounds:209 case Array::ArrayToArrayStorage:210 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage)))211 return true;212 return value.m_currentKnownStructure.hasSingleton()213 && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType())214 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);215 216 case Array::ArrayWithSlowPutArrayStorage:217 if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))218 return true;219 return value.m_currentKnownStructure.hasSingleton()220 && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType())221 && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);222 223 203 case Array::Arguments: 224 204 return isArgumentsSpeculation(value.m_type); … … 256 236 } 257 237 258 ASSERT_NOT_REACHED();238 CRASH(); 259 239 return false; 260 240 } 261 241 262 const char* modeToString(Array::Mode mode)263 { 264 switch ( mode) {242 const char* arrayTypeToString(Array::Type type) 243 { 244 switch (type) { 265 245 case Array::SelectUsingPredictions: 266 246 return "SelectUsingPredictions"; … … 275 255 case Array::Contiguous: 276 256 return "Contiguous"; 277 case Array::ContiguousToTail:278 return "ContiguousToTail";279 case Array::ContiguousOutOfBounds:280 return "ContiguousOutOfBounds";281 case Array::ArrayWithContiguous:282 return "ArrayWithContiguous";283 case Array::ArrayWithContiguousToTail:284 return "ArrayWithContiguousToTail";285 case Array::ArrayWithContiguousOutOfBounds:286 return "ArrayWithContiguousOutOfBounds";287 case Array::PossiblyArrayWithContiguous:288 return "PossiblyArrayWithContiguous";289 case Array::PossiblyArrayWithContiguousToTail:290 return "PossiblyArrayWithContiguousToTail";291 case Array::PossiblyArrayWithContiguousOutOfBounds:292 return "PossiblyArrayWithContiguousOutOfBounds";293 257 case Array::ArrayStorage: 294 258 return "ArrayStorage"; 295 case Array::ArrayStorageToHole:296 return "ArrayStorageToHole";297 259 case Array::SlowPutArrayStorage: 298 260 return "SlowPutArrayStorage"; 299 case Array::ArrayStorageOutOfBounds:300 return "ArrayStorageOutOfBounds";301 case Array::ArrayWithArrayStorage:302 return "ArrayWithArrayStorage";303 case Array::ArrayWithArrayStorageToHole:304 return "ArrayWithArrayStorageToHole";305 case Array::ArrayWithSlowPutArrayStorage:306 return "ArrayWithSlowPutArrayStorage";307 case Array::ArrayWithArrayStorageOutOfBounds:308 return "ArrayWithArrayStorageOutOfBounds";309 case Array::PossiblyArrayWithArrayStorage:310 return "PossiblyArrayWithArrayStorage";311 case Array::PossiblyArrayWithArrayStorageToHole:312 return "PossiblyArrayWithArrayStorageToHole";313 case Array::PossiblyArrayWithSlowPutArrayStorage:314 return "PossiblyArrayWithSlowPutArrayStorage";315 case Array::PossiblyArrayWithArrayStorageOutOfBounds:316 return "PossiblyArrayWithArrayStorageOutOfBounds";317 case Array::ToContiguous:318 return "ToContiguous";319 case Array::ToArrayStorage:320 return "ToArrayStorage";321 case Array::ToSlowPutArrayStorage:322 return "ToSlowPutArrayStorage";323 case Array::ArrayToArrayStorage:324 return "ArrayToArrayStorage";325 case Array::PossiblyArrayToArrayStorage:326 return "PossiblyArrayToArrayStorage";327 261 case Array::Arguments: 328 262 return "Arguments"; … … 354 288 } 355 289 290 const char* arrayClassToString(Array::Class arrayClass) 291 { 292 switch (arrayClass) { 293 case Array::Array: 294 return "Array"; 295 case Array::NonArray: 296 return "NonArray"; 297 case Array::PossiblyArray: 298 return "PossiblyArray"; 299 default: 300 return "Unknown!"; 301 } 302 } 303 304 const char* arraySpeculationToString(Array::Speculation speculation) 305 { 306 switch (speculation) { 307 case Array::InBounds: 308 return "InBounds"; 309 case Array::ToHole: 310 return "ToHole"; 311 case Array::OutOfBounds: 312 return "OutOfBounds"; 313 default: 314 return "Unknown!"; 315 } 316 } 317 318 const char* arrayConversionToString(Array::Conversion conversion) 319 { 320 switch (conversion) { 321 case Array::AsIs: 322 return "AsIs"; 323 case Array::Convert: 324 return "Convert"; 325 default: 326 return "Unknown!"; 327 } 328 } 329 330 const char* ArrayMode::toString() const 331 { 332 static char buffer[256]; 333 snprintf(buffer, sizeof(buffer), "%s%s%s%s", arrayTypeToString(type()), arrayClassToString(arrayClass()), arraySpeculationToString(speculation()), arrayConversionToString(conversion())); 334 return buffer; 335 } 336 356 337 } } // namespace JSC::DFG 357 338
Note:
See TracChangeset
for help on using the changeset viewer.