ef49f20ce767116e0fe7ad4ac89f6b3b40ab7189
[WebKit-https.git] / Source / JavaScriptCore / bytecode / ArrayProfile.cpp
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
35 namespace JSC {
36
37 void 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
78 void 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
101 CString ArrayProfile::briefDescription(const ConcurrentJITLocker& locker, CodeBlock* codeBlock)
102 {
103     computeUpdatedPrediction(locker, codeBlock);
104     return briefDescriptionWithoutUpdating(locker);
105 }
106
107 CString 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