fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 1 | /* |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 2 | * Copyright (C) 2012-2015 Apple Inc. All rights reserved. |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +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 | * 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 "PutByIdStatus.h" |
| 28 | |
| 29 | #include "CodeBlock.h" |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 30 | #include "ComplexGetStatus.h" |
commit-queue@webkit.org | eebad5d | 2012-08-31 23:25:28 +0000 | [diff] [blame] | 31 | #include "LLIntData.h" |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 32 | #include "LowLevelInterpreter.h" |
fpizlo@apple.com | fb7eff2 | 2014-02-11 01:45:50 +0000 | [diff] [blame] | 33 | #include "JSCInlines.h" |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 34 | #include "PolymorphicAccess.h" |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 35 | #include "Structure.h" |
| 36 | #include "StructureChain.h" |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 37 | #include <wtf/ListDump.h> |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 38 | |
| 39 | namespace JSC { |
| 40 | |
fpizlo@apple.com | 5739957 | 2014-03-05 22:01:57 +0000 | [diff] [blame] | 41 | bool PutByIdStatus::appendVariant(const PutByIdVariant& variant) |
| 42 | { |
| 43 | for (unsigned i = 0; i < m_variants.size(); ++i) { |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 44 | if (m_variants[i].attemptToMerge(variant)) |
| 45 | return true; |
| 46 | } |
| 47 | for (unsigned i = 0; i < m_variants.size(); ++i) { |
| 48 | if (m_variants[i].oldStructure().overlaps(variant.oldStructure())) |
fpizlo@apple.com | 5739957 | 2014-03-05 22:01:57 +0000 | [diff] [blame] | 49 | return false; |
| 50 | } |
| 51 | m_variants.append(variant); |
| 52 | return true; |
| 53 | } |
| 54 | |
commit-queue@webkit.org | e975487 | 2014-02-15 08:30:54 +0000 | [diff] [blame] | 55 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | c1f69d7 | 2015-06-02 05:39:11 +0000 | [diff] [blame] | 56 | bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 57 | { |
fpizlo@apple.com | c1f69d7 | 2015-06-02 05:39:11 +0000 | [diff] [blame] | 58 | return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache)) |
| 59 | || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache)); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 60 | |
| 61 | } |
| 62 | #endif |
| 63 | |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 64 | PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, UniquedStringImpl* uid) |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 65 | { |
| 66 | UNUSED_PARAM(profiledBlock); |
| 67 | UNUSED_PARAM(bytecodeIndex); |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 68 | UNUSED_PARAM(uid); |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 69 | |
| 70 | VM& vm = *profiledBlock->vm(); |
| 71 | |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 72 | Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; |
| 73 | |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 74 | StructureID structureID = instruction[4].u.structureID; |
| 75 | if (!structureID) |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 76 | return PutByIdStatus(NoInformation); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 77 | |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 78 | Structure* structure = vm.heap.structureIDTable().get(structureID); |
| 79 | |
| 80 | StructureID newStructureID = instruction[6].u.structureID; |
| 81 | if (!newStructureID) { |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 82 | PropertyOffset offset = structure->getConcurrently(uid); |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 83 | if (!isValidOffset(offset)) |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 84 | return PutByIdStatus(NoInformation); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 85 | |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 86 | return PutByIdVariant::replace(structure, offset, structure->inferredTypeDescriptorFor(uid)); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 87 | } |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 88 | |
| 89 | Structure* newStructure = vm.heap.structureIDTable().get(newStructureID); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 90 | |
fpizlo@apple.com | 04e4115 | 2012-06-15 22:14:53 +0000 | [diff] [blame] | 91 | ASSERT(structure->transitionWatchpointSetHasBeenInvalidated()); |
| 92 | |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 93 | PropertyOffset offset = newStructure->getConcurrently(uid); |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 94 | if (!isValidOffset(offset)) |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 95 | return PutByIdStatus(NoInformation); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 96 | |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 97 | ObjectPropertyConditionSet conditionSet; |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 98 | if (!(instruction[8].u.putByIdFlags & PutByIdIsDirect)) { |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 99 | conditionSet = |
| 100 | generateConditionsForPropertySetterMissConcurrently( |
| 101 | *profiledBlock->vm(), profiledBlock->globalObject(), structure, uid); |
| 102 | if (!conditionSet.isValid()) |
| 103 | return PutByIdStatus(NoInformation); |
| 104 | } |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 105 | |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 106 | return PutByIdVariant::transition( |
| 107 | structure, newStructure, conditionSet, offset, newStructure->inferredTypeDescriptorFor(uid)); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 108 | } |
| 109 | |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 110 | PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, StubInfoMap& map, unsigned bytecodeIndex, UniquedStringImpl* uid) |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 111 | { |
oliver@apple.com | d205666 | 2013-07-25 04:00:37 +0000 | [diff] [blame] | 112 | ConcurrentJITLocker locker(profiledBlock->m_lock); |
oliver@apple.com | 0c1b13e | 2013-07-25 03:58:43 +0000 | [diff] [blame] | 113 | |
fpizlo@apple.com | 246741b | 2012-01-22 09:11:49 +0000 | [diff] [blame] | 114 | UNUSED_PARAM(profiledBlock); |
| 115 | UNUSED_PARAM(bytecodeIndex); |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 116 | UNUSED_PARAM(uid); |
commit-queue@webkit.org | e975487 | 2014-02-15 08:30:54 +0000 | [diff] [blame] | 117 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | 4d04f3c | 2015-06-03 20:04:00 +0000 | [diff] [blame] | 118 | if (hasExitSite(locker, profiledBlock, bytecodeIndex)) |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 119 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 120 | |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 121 | StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex)); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 122 | PutByIdStatus result = computeForStubInfo( |
| 123 | locker, profiledBlock, stubInfo, uid, |
| 124 | CallLinkStatus::computeExitSiteData(locker, profiledBlock, bytecodeIndex)); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 125 | if (!result) |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 126 | return computeFromLLInt(profiledBlock, bytecodeIndex, uid); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 127 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 128 | return result; |
| 129 | #else // ENABLE(JIT) |
| 130 | UNUSED_PARAM(map); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 131 | return PutByIdStatus(NoInformation); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 132 | #endif // ENABLE(JIT) |
| 133 | } |
| 134 | |
| 135 | #if ENABLE(JIT) |
utatane.tea@gmail.com | cb7ea56 | 2015-08-20 20:18:45 +0000 | [diff] [blame] | 136 | PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker& locker, CodeBlock* baselineBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin, UniquedStringImpl* uid) |
| 137 | { |
| 138 | return computeForStubInfo( |
| 139 | locker, baselineBlock, stubInfo, uid, |
| 140 | CallLinkStatus::computeExitSiteData(locker, baselineBlock, codeOrigin.bytecodeIndex)); |
| 141 | } |
| 142 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 143 | PutByIdStatus PutByIdStatus::computeForStubInfo( |
| 144 | const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 145 | UniquedStringImpl* uid, CallLinkStatus::ExitSiteData callExitSiteData) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 146 | { |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 147 | if (!stubInfo || !stubInfo->everConsidered) |
fpizlo@apple.com | 4d04f3c | 2015-06-03 20:04:00 +0000 | [diff] [blame] | 148 | return PutByIdStatus(); |
| 149 | |
| 150 | if (stubInfo->tookSlowPath) |
| 151 | return PutByIdStatus(TakesSlowPath); |
| 152 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 153 | switch (stubInfo->cacheType) { |
| 154 | case CacheType::Unset: |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 155 | // This means that we attempted to cache but failed for some reason. |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 156 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 157 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 158 | case CacheType::PutByIdReplace: { |
oliver@apple.com | b395644 | 2013-07-25 03:58:27 +0000 | [diff] [blame] | 159 | PropertyOffset offset = |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 160 | stubInfo->u.byIdSelf.baseObjectStructure->getConcurrently(uid); |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 161 | if (isValidOffset(offset)) { |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 162 | return PutByIdVariant::replace( |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 163 | stubInfo->u.byIdSelf.baseObjectStructure.get(), offset, InferredType::Top); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 164 | } |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 165 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 166 | } |
| 167 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 168 | case CacheType::Stub: { |
| 169 | PolymorphicAccess* list = stubInfo->u.stub; |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 170 | |
| 171 | PutByIdStatus result; |
| 172 | result.m_state = Simple; |
| 173 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 174 | State slowPathState = TakesSlowPath; |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 175 | for (unsigned i = 0; i < list->size(); ++i) { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 176 | const AccessCase& access = list->at(i); |
| 177 | if (access.doesCalls()) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 178 | slowPathState = MakesCalls; |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | for (unsigned i = 0; i < list->size(); ++i) { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 182 | const AccessCase& access = list->at(i); |
| 183 | if (access.viaProxy()) |
| 184 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 185 | |
| 186 | PutByIdVariant variant; |
| 187 | |
| 188 | switch (access.type()) { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 189 | case AccessCase::Replace: { |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 190 | Structure* structure = access.structure(); |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 191 | PropertyOffset offset = structure->getConcurrently(uid); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 192 | if (!isValidOffset(offset)) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 193 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 194 | variant = PutByIdVariant::replace( |
| 195 | structure, offset, structure->inferredTypeDescriptorFor(uid)); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 196 | break; |
| 197 | } |
| 198 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 199 | case AccessCase::Transition: { |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 200 | PropertyOffset offset = |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 201 | access.newStructure()->getConcurrently(uid); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 202 | if (!isValidOffset(offset)) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 203 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 204 | ObjectPropertyConditionSet conditionSet = access.conditionSet(); |
| 205 | if (!conditionSet.structuresEnsureValidity()) |
| 206 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 207 | variant = PutByIdVariant::transition( |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 208 | access.structure(), access.newStructure(), conditionSet, offset, |
| 209 | access.newStructure()->inferredTypeDescriptorFor(uid)); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 210 | break; |
| 211 | } |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 212 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 213 | case AccessCase::Setter: { |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 214 | Structure* structure = access.structure(); |
| 215 | |
| 216 | ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor( |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 217 | structure, access.conditionSet(), uid); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 218 | |
| 219 | switch (complexGetStatus.kind()) { |
| 220 | case ComplexGetStatus::ShouldSkip: |
| 221 | continue; |
| 222 | |
| 223 | case ComplexGetStatus::TakesSlowPath: |
| 224 | return PutByIdStatus(slowPathState); |
| 225 | |
| 226 | case ComplexGetStatus::Inlineable: { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 227 | CallLinkInfo* callLinkInfo = access.callLinkInfo(); |
| 228 | ASSERT(callLinkInfo); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 229 | std::unique_ptr<CallLinkStatus> callLinkStatus = |
| 230 | std::make_unique<CallLinkStatus>( |
| 231 | CallLinkStatus::computeFor( |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 232 | locker, profiledBlock, *callLinkInfo, callExitSiteData)); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 233 | |
| 234 | variant = PutByIdVariant::setter( |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 235 | structure, complexGetStatus.offset(), complexGetStatus.conditionSet(), |
gyuyoung.kim@samsung.com | 23dff19 | 2014-10-17 09:54:14 +0000 | [diff] [blame] | 236 | WTF::move(callLinkStatus)); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 237 | } } |
| 238 | break; |
| 239 | } |
| 240 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 241 | case AccessCase::CustomSetter: |
oliver@apple.com | 11ce5ff | 2014-03-06 21:27:13 +0000 | [diff] [blame] | 242 | return PutByIdStatus(MakesCalls); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 243 | |
| 244 | default: |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 245 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 246 | } |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 247 | |
| 248 | if (!result.appendVariant(variant)) |
| 249 | return PutByIdStatus(slowPathState); |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 250 | } |
| 251 | |
| 252 | return result; |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 253 | } |
| 254 | |
| 255 | default: |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 256 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 257 | } |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 258 | } |
| 259 | #endif |
| 260 | |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 261 | PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin codeOrigin, UniquedStringImpl* uid) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 262 | { |
commit-queue@webkit.org | e975487 | 2014-02-15 08:30:54 +0000 | [diff] [blame] | 263 | #if ENABLE(DFG_JIT) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 264 | if (dfgBlock) { |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 265 | CallLinkStatus::ExitSiteData exitSiteData; |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 266 | { |
| 267 | ConcurrentJITLocker locker(baselineBlock->m_lock); |
fpizlo@apple.com | c1f69d7 | 2015-06-02 05:39:11 +0000 | [diff] [blame] | 268 | if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex)) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 269 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 270 | exitSiteData = CallLinkStatus::computeExitSiteData( |
fpizlo@apple.com | c1f69d7 | 2015-06-02 05:39:11 +0000 | [diff] [blame] | 271 | locker, baselineBlock, codeOrigin.bytecodeIndex); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 272 | } |
| 273 | |
| 274 | PutByIdStatus result; |
| 275 | { |
| 276 | ConcurrentJITLocker locker(dfgBlock->m_lock); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 277 | result = computeForStubInfo( |
| 278 | locker, dfgBlock, dfgMap.get(codeOrigin), uid, exitSiteData); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 279 | } |
| 280 | |
fpizlo@apple.com | a502abe | 2014-03-30 18:43:41 +0000 | [diff] [blame] | 281 | // We use TakesSlowPath in some cases where the stub was unset. That's weird and |
| 282 | // it would be better not to do that. But it means that we have to defend |
| 283 | // ourselves here. |
| 284 | if (result.isSimple()) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 285 | return result; |
| 286 | } |
| 287 | #else |
| 288 | UNUSED_PARAM(dfgBlock); |
| 289 | UNUSED_PARAM(dfgMap); |
| 290 | #endif |
| 291 | |
| 292 | return computeFor(baselineBlock, baselineMap, codeOrigin.bytecodeIndex, uid); |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 293 | } |
| 294 | |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 295 | PutByIdStatus PutByIdStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, UniquedStringImpl* uid, bool isDirect) |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 296 | { |
utatane.tea@gmail.com | c7c203c | 2015-04-06 12:40:33 +0000 | [diff] [blame] | 297 | if (parseIndex(*uid)) |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 298 | return PutByIdStatus(TakesSlowPath); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 299 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 300 | if (set.isEmpty()) |
| 301 | return PutByIdStatus(); |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 302 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 303 | PutByIdStatus result; |
| 304 | result.m_state = Simple; |
| 305 | for (unsigned i = 0; i < set.size(); ++i) { |
| 306 | Structure* structure = set[i]; |
| 307 | |
| 308 | if (structure->typeInfo().overridesGetOwnPropertySlot() && structure->typeInfo().type() != GlobalObjectType) |
| 309 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 310 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 311 | if (!structure->propertyAccessesAreCacheable()) |
| 312 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 313 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 314 | unsigned attributes; |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 315 | PropertyOffset offset = structure->getConcurrently(uid, attributes); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 316 | if (isValidOffset(offset)) { |
| 317 | if (attributes & CustomAccessor) |
| 318 | return PutByIdStatus(MakesCalls); |
oliver@apple.com | 11ce5ff | 2014-03-06 21:27:13 +0000 | [diff] [blame] | 319 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 320 | if (attributes & (Accessor | ReadOnly)) |
| 321 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 322 | |
| 323 | WatchpointSet* replaceSet = structure->propertyReplacementWatchpointSet(offset); |
| 324 | if (!replaceSet || replaceSet->isStillValid()) { |
| 325 | // When this executes, it'll create, and fire, this replacement watchpoint set. |
| 326 | // That means that this has probably never executed or that something fishy is |
| 327 | // going on. Also, we cannot create or fire the watchpoint set from the concurrent |
| 328 | // JIT thread, so even if we wanted to do this, we'd need to have a lazy thingy. |
| 329 | // So, better leave this alone and take slow path. |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 330 | return PutByIdStatus(TakesSlowPath); |
| 331 | } |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 332 | |
| 333 | PutByIdVariant variant = |
| 334 | PutByIdVariant::replace(structure, offset, structure->inferredTypeDescriptorFor(uid)); |
| 335 | if (!result.appendVariant(variant)) |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 336 | return PutByIdStatus(TakesSlowPath); |
| 337 | continue; |
fpizlo@apple.com | fd016b1 | 2013-03-22 20:51:24 +0000 | [diff] [blame] | 338 | } |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 339 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 340 | // Our hypothesis is that we're doing a transition. Before we prove that this is really |
| 341 | // true, we want to do some sanity checks. |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 342 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 343 | // Don't cache put transitions on dictionaries. |
| 344 | if (structure->isDictionary()) |
| 345 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 346 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 347 | // If the structure corresponds to something that isn't an object, then give up, since |
| 348 | // we don't want to be adding properties to strings. |
utatane.tea@gmail.com | 0bfb74c | 2015-02-24 23:01:58 +0000 | [diff] [blame] | 349 | if (!structure->typeInfo().isObject()) |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 350 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 351 | |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 352 | ObjectPropertyConditionSet conditionSet; |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 353 | if (!isDirect) { |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 354 | conditionSet = generateConditionsForPropertySetterMissConcurrently( |
| 355 | globalObject->vm(), globalObject, structure, uid); |
| 356 | if (!conditionSet.isValid()) |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 357 | return PutByIdStatus(TakesSlowPath); |
| 358 | } |
| 359 | |
| 360 | // We only optimize if there is already a structure that the transition is cached to. |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 361 | Structure* transition = |
| 362 | Structure::addPropertyTransitionToExistingStructureConcurrently(structure, uid, 0, offset); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 363 | if (!transition) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 364 | return PutByIdStatus(TakesSlowPath); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 365 | ASSERT(isValidOffset(offset)); |
| 366 | |
| 367 | bool didAppend = result.appendVariant( |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 368 | PutByIdVariant::transition( |
| 369 | structure, transition, conditionSet, offset, |
| 370 | transition->inferredTypeDescriptorFor(uid))); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 371 | if (!didAppend) |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 372 | return PutByIdStatus(TakesSlowPath); |
| 373 | } |
| 374 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 375 | return result; |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 376 | } |
| 377 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 378 | bool PutByIdStatus::makesCalls() const |
| 379 | { |
| 380 | if (m_state == MakesCalls) |
| 381 | return true; |
| 382 | |
| 383 | if (m_state != Simple) |
| 384 | return false; |
| 385 | |
| 386 | for (unsigned i = m_variants.size(); i--;) { |
| 387 | if (m_variants[i].makesCalls()) |
| 388 | return true; |
| 389 | } |
| 390 | |
| 391 | return false; |
| 392 | } |
| 393 | |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 394 | void PutByIdStatus::dump(PrintStream& out) const |
| 395 | { |
| 396 | switch (m_state) { |
| 397 | case NoInformation: |
| 398 | out.print("(NoInformation)"); |
| 399 | return; |
| 400 | |
| 401 | case Simple: |
| 402 | out.print("(", listDump(m_variants), ")"); |
| 403 | return; |
| 404 | |
| 405 | case TakesSlowPath: |
| 406 | out.print("(TakesSlowPath)"); |
| 407 | return; |
oliver@apple.com | 11ce5ff | 2014-03-06 21:27:13 +0000 | [diff] [blame] | 408 | case MakesCalls: |
| 409 | out.print("(MakesCalls)"); |
| 410 | return; |
fpizlo@apple.com | 4321952 | 2014-02-25 02:02:50 +0000 | [diff] [blame] | 411 | } |
| 412 | |
| 413 | RELEASE_ASSERT_NOT_REACHED(); |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 414 | } |
| 415 | |
fpizlo@apple.com | 1f8917f | 2012-01-22 01:36:23 +0000 | [diff] [blame] | 416 | } // namespace JSC |
| 417 | |