SpeculatedType.cpp 11.2 KB
Newer Older
1
/*
2
 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *
 * 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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"
30
#include "SpeculatedType.h"
31

32
#include "Arguments.h"
33
#include "JSArray.h"
34
#include "JSFunction.h"
35
#include "Operations.h"
36
#include "StringObject.h"
37
#include "ValueProfile.h"
38
#include <wtf/BoundsCheckedPointer.h>
39
#include <wtf/StringPrintStream.h>
40 41 42

namespace JSC {

43
void dumpSpeculation(PrintStream& out, SpeculatedType value)
44
{
45 46 47 48
    if (value == SpecNone) {
        out.print("None");
        return;
    }
49
    
50
    StringPrintStream myOut;
51
    
52 53
    bool isTop = true;
    
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    if ((value & SpecCell) == SpecCell)
        myOut.print("Cell");
    else {
        if ((value & SpecObject) == SpecObject)
            myOut.print("Object");
        else {
            if (value & SpecCellOther)
                myOut.print("Othercell");
            else
                isTop = false;
    
            if (value & SpecObjectOther)
                myOut.print("Otherobj");
            else
                isTop = false;
    
            if (value & SpecFinalObject)
                myOut.print("Final");
            else
                isTop = false;
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
            if (value & SpecArray)
                myOut.print("Array");
            else
                isTop = false;
    
            if (value & SpecInt8Array)
                myOut.print("Int8array");
            else
                isTop = false;
    
            if (value & SpecInt16Array)
                myOut.print("Int16array");
            else
                isTop = false;
    
            if (value & SpecInt32Array)
                myOut.print("Int32array");
            else
                isTop = false;
    
            if (value & SpecUint8Array)
                myOut.print("Uint8array");
            else
                isTop = false;
99

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
            if (value & SpecUint8ClampedArray)
                myOut.print("Uint8clampedarray");
            else
                isTop = false;
    
            if (value & SpecUint16Array)
                myOut.print("Uint16array");
            else
                isTop = false;
    
            if (value & SpecUint32Array)
                myOut.print("Uint32array");
            else
                isTop = false;
    
            if (value & SpecFloat32Array)
                myOut.print("Float32array");
            else
                isTop = false;
    
            if (value & SpecFloat64Array)
                myOut.print("Float64array");
            else
                isTop = false;
    
            if (value & SpecFunction)
                myOut.print("Function");
            else
                isTop = false;
    
            if (value & SpecArguments)
                myOut.print("Arguments");
            else
                isTop = false;
    
            if (value & SpecStringObject)
                myOut.print("Stringobject");
            else
                isTop = false;
        }

141
        if ((value & SpecString) == SpecString)
142
            myOut.print("String");
143 144 145 146 147 148 149 150 151 152 153
        else {
            if (value & SpecStringIdent)
                myOut.print("Stringident");
            else
                isTop = false;
            
            if (value & SpecStringVar)
                myOut.print("Stringvar");
            else
                isTop = false;
        }
154
    }
155
    
156
    if (value & SpecInt32)
157
        myOut.print("Int32");
158 159
    else
        isTop = false;
160
    
161 162 163
    if (value & SpecInt52)
        myOut.print("Int52");
        
164 165 166
    if ((value & SpecDouble) == SpecDouble)
        myOut.print("Double");
    else {
167 168
        if (value & SpecInt52AsDouble)
            myOut.print("Int52asdouble");
169 170 171
        else
            isTop = false;
        
172 173
        if (value & SpecNonIntAsDouble)
            myOut.print("Nonintasdouble");
174 175 176 177 178 179 180 181
        else
            isTop = false;
        
        if (value & SpecDoubleNaN)
            myOut.print("Doublenan");
        else
            isTop = false;
    }
182
    
183
    if (value & SpecBoolean)
184
        myOut.print("Bool");
185 186
    else
        isTop = false;
187
    
188
    if (value & SpecOther)
189
        myOut.print("Other");
190 191 192
    else
        isTop = false;
    
193 194 195 196
    if (isTop)
        out.print("Top");
    else
        out.print(myOut.toCString());
197
    
198
    if (value & SpecEmpty)
199
        out.print("Empty");
200 201
}

202 203 204
// We don't expose this because we don't want anyone relying on the fact that this method currently
// just returns string constants.
static const char* speculationToAbbreviatedString(SpeculatedType prediction)
205
{
206
    if (isFinalObjectSpeculation(prediction))
207
        return "<Final>";
208
    if (isArraySpeculation(prediction))
209
        return "<Array>";
210 211
    if (isStringIdentSpeculation(prediction))
        return "<StringIdent>";
212
    if (isStringSpeculation(prediction))
213
        return "<String>";
214
    if (isFunctionSpeculation(prediction))
215
        return "<Function>";
216
    if (isInt8ArraySpeculation(prediction))
217
        return "<Int8array>";
218
    if (isInt16ArraySpeculation(prediction))
219
        return "<Int16array>";
220
    if (isInt32ArraySpeculation(prediction))
221
        return "<Int32array>";
222
    if (isUint8ArraySpeculation(prediction))
223
        return "<Uint8array>";
224
    if (isUint16ArraySpeculation(prediction))
225
        return "<Uint16array>";
226
    if (isUint32ArraySpeculation(prediction))
227
        return "<Uint32array>";
228
    if (isFloat32ArraySpeculation(prediction))
229
        return "<Float32array>";
230
    if (isFloat64ArraySpeculation(prediction))
231
        return "<Float64array>";
232
    if (isArgumentsSpeculation(prediction))
233
        return "<Arguments>";
234 235 236 237
    if (isStringObjectSpeculation(prediction))
        return "<StringObject>";
    if (isStringOrStringObjectSpeculation(prediction))
        return "<StringOrStringObject>";
238
    if (isObjectSpeculation(prediction))
239
        return "<Object>";
240
    if (isCellSpeculation(prediction))
241
        return "<Cell>";
242
    if (isInt32Speculation(prediction))
243
        return "<Int32>";
244 245 246 247 248 249
    if (isInt52AsDoubleSpeculation(prediction))
        return "<Int52AsDouble>";
    if (isInt52Speculation(prediction))
        return "<Int52>";
    if (isMachineIntSpeculation(prediction))
        return "<MachineInt>";
250
    if (isDoubleSpeculation(prediction))
251
        return "<Double>";
252
    if (isFullNumberSpeculation(prediction))
253
        return "<Number>";
254
    if (isBooleanSpeculation(prediction))
255
        return "<Boolean>";
256
    if (isOtherSpeculation(prediction))
257 258 259 260
        return "<Other>";
    return "";
}

261 262 263 264 265
void dumpSpeculationAbbreviated(PrintStream& out, SpeculatedType value)
{
    out.print(speculationToAbbreviatedString(value));
}

266
SpeculatedType speculationFromTypedArrayType(TypedArrayType type)
267
{
268
    switch (type) {
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
    case TypeInt8:
        return SpecInt8Array;
    case TypeInt16:
        return SpecInt16Array;
    case TypeInt32:
        return SpecInt32Array;
    case TypeUint8:
        return SpecUint8Array;
    case TypeUint8Clamped:
        return SpecUint8ClampedArray;
    case TypeUint16:
        return SpecUint16Array;
    case TypeUint32:
        return SpecUint32Array;
    case TypeFloat32:
        return SpecFloat32Array;
    case TypeFloat64:
        return SpecFloat64Array;
287 288
    case NotTypedArray:
    case TypeDataView:
289
        break;
290
    }
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    RELEASE_ASSERT_NOT_REACHED();
    return SpecNone;
}

SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
{
    if (classInfo == JSFinalObject::info())
        return SpecFinalObject;
    
    if (classInfo == JSArray::info())
        return SpecArray;
    
    if (classInfo == Arguments::info())
        return SpecArguments;
    
    if (classInfo == StringObject::info())
        return SpecStringObject;
    
    if (classInfo->isSubClassOf(JSFunction::info()))
        return SpecFunction;
    
    if (isTypedView(classInfo->typedArrayStorageType))
        return speculationFromTypedArrayType(classInfo->typedArrayStorageType);
314
    
315
    if (classInfo->isSubClassOf(JSObject::info()))
316
        return SpecObjectOther;
317
    
318
    return SpecCellOther;
319 320
}

321
SpeculatedType speculationFromStructure(Structure* structure)
322
{
323 324
    if (structure->typeInfo().type() == StringType)
        return SpecString;
325
    return speculationFromClassInfo(structure->classInfo());
326 327
}

328
SpeculatedType speculationFromCell(JSCell* cell)
329
{
330 331 332 333 334 335 336
    if (JSString* string = jsDynamicCast<JSString*>(cell)) {
        if (const StringImpl* impl = string->tryGetValueImpl()) {
            if (impl->isIdentifier())
                return SpecStringIdent;
        }
        return SpecStringVar;
    }
337
    return speculationFromStructure(cell->structure());
338 339
}

340
SpeculatedType speculationFromValue(JSValue value)
341
{
342
    if (value.isEmpty())
343
        return SpecEmpty;
344
    if (value.isInt32())
345
        return SpecInt32;
346 347
    if (value.isDouble()) {
        double number = value.asNumber();
348 349 350 351 352
        if (number != number)
            return SpecDoubleNaN;
        if (value.isMachineInt())
            return SpecInt52AsDouble;
        return SpecNonIntAsDouble;
353
    }
354
    if (value.isCell())
355
        return speculationFromCell(value.asCell());
356
    if (value.isBoolean())
357
        return SpecBoolean;
358
    ASSERT(value.isUndefinedOrNull());
359
    return SpecOther;
360 361
}

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
{
    if (isInt8ArraySpeculation(type))
        return TypeInt8;
        
    if (isInt16ArraySpeculation(type))
        return TypeInt16;
        
    if (isInt32ArraySpeculation(type))
        return TypeInt32;
        
    if (isUint8ArraySpeculation(type))
        return TypeUint8;
        
    if (isUint8ClampedArraySpeculation(type))
        return TypeUint8Clamped;
        
    if (isUint16ArraySpeculation(type))
        return TypeUint16;
        
    if (isUint32ArraySpeculation(type))
        return TypeUint32;
        
    if (isFloat32ArraySpeculation(type))
        return TypeFloat32;
        
    if (isFloat64ArraySpeculation(type))
        return TypeFloat64;
    
    return NotTypedArray;
}

394 395
} // namespace JSC