1/* 2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef DFGValueSource_h 27#define DFGValueSource_h 28 29#include <wtf/Platform.h> 30 31#if ENABLE(DFG_JIT) 32 33#include "DFGCommon.h" 34#include "DFGMinifiedID.h" 35#include "DataFormat.h" 36#include "SpeculatedType.h" 37#include "ValueRecovery.h" 38 39namespace JSC { namespace DFG { 40 41enum ValueSourceKind { 42 SourceNotSet, 43 ValueInJSStack, 44 Int32InJSStack, 45 CellInJSStack, 46 BooleanInJSStack, 47 DoubleInJSStack, 48 ArgumentsSource, 49 SourceIsDead, 50 HaveNode 51}; 52 53static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat) 54{ 55 switch (dataFormat) { 56 case DataFormatInteger: 57 return Int32InJSStack; 58 case DataFormatDouble: 59 return DoubleInJSStack; 60 case DataFormatBoolean: 61 return BooleanInJSStack; 62 case DataFormatCell: 63 return CellInJSStack; 64 case DataFormatDead: 65 return SourceIsDead; 66 case DataFormatArguments: 67 return ArgumentsSource; 68 default: 69 RELEASE_ASSERT(dataFormat & DataFormatJS); 70 return ValueInJSStack; 71 } 72} 73 74static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind) 75{ 76 switch (kind) { 77 case ValueInJSStack: 78 return DataFormatJS; 79 case Int32InJSStack: 80 return DataFormatInteger; 81 case CellInJSStack: 82 return DataFormatCell; 83 case BooleanInJSStack: 84 return DataFormatBoolean; 85 case DoubleInJSStack: 86 return DataFormatDouble; 87 case ArgumentsSource: 88 return DataFormatArguments; 89 case SourceIsDead: 90 return DataFormatDead; 91 default: 92 return DataFormatNone; 93 } 94} 95 96static inline bool isInJSStack(ValueSourceKind kind) 97{ 98 DataFormat format = valueSourceKindToDataFormat(kind); 99 return format != DataFormatNone && format < DataFormatOSRMarker; 100} 101 102// Can this value be recovered without having to look at register allocation state or 103// DFG node liveness? 104static inline bool isTriviallyRecoverable(ValueSourceKind kind) 105{ 106 return valueSourceKindToDataFormat(kind) != DataFormatNone; 107} 108 109class ValueSource { 110public: 111 ValueSource() 112 : m_value(idFromKind(SourceNotSet)) 113 { 114 } 115 116 explicit ValueSource(ValueSourceKind valueSourceKind) 117 : m_value(idFromKind(valueSourceKind)) 118 { 119 ASSERT(kind() != SourceNotSet); 120 ASSERT(kind() != HaveNode); 121 } 122 123 explicit ValueSource(MinifiedID id) 124 : m_value(id) 125 { 126 ASSERT(!!id); 127 ASSERT(kind() == HaveNode); 128 } 129 130 static ValueSource forSpeculation(SpeculatedType prediction) 131 { 132 if (isInt32Speculation(prediction)) 133 return ValueSource(Int32InJSStack); 134 if (isArraySpeculation(prediction) || isCellSpeculation(prediction)) 135 return ValueSource(CellInJSStack); 136 if (isBooleanSpeculation(prediction)) 137 return ValueSource(BooleanInJSStack); 138 return ValueSource(ValueInJSStack); 139 } 140 141 static ValueSource forDataFormat(DataFormat dataFormat) 142 { 143 return ValueSource(dataFormatToValueSourceKind(dataFormat)); 144 } 145 146 bool isSet() const 147 { 148 return kindFromID(m_value) != SourceNotSet; 149 } 150 151 ValueSourceKind kind() const 152 { 153 return kindFromID(m_value); 154 } 155 156 bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); } 157 bool isTriviallyRecoverable() const { return JSC::DFG::isTriviallyRecoverable(kind()); } 158 159 DataFormat dataFormat() const 160 { 161 return valueSourceKindToDataFormat(kind()); 162 } 163 164 ValueRecovery valueRecovery() const 165 { 166 ASSERT(isTriviallyRecoverable()); 167 switch (kind()) { 168 case ValueInJSStack: 169 return ValueRecovery::alreadyInJSStack(); 170 171 case Int32InJSStack: 172 return ValueRecovery::alreadyInJSStackAsUnboxedInt32(); 173 174 case CellInJSStack: 175 return ValueRecovery::alreadyInJSStackAsUnboxedCell(); 176 177 case BooleanInJSStack: 178 return ValueRecovery::alreadyInJSStackAsUnboxedBoolean(); 179 180 case DoubleInJSStack: 181 return ValueRecovery::alreadyInJSStackAsUnboxedDouble(); 182 183 case SourceIsDead: 184 return ValueRecovery::constant(jsUndefined()); 185 186 case ArgumentsSource: 187 return ValueRecovery::argumentsThatWereNotCreated(); 188 189 default: 190 RELEASE_ASSERT_NOT_REACHED(); 191 return ValueRecovery(); 192 } 193 } 194 195 MinifiedID id() const 196 { 197 ASSERT(kind() == HaveNode); 198 return m_value; 199 } 200 201 void dump(PrintStream&) const; 202 203private: 204 static MinifiedID idFromKind(ValueSourceKind kind) 205 { 206 ASSERT(kind >= SourceNotSet && kind < HaveNode); 207 return MinifiedID::fromBits(MinifiedID::invalidID() - kind); 208 } 209 210 static ValueSourceKind kindFromID(MinifiedID id) 211 { 212 uintptr_t kind = static_cast<uintptr_t>(MinifiedID::invalidID() - id.m_id); 213 if (kind >= static_cast<uintptr_t>(HaveNode)) 214 return HaveNode; 215 return static_cast<ValueSourceKind>(kind); 216 } 217 218 MinifiedID m_value; 219}; 220 221} } // namespace JSC::DFG 222 223#endif // ENABLE(DFG_JIT) 224 225#endif // DFGValueSource_h 226 227