diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGArrayMode.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGArrayMode.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp new file mode 100644 index 000000000..ec4edc2e8 --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DFGArrayMode.h" + +#if ENABLE(DFG_JIT) + +#include "DFGAbstractValue.h" + +namespace JSC { namespace DFG { + +Array::Mode fromObserved(ArrayModes modes, bool makeSafe) +{ + // FIXME: we may want to add some polymorphic support in the future. That's why this + // is a switch statement right now. + + switch (modes) { + case 0: + return Array::Undecided; + case IsJSArray: + return makeSafe ? Array::JSArrayOutOfBounds : Array::JSArray; + default: + // 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 Array::Undecided; + } +} + +Array::Mode refineArrayMode(Array::Mode arrayMode, SpeculatedType base, SpeculatedType index) +{ + if (!base || !index) { + // It can be that we had a legitimate arrayMode but no incoming predictions. That'll + // happen if we inlined code based on, say, a global variable watchpoint, but later + // realized that the callsite could not have possibly executed. It may be worthwhile + // to fix that, but for now I'm leaving it as-is. + return Array::ForceExit; + } + + if (!isInt32Speculation(index) || !isCellSpeculation(base)) + return Array::Generic; + + // Pass through any array modes that would have been decided by the array profile, since + // the predictions of the inputs will not tell us anything useful that we didn't already + // get from the array profile. + switch (arrayMode) { + case Array::ForceExit: + case Array::JSArray: + case Array::JSArrayOutOfBounds: + return arrayMode; + default: + break; + } + + if (isStringSpeculation(base)) + return Array::String; + + if (isArgumentsSpeculation(base)) + return Array::Arguments; + + if (isInt8ArraySpeculation(base)) + return Array::Int8Array; + + if (isInt16ArraySpeculation(base)) + return Array::Int16Array; + + if (isInt32ArraySpeculation(base)) + return Array::Int32Array; + + if (isUint8ArraySpeculation(base)) + return Array::Uint8Array; + + if (isUint8ClampedArraySpeculation(base)) + return Array::Uint8ClampedArray; + + if (isUint16ArraySpeculation(base)) + return Array::Uint16Array; + + if (isUint32ArraySpeculation(base)) + return Array::Uint32Array; + + if (isFloat32ArraySpeculation(base)) + return Array::Float32Array; + + if (isFloat64ArraySpeculation(base)) + return Array::Float64Array; + + return Array::Generic; +} + +bool modeAlreadyChecked(AbstractValue& value, Array::Mode arrayMode) +{ + switch (arrayMode) { + case Array::Generic: + return true; + + case Array::ForceExit: + return false; + + case Array::String: + return isStringSpeculation(value.m_type); + + case Array::JSArray: + case Array::JSArrayOutOfBounds: + return value.m_currentKnownStructure.hasSingleton() + && value.m_currentKnownStructure.singleton()->classInfo() == &JSArray::s_info; + + case Array::Arguments: + return isArgumentsSpeculation(value.m_type); + + case Array::Int8Array: + return isInt8ArraySpeculation(value.m_type); + + case Array::Int16Array: + return isInt16ArraySpeculation(value.m_type); + + case Array::Int32Array: + return isInt32ArraySpeculation(value.m_type); + + case Array::Uint8Array: + return isUint8ArraySpeculation(value.m_type); + + case Array::Uint8ClampedArray: + return isUint8ClampedArraySpeculation(value.m_type); + + case Array::Uint16Array: + return isUint16ArraySpeculation(value.m_type); + + case Array::Uint32Array: + return isUint32ArraySpeculation(value.m_type); + + case Array::Float32Array: + return isFloat32ArraySpeculation(value.m_type); + + case Array::Float64Array: + return isFloat64ArraySpeculation(value.m_type); + + case Array::Undecided: + break; + } + + ASSERT_NOT_REACHED(); + return false; +} + +const char* modeToString(Array::Mode mode) +{ + switch (mode) { + case Array::Undecided: + return "Undecided"; + case Array::Generic: + return "Generic"; + case Array::ForceExit: + return "ForceExit"; + case Array::String: + return "String"; + case Array::JSArray: + return "JSArray"; + case Array::JSArrayOutOfBounds: + return "JSArrayOutOfBounds"; + case Array::Arguments: + return "Arguments"; + case Array::Int8Array: + return "Int8Array"; + case Array::Int16Array: + return "Int16Array"; + case Array::Int32Array: + return "Int32Array"; + case Array::Uint8Array: + return "Uint8Array"; + case Array::Uint8ClampedArray: + return "Uint8ClampedArray"; + case Array::Uint16Array: + return "Uint16Array"; + case Array::Uint32Array: + return "Uint32Array"; + case Array::Float32Array: + return "Float32Array"; + case Array::Float64Array: + return "Float64Array"; + default: + // Better to return something then it is to crash. Remember, this method + // is being called from our main diagnostic tool, the IR dumper. It's like + // a stack trace. So if we get here then probably something has already + // gone wrong. + return "Unknown!"; + } +} + +} } // namespace JSC::DFG + +#endif // ENABLE(DFG_JIT) + |