1/* 2 * Copyright (C) 2012, 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#include "config.h" 27#include "ArrayProfile.h" 28 29#include "CodeBlock.h" 30#include "JSCInlines.h" 31#include <wtf/CommaPrinter.h> 32#include <wtf/StringExtras.h> 33#include <wtf/StringPrintStream.h> 34 35namespace JSC { 36 37void dumpArrayModes(PrintStream& out, ArrayModes arrayModes) 38{ 39 if (!arrayModes) { 40 out.print("<empty>"); 41 return; 42 } 43 44 if (arrayModes == ALL_ARRAY_MODES) { 45 out.print("TOP"); 46 return; 47 } 48 49 CommaPrinter comma("|"); 50 if (arrayModes & asArrayModes(NonArray)) 51 out.print(comma, "NonArray"); 52 if (arrayModes & asArrayModes(NonArrayWithInt32)) 53 out.print(comma, "NonArrayWithInt32"); 54 if (arrayModes & asArrayModes(NonArrayWithDouble)) 55 out.print(comma, "NonArrayWithDouble"); 56 if (arrayModes & asArrayModes(NonArrayWithContiguous)) 57 out.print(comma, "NonArrayWithContiguous"); 58 if (arrayModes & asArrayModes(NonArrayWithArrayStorage)) 59 out.print(comma, "NonArrayWithArrayStorage"); 60 if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage)) 61 out.print(comma, "NonArrayWithSlowPutArrayStorage"); 62 if (arrayModes & asArrayModes(ArrayClass)) 63 out.print(comma, "ArrayClass"); 64 if (arrayModes & asArrayModes(ArrayWithUndecided)) 65 out.print(comma, "ArrayWithUndecided"); 66 if (arrayModes & asArrayModes(ArrayWithInt32)) 67 out.print(comma, "ArrayWithInt32"); 68 if (arrayModes & asArrayModes(ArrayWithDouble)) 69 out.print(comma, "ArrayWithDouble"); 70 if (arrayModes & asArrayModes(ArrayWithContiguous)) 71 out.print(comma, "ArrayWithContiguous"); 72 if (arrayModes & asArrayModes(ArrayWithArrayStorage)) 73 out.print(comma, "ArrayWithArrayStorage"); 74 if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage)) 75 out.print(comma, "ArrayWithSlowPutArrayStorage"); 76} 77 78void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock) 79{ 80 if (!m_lastSeenStructureID) 81 return; 82 83 Structure* lastSeenStructure = codeBlock->heap()->structureIDTable().get(m_lastSeenStructureID); 84 m_observedArrayModes |= arrayModeFromStructure(lastSeenStructure); 85 86 if (!m_didPerformFirstRunPruning 87 && hasTwoOrMoreBitsSet(m_observedArrayModes)) { 88 m_observedArrayModes = arrayModeFromStructure(lastSeenStructure); 89 m_didPerformFirstRunPruning = true; 90 } 91 92 m_mayInterceptIndexedAccesses |= 93 lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero(); 94 JSGlobalObject* globalObject = codeBlock->globalObject(); 95 if (!globalObject->isOriginalArrayStructure(lastSeenStructure) 96 && !globalObject->isOriginalTypedArrayStructure(lastSeenStructure)) 97 m_usesOriginalArrayStructures = false; 98 m_lastSeenStructureID = 0; 99} 100 101CString ArrayProfile::briefDescription(const ConcurrentJITLocker& locker, CodeBlock* codeBlock) 102{ 103 computeUpdatedPrediction(locker, codeBlock); 104 return briefDescriptionWithoutUpdating(locker); 105} 106 107CString ArrayProfile::briefDescriptionWithoutUpdating(const ConcurrentJITLocker&) 108{ 109 StringPrintStream out; 110 111 bool hasPrinted = false; 112 113 if (m_observedArrayModes) { 114 if (hasPrinted) 115 out.print(", "); 116 out.print(ArrayModesDump(m_observedArrayModes)); 117 hasPrinted = true; 118 } 119 120 if (m_mayStoreToHole) { 121 if (hasPrinted) 122 out.print(", "); 123 out.print("Hole"); 124 hasPrinted = true; 125 } 126 127 if (m_outOfBounds) { 128 if (hasPrinted) 129 out.print(", "); 130 out.print("OutOfBounds"); 131 hasPrinted = true; 132 } 133 134 if (m_mayInterceptIndexedAccesses) { 135 if (hasPrinted) 136 out.print(", "); 137 out.print("Intercept"); 138 hasPrinted = true; 139 } 140 141 if (m_usesOriginalArrayStructures) { 142 if (hasPrinted) 143 out.print(", "); 144 out.print("Original"); 145 hasPrinted = true; 146 } 147 148 UNUSED_PARAM(hasPrinted); 149 150 return out.toCString(); 151} 152 153} // namespace JSC 154 155