fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 1 | /* |
fpizlo@apple.com | acdb63e | 2016-05-10 02:01:28 +0000 | [diff] [blame] | 2 | * Copyright (C) 2011-2013, 2016 Apple Inc. All rights reserved. |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 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 | * |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
mjs@apple.com | 9204733 | 2014-03-15 04:08:27 +0000 | [diff] [blame] | 13 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 14 | * its contributors may be used to endorse or promote products derived |
| 15 | * from this software without specific prior written permission. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| 18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 20 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | */ |
| 28 | |
ryanhaddad@apple.com | 22104f5 | 2016-09-28 17:08:17 +0000 | [diff] [blame] | 29 | #pragma once |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 30 | |
fpizlo@apple.com | 171d06f | 2016-11-15 23:21:50 +0000 | [diff] [blame] | 31 | #include "ConcurrentJSLock.h" |
fpizlo@apple.com | 016fd68 | 2012-05-25 20:19:55 +0000 | [diff] [blame] | 32 | #include "Heap.h" |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 33 | #include "JSArray.h" |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 34 | #include "SpeculatedType.h" |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 35 | #include "Structure.h" |
fpizlo@apple.com | acdb63e | 2016-05-10 02:01:28 +0000 | [diff] [blame] | 36 | #include "TagRegistersMode.h" |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 37 | #include "WriteBarrier.h" |
fpizlo@apple.com | 8a8b45e | 2012-11-28 01:29:29 +0000 | [diff] [blame] | 38 | #include <wtf/PrintStream.h> |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 39 | #include <wtf/StringPrintStream.h> |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 40 | |
| 41 | namespace JSC { |
| 42 | |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 43 | template<unsigned numberOfBucketsArgument> |
| 44 | struct ValueProfileBase { |
| 45 | static const unsigned numberOfBuckets = numberOfBucketsArgument; |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 46 | static const unsigned numberOfSpecFailBuckets = 1; |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 47 | static const unsigned bucketIndexMask = numberOfBuckets - 1; |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 48 | static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets; |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 49 | |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 50 | ValueProfileBase() |
fpizlo@apple.com | 086d2af | 2011-12-21 02:29:15 +0000 | [diff] [blame] | 51 | : m_bytecodeOffset(-1) |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 52 | , m_prediction(SpecNone) |
fpizlo@apple.com | 086d2af | 2011-12-21 02:29:15 +0000 | [diff] [blame] | 53 | , m_numberOfSamplesInPrediction(0) |
| 54 | { |
| 55 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) |
| 56 | m_buckets[i] = JSValue::encode(JSValue()); |
| 57 | } |
| 58 | |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 59 | ValueProfileBase(int bytecodeOffset) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 60 | : m_bytecodeOffset(bytecodeOffset) |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 61 | , m_prediction(SpecNone) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 62 | , m_numberOfSamplesInPrediction(0) |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 63 | { |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 64 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 65 | m_buckets[i] = JSValue::encode(JSValue()); |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 66 | } |
| 67 | |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 68 | EncodedJSValue* specFailBucket(unsigned i) |
| 69 | { |
| 70 | ASSERT(numberOfBuckets + i < totalNumberOfBuckets); |
| 71 | return m_buckets + numberOfBuckets + i; |
| 72 | } |
| 73 | |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 74 | const ClassInfo* classInfo(unsigned bucket) const |
| 75 | { |
commit-queue@webkit.org | 387d2ec | 2011-10-09 10:19:23 +0000 | [diff] [blame] | 76 | JSValue value = JSValue::decode(m_buckets[bucket]); |
| 77 | if (!!value) { |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 78 | if (!value.isCell()) |
| 79 | return 0; |
| 80 | return value.asCell()->structure()->classInfo(); |
| 81 | } |
fpizlo@apple.com | ab9a92c | 2011-10-12 20:28:49 +0000 | [diff] [blame] | 82 | return 0; |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | unsigned numberOfSamples() const |
| 86 | { |
| 87 | unsigned result = 0; |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 88 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { |
fpizlo@apple.com | ab9a92c | 2011-10-12 20:28:49 +0000 | [diff] [blame] | 89 | if (!!JSValue::decode(m_buckets[i])) |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 90 | result++; |
| 91 | } |
| 92 | return result; |
| 93 | } |
| 94 | |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 95 | unsigned totalNumberOfSamples() const |
| 96 | { |
| 97 | return numberOfSamples() + m_numberOfSamplesInPrediction; |
| 98 | } |
| 99 | |
| 100 | bool isLive() const |
| 101 | { |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 102 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { |
fpizlo@apple.com | ab9a92c | 2011-10-12 20:28:49 +0000 | [diff] [blame] | 103 | if (!!JSValue::decode(m_buckets[i])) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 104 | return true; |
| 105 | } |
| 106 | return false; |
| 107 | } |
| 108 | |
fpizlo@apple.com | 171d06f | 2016-11-15 23:21:50 +0000 | [diff] [blame] | 109 | CString briefDescription(const ConcurrentJSLocker& locker) |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 110 | { |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 111 | computeUpdatedPrediction(locker); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 112 | |
| 113 | StringPrintStream out; |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 114 | out.print("predicting ", SpeculationDump(m_prediction)); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 115 | return out.toCString(); |
| 116 | } |
| 117 | |
fpizlo@apple.com | 8a8b45e | 2012-11-28 01:29:29 +0000 | [diff] [blame] | 118 | void dump(PrintStream& out) |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 119 | { |
fpizlo@apple.com | 02e3563 | 2012-11-29 06:01:40 +0000 | [diff] [blame] | 120 | out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction)); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 121 | bool first = true; |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 122 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { |
commit-queue@webkit.org | 387d2ec | 2011-10-09 10:19:23 +0000 | [diff] [blame] | 123 | JSValue value = JSValue::decode(m_buckets[i]); |
fpizlo@apple.com | ab9a92c | 2011-10-12 20:28:49 +0000 | [diff] [blame] | 124 | if (!!value) { |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 125 | if (first) { |
fpizlo@apple.com | 8a8b45e | 2012-11-28 01:29:29 +0000 | [diff] [blame] | 126 | out.printf(": "); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 127 | first = false; |
| 128 | } else |
fpizlo@apple.com | 8a8b45e | 2012-11-28 01:29:29 +0000 | [diff] [blame] | 129 | out.printf(", "); |
fpizlo@apple.com | 9fe4913 | 2012-12-04 19:29:13 +0000 | [diff] [blame] | 130 | out.print(value); |
fpizlo@apple.com | ab9a92c | 2011-10-12 20:28:49 +0000 | [diff] [blame] | 131 | } |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 132 | } |
| 133 | } |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 134 | |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 135 | // Updates the prediction and returns the new one. Never call this from any thread |
| 136 | // that isn't executing the code. |
fpizlo@apple.com | 171d06f | 2016-11-15 23:21:50 +0000 | [diff] [blame] | 137 | SpeculatedType computeUpdatedPrediction(const ConcurrentJSLocker&) |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 138 | { |
| 139 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { |
| 140 | JSValue value = JSValue::decode(m_buckets[i]); |
| 141 | if (!value) |
| 142 | continue; |
| 143 | |
| 144 | m_numberOfSamplesInPrediction++; |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 145 | mergeSpeculation(m_prediction, speculationFromValue(value)); |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 146 | |
| 147 | m_buckets[i] = JSValue::encode(JSValue()); |
| 148 | } |
| 149 | |
| 150 | return m_prediction; |
| 151 | } |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 152 | |
| 153 | int m_bytecodeOffset; // -1 for prologue |
| 154 | |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 155 | SpeculatedType m_prediction; |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 156 | unsigned m_numberOfSamplesInPrediction; |
| 157 | |
fpizlo@apple.com | 49bfe57 | 2011-10-31 23:50:57 +0000 | [diff] [blame] | 158 | EncodedJSValue m_buckets[totalNumberOfBuckets]; |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 159 | }; |
| 160 | |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 161 | struct MinimalValueProfile : public ValueProfileBase<0> { |
| 162 | MinimalValueProfile(): ValueProfileBase<0>() { } |
| 163 | MinimalValueProfile(int bytecodeOffset): ValueProfileBase<0>(bytecodeOffset) { } |
| 164 | }; |
| 165 | |
| 166 | template<unsigned logNumberOfBucketsArgument> |
| 167 | struct ValueProfileWithLogNumberOfBuckets : public ValueProfileBase<1 << logNumberOfBucketsArgument> { |
| 168 | static const unsigned logNumberOfBuckets = logNumberOfBucketsArgument; |
| 169 | |
| 170 | ValueProfileWithLogNumberOfBuckets() |
| 171 | : ValueProfileBase<1 << logNumberOfBucketsArgument>() |
| 172 | { |
| 173 | } |
| 174 | ValueProfileWithLogNumberOfBuckets(int bytecodeOffset) |
| 175 | : ValueProfileBase<1 << logNumberOfBucketsArgument>(bytecodeOffset) |
| 176 | { |
| 177 | } |
| 178 | }; |
| 179 | |
| 180 | struct ValueProfile : public ValueProfileWithLogNumberOfBuckets<0> { |
| 181 | ValueProfile(): ValueProfileWithLogNumberOfBuckets<0>() { } |
| 182 | ValueProfile(int bytecodeOffset): ValueProfileWithLogNumberOfBuckets<0>(bytecodeOffset) { } |
| 183 | }; |
| 184 | |
| 185 | template<typename T> |
| 186 | inline int getValueProfileBytecodeOffset(T* valueProfile) |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 187 | { |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 188 | return valueProfile->m_bytecodeOffset; |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 189 | } |
fpizlo@apple.com | 9b0b31e | 2011-09-19 22:27:38 +0000 | [diff] [blame] | 190 | |
| 191 | // This is a mini value profile to catch pathologies. It is a counter that gets |
| 192 | // incremented when we take the slow path on any instruction. |
| 193 | struct RareCaseProfile { |
| 194 | RareCaseProfile(int bytecodeOffset) |
| 195 | : m_bytecodeOffset(bytecodeOffset) |
| 196 | , m_counter(0) |
| 197 | { |
| 198 | } |
| 199 | |
| 200 | int m_bytecodeOffset; |
| 201 | uint32_t m_counter; |
| 202 | }; |
| 203 | |
| 204 | inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile) |
| 205 | { |
| 206 | return rareCaseProfile->m_bytecodeOffset; |
| 207 | } |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 208 | |
fpizlo@apple.com | 31659de | 2012-02-23 22:51:09 +0000 | [diff] [blame] | 209 | } // namespace JSC |