summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-09 12:15:52 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-09 12:16:06 +0100
commitde4f791e30be4e4239b381c11745ffa4d87ddb8b (patch)
tree885e3a5d6670828b454cf676b4d42f78e28b1f0e /Source/JavaScriptCore/dfg/DFGArrayMode.cpp
parentb022df48697d40cdabdeafb2c29bb14fe489b6fe (diff)
downloadqtwebkit-de4f791e30be4e4239b381c11745ffa4d87ddb8b.tar.gz
Imported WebKit commit e2c32e2f53e02d388e70b9db88b91d8d9d28fc84 (http://svn.webkit.org/repository/webkit/trunk@133952)
Revert back to an older snapshot that should build on ARM
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGArrayMode.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayMode.cpp241
1 files changed, 91 insertions, 150 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
index 0d15b9a30..699902a16 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
@@ -34,46 +34,19 @@ namespace JSC { namespace DFG {
ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, bool makeSafe)
{
- ArrayModes observed = profile->observedArrayModes();
- switch (observed) {
+ switch (profile->observedArrayModes()) {
case 0:
return ArrayMode(Array::Unprofiled);
case asArrayModes(NonArray):
if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return ArrayMode(Array::Undecided, Array::NonArray, Array::OutOfBounds, Array::Convert);
+ 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.
return ArrayMode(Array::SelectUsingPredictions);
-
- case asArrayModes(ArrayWithUndecided):
- if (action == Array::Write)
- return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::Convert);
- return ArrayMode(Array::Generic);
-
- case asArrayModes(NonArray) | asArrayModes(ArrayWithUndecided):
- if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
- return ArrayMode(Array::Undecided, Array::PossiblyArray, Array::OutOfBounds, Array::Convert);
- return ArrayMode(Array::SelectUsingPredictions);
-
- case asArrayModes(NonArrayWithInt32):
- return ArrayMode(Array::Int32, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe);
- case asArrayModes(ArrayWithInt32):
- return ArrayMode(Array::Int32, Array::Array, Array::AsIs).withProfile(profile, makeSafe);
- case asArrayModes(NonArrayWithInt32) | asArrayModes(ArrayWithInt32):
- return ArrayMode(Array::Int32, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe);
-
- case asArrayModes(NonArrayWithDouble):
- return ArrayMode(Array::Double, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe);
- case asArrayModes(ArrayWithDouble):
- return ArrayMode(Array::Double, Array::Array, Array::AsIs).withProfile(profile, makeSafe);
- case asArrayModes(NonArrayWithDouble) | asArrayModes(ArrayWithDouble):
- return ArrayMode(Array::Double, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe);
-
case asArrayModes(NonArrayWithContiguous):
return ArrayMode(Array::Contiguous, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe);
case asArrayModes(ArrayWithContiguous):
return ArrayMode(Array::Contiguous, Array::Array, Array::AsIs).withProfile(profile, makeSafe);
case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous):
return ArrayMode(Array::Contiguous, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe);
-
case asArrayModes(NonArrayWithArrayStorage):
return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::AsIs).withProfile(profile, makeSafe);
case asArrayModes(NonArrayWithSlowPutArrayStorage):
@@ -89,39 +62,36 @@ ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, b
case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
return ArrayMode(Array::SlowPutArrayStorage, Array::PossiblyArray, Array::AsIs).withProfile(profile, makeSafe);
-
+ case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage):
+ return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::Convert).withProfile(profile, makeSafe);
+ case asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage):
+ return ArrayMode(Array::ArrayStorage, Array::Array, Array::Convert).withProfile(profile, makeSafe);
+ case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage):
+ return ArrayMode(Array::ArrayStorage, Array::PossiblyArray, Array::Convert).withProfile(profile, makeSafe);
+ case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous):
+ if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
+ return ArrayMode(Array::Contiguous, Array::NonArray, Array::OutOfBounds, Array::Convert);
+ return ArrayMode(Array::SelectUsingPredictions);
+ case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage):
+ case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage):
+ if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
+ return ArrayMode(Array::ArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert);
+ return ArrayMode(Array::SelectUsingPredictions);
+ case asArrayModes(NonArray) | asArrayModes(NonArrayWithSlowPutArrayStorage):
+ case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage):
+ if (action == Array::Write && !profile->mayInterceptIndexedAccesses())
+ return ArrayMode(Array::SlowPutArrayStorage, Array::NonArray, Array::OutOfBounds, Array::Convert);
+ return ArrayMode(Array::SelectUsingPredictions);
default:
- if ((observed & asArrayModes(NonArray)) && profile->mayInterceptIndexedAccesses())
- return ArrayMode(Array::SelectUsingPredictions);
-
- Array::Type type;
- Array::Class arrayClass;
-
- if (shouldUseSlowPutArrayStorage(observed))
- type = Array::SlowPutArrayStorage;
- else if (shouldUseFastArrayStorage(observed))
- type = Array::ArrayStorage;
- else if (shouldUseContiguous(observed))
- type = Array::Contiguous;
- else if (shouldUseDouble(observed))
- type = Array::Double;
- else if (shouldUseInt32(observed))
- type = Array::Int32;
- else
- type = Array::Undecided;
-
- if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
- arrayClass = Array::Array;
- else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage)))
- arrayClass = Array::NonArray;
- else
- arrayClass = Array::PossiblyArray;
-
- return ArrayMode(type, arrayClass, Array::Convert).withProfile(profile, makeSafe);
+ // We know that this is possibly a kind of array for which, though there is no
+ // useful data in the array profile, we may be able to extract useful data from
+ // the value profiles of the inputs. Hence, we leave it as undecided, and let
+ // the predictions propagator decide later.
+ return ArrayMode(Array::SelectUsingPredictions);
}
}
-ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, SpeculatedType value) const
+ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index) const
{
if (!base || !index) {
// It can be that we had a legitimate arrayMode but no incoming predictions. That'll
@@ -134,85 +104,49 @@ ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, Speculate
if (!isInt32Speculation(index) || !isCellSpeculation(base))
return ArrayMode(Array::Generic);
- switch (type()) {
- case Array::Unprofiled:
+ if (type() == Array::Unprofiled) {
+ // If the indexing type wasn't recorded in the array profile but the values are
+ // base=cell property=int, then we know that this access didn't execute.
return ArrayMode(Array::ForceExit);
-
- case Array::Undecided:
- if (!value)
- return withType(Array::ForceExit);
- if (isInt32Speculation(value))
- return withTypeAndConversion(Array::Int32, Array::Convert);
- if (isNumberSpeculation(value))
- return withTypeAndConversion(Array::Double, Array::Convert);
- return withTypeAndConversion(Array::Contiguous, Array::Convert);
-
- case Array::Int32:
- if (!value || isInt32Speculation(value))
- return *this;
- if (isNumberSpeculation(value))
- return withTypeAndConversion(Array::Double, Array::Convert);
- return withTypeAndConversion(Array::Contiguous, Array::Convert);
-
- case Array::Double:
- if (!value || isNumberSpeculation(value))
- return *this;
- return withTypeAndConversion(Array::Contiguous, Array::Convert);
-
- case Array::SelectUsingPredictions:
- if (isStringSpeculation(base))
- return ArrayMode(Array::String);
-
- if (isArgumentsSpeculation(base))
- return ArrayMode(Array::Arguments);
-
- if (isInt8ArraySpeculation(base))
- return ArrayMode(Array::Int8Array);
-
- if (isInt16ArraySpeculation(base))
- return ArrayMode(Array::Int16Array);
-
- if (isInt32ArraySpeculation(base))
- return ArrayMode(Array::Int32Array);
-
- if (isUint8ArraySpeculation(base))
- return ArrayMode(Array::Uint8Array);
-
- if (isUint8ClampedArraySpeculation(base))
- return ArrayMode(Array::Uint8ClampedArray);
-
- if (isUint16ArraySpeculation(base))
- return ArrayMode(Array::Uint16Array);
-
- if (isUint32ArraySpeculation(base))
- return ArrayMode(Array::Uint32Array);
-
- if (isFloat32ArraySpeculation(base))
- return ArrayMode(Array::Float32Array);
-
- if (isFloat64ArraySpeculation(base))
- return ArrayMode(Array::Float64Array);
-
- return ArrayMode(Array::Generic);
-
- default:
- return *this;
- }
-}
-
-bool ArrayMode::alreadyChecked(AbstractValue& value, IndexingType shape) const
-{
- if (isJSArray()) {
- if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
- return true;
- return value.m_currentKnownStructure.hasSingleton()
- && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape
- && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
}
- if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape) | asArrayModes(shape | IsArray)))
- return true;
- return value.m_currentKnownStructure.hasSingleton()
- && (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape;
+
+ if (type() != Array::SelectUsingPredictions)
+ return *this;
+
+ if (isStringSpeculation(base))
+ return ArrayMode(Array::String);
+
+ if (isArgumentsSpeculation(base))
+ return ArrayMode(Array::Arguments);
+
+ if (isInt8ArraySpeculation(base))
+ return ArrayMode(Array::Int8Array);
+
+ if (isInt16ArraySpeculation(base))
+ return ArrayMode(Array::Int16Array);
+
+ if (isInt32ArraySpeculation(base))
+ return ArrayMode(Array::Int32Array);
+
+ if (isUint8ArraySpeculation(base))
+ return ArrayMode(Array::Uint8Array);
+
+ if (isUint8ClampedArraySpeculation(base))
+ return ArrayMode(Array::Uint8ClampedArray);
+
+ if (isUint16ArraySpeculation(base))
+ return ArrayMode(Array::Uint16Array);
+
+ if (isUint32ArraySpeculation(base))
+ return ArrayMode(Array::Uint32Array);
+
+ if (isFloat32ArraySpeculation(base))
+ return ArrayMode(Array::Float32Array);
+
+ if (isFloat64ArraySpeculation(base))
+ return ArrayMode(Array::Float64Array);
+
+ return ArrayMode(Array::Generic);
}
bool ArrayMode::alreadyChecked(AbstractValue& value) const
@@ -227,17 +161,31 @@ bool ArrayMode::alreadyChecked(AbstractValue& value) const
case Array::String:
return speculationChecked(value.m_type, SpecString);
- case Array::Int32:
- return alreadyChecked(value, Int32Shape);
-
- case Array::Double:
- return alreadyChecked(value, DoubleShape);
-
case Array::Contiguous:
- return alreadyChecked(value, ContiguousShape);
+ if (isJSArray()) {
+ if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithContiguous)))
+ return true;
+ return value.m_currentKnownStructure.hasSingleton()
+ && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType())
+ && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+ }
+ if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous)))
+ return true;
+ return value.m_currentKnownStructure.hasSingleton()
+ && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType());
case Array::ArrayStorage:
- return alreadyChecked(value, ArrayStorageShape);
+ if (isJSArray()) {
+ if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(ArrayWithArrayStorage)))
+ return true;
+ return value.m_currentKnownStructure.hasSingleton()
+ && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType())
+ && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+ }
+ if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage)))
+ return true;
+ return value.m_currentKnownStructure.hasSingleton()
+ && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType());
case Array::SlowPutArrayStorage:
if (isJSArray()) {
@@ -284,7 +232,6 @@ bool ArrayMode::alreadyChecked(AbstractValue& value) const
case Array::SelectUsingPredictions:
case Array::Unprofiled:
- case Array::Undecided:
break;
}
@@ -305,12 +252,6 @@ const char* arrayTypeToString(Array::Type type)
return "ForceExit";
case Array::String:
return "String";
- case Array::Undecided:
- return "Undecided";
- case Array::Int32:
- return "Int32";
- case Array::Double:
- return "Double";
case Array::Contiguous:
return "Contiguous";
case Array::ArrayStorage: