fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 1 | /* |
fpizlo@apple.com | 80d0656 | 2016-04-05 19:58:04 +0000 | [diff] [blame] | 2 | * Copyright (C) 2011-2016 Apple Inc. All rights reserved. |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +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" |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 27 | #include "Repatch.h" |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 28 | |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 29 | #if ENABLE(JIT) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 30 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 31 | #include "BinarySwitch.h" |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 32 | #include "CCallHelpers.h" |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 33 | #include "CallFrameShuffler.h" |
mhahnenberg@apple.com | 2ceb9d7 | 2013-12-20 00:49:58 +0000 | [diff] [blame] | 34 | #include "DFGOperations.h" |
| 35 | #include "DFGSpeculativeJIT.h" |
utatane.tea@gmail.com | 9d300ae | 2016-10-04 19:34:52 +0000 | [diff] [blame] | 36 | #include "DOMJITGetterSetter.h" |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 37 | #include "DirectArguments.h" |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 38 | #include "FTLThunks.h" |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 39 | #include "GCAwareJITStubRoutine.h" |
fpizlo@apple.com | bf7daac | 2014-03-25 22:38:52 +0000 | [diff] [blame] | 40 | #include "GetterSetter.h" |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 41 | #include "ICStats.h" |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 42 | #include "InlineAccess.h" |
mhahnenberg@apple.com | b6f8519 | 2014-02-27 01:27:18 +0000 | [diff] [blame] | 43 | #include "JIT.h" |
| 44 | #include "JITInlines.h" |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 45 | #include "LinkBuffer.h" |
fpizlo@apple.com | fb7eff2 | 2014-02-11 01:45:50 +0000 | [diff] [blame] | 46 | #include "JSCInlines.h" |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 47 | #include "PolymorphicAccess.h" |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 48 | #include "ScopedArguments.h" |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 49 | #include "ScratchRegisterAllocator.h" |
mhahnenberg@apple.com | 3ddd7ac | 2014-01-10 02:28:27 +0000 | [diff] [blame] | 50 | #include "StackAlignment.h" |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 51 | #include "StructureRareDataInlines.h" |
rniwa@webkit.org | 1293295 | 2013-12-16 05:56:25 +0000 | [diff] [blame] | 52 | #include "StructureStubClearingWatchpoint.h" |
ossy@webkit.org | ff7c180 | 2016-05-10 16:34:26 +0000 | [diff] [blame] | 53 | #include "StructureStubInfo.h" |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 54 | #include "ThunkGenerators.h" |
fpizlo@apple.com | b1e1c2d | 2015-05-05 20:42:44 +0000 | [diff] [blame] | 55 | #include <wtf/CommaPrinter.h> |
ossy@webkit.org | 95b5d17 | 2015-02-09 18:07:46 +0000 | [diff] [blame] | 56 | #include <wtf/ListDump.h> |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 57 | #include <wtf/StringPrintStream.h> |
| 58 | |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 59 | namespace JSC { |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 60 | |
fpizlo@apple.com | 13d4136 | 2015-09-03 19:41:42 +0000 | [diff] [blame] | 61 | static FunctionPtr readCallTarget(CodeBlock* codeBlock, CodeLocationCall call) |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 62 | { |
| 63 | FunctionPtr result = MacroAssembler::readCallTarget(call); |
| 64 | #if ENABLE(FTL_JIT) |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 65 | if (codeBlock->jitType() == JITCode::FTLJIT) { |
| 66 | return FunctionPtr(codeBlock->vm()->ftlThunks->keyForSlowPathCallThunk( |
| 67 | MacroAssemblerCodePtr::createFromExecutableAddress( |
| 68 | result.executableAddress())).callTarget()); |
| 69 | } |
| 70 | #else |
fpizlo@apple.com | 13d4136 | 2015-09-03 19:41:42 +0000 | [diff] [blame] | 71 | UNUSED_PARAM(codeBlock); |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 72 | #endif // ENABLE(FTL_JIT) |
| 73 | return result; |
| 74 | } |
| 75 | |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 76 | void ftlThunkAwareRepatchCall(CodeBlock* codeBlock, CodeLocationCall call, FunctionPtr newCalleeFunction) |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 77 | { |
| 78 | #if ENABLE(FTL_JIT) |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 79 | if (codeBlock->jitType() == JITCode::FTLJIT) { |
| 80 | VM& vm = *codeBlock->vm(); |
| 81 | FTL::Thunks& thunks = *vm.ftlThunks; |
| 82 | FTL::SlowPathCallKey key = thunks.keyForSlowPathCallThunk( |
| 83 | MacroAssemblerCodePtr::createFromExecutableAddress( |
| 84 | MacroAssembler::readCallTarget(call).executableAddress())); |
| 85 | key = key.withCallTarget(newCalleeFunction.executableAddress()); |
| 86 | newCalleeFunction = FunctionPtr( |
| 87 | thunks.getSlowPathCallThunk(vm, key).code().executableAddress()); |
| 88 | } |
fpizlo@apple.com | 13d4136 | 2015-09-03 19:41:42 +0000 | [diff] [blame] | 89 | #else // ENABLE(FTL_JIT) |
| 90 | UNUSED_PARAM(codeBlock); |
fpizlo@apple.com | d2ceb39 | 2013-11-11 07:30:50 +0000 | [diff] [blame] | 91 | #endif // ENABLE(FTL_JIT) |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 92 | MacroAssembler::repatchCall(call, newCalleeFunction); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 93 | } |
| 94 | |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 95 | enum InlineCacheAction { |
| 96 | GiveUpOnCache, |
| 97 | RetryCacheLater, |
| 98 | AttemptToCache |
| 99 | }; |
| 100 | |
| 101 | static InlineCacheAction actionForCell(VM& vm, JSCell* cell) |
| 102 | { |
| 103 | Structure* structure = cell->structure(vm); |
| 104 | |
| 105 | TypeInfo typeInfo = structure->typeInfo(); |
| 106 | if (typeInfo.prohibitsPropertyCaching()) |
| 107 | return GiveUpOnCache; |
| 108 | |
| 109 | if (structure->isUncacheableDictionary()) { |
| 110 | if (structure->hasBeenFlattenedBefore()) |
| 111 | return GiveUpOnCache; |
| 112 | // Flattening could have changed the offset, so return early for another try. |
| 113 | asObject(cell)->flattenDictionaryObject(vm); |
| 114 | return RetryCacheLater; |
| 115 | } |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 116 | |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 117 | if (!structure->propertyAccessesAreCacheable()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 118 | return GiveUpOnCache; |
| 119 | |
| 120 | return AttemptToCache; |
| 121 | } |
| 122 | |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 123 | static bool forceICFailure(ExecState*) |
| 124 | { |
ossy@webkit.org | d832aa4 | 2016-07-15 09:43:33 +0000 | [diff] [blame] | 125 | #if CPU(ARM_TRADITIONAL) |
| 126 | // FIXME: Remove this workaround once the proper fixes are landed. |
| 127 | // [ARM] Disable Inline Caching on ARMv7 traditional until proper fix |
| 128 | // https://bugs.webkit.org/show_bug.cgi?id=159759 |
| 129 | return true; |
| 130 | #else |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 131 | return Options::forceICFailure(); |
ossy@webkit.org | d832aa4 | 2016-07-15 09:43:33 +0000 | [diff] [blame] | 132 | #endif |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 133 | } |
| 134 | |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 135 | inline J_JITOperation_ESsiJI appropriateOptimizingGetByIdFunction(GetByIDKind kind) |
| 136 | { |
| 137 | if (kind == GetByIDKind::Normal) |
| 138 | return operationGetByIdOptimize; |
| 139 | return operationTryGetByIdOptimize; |
| 140 | } |
| 141 | |
| 142 | inline J_JITOperation_ESsiJI appropriateGenericGetByIdFunction(GetByIDKind kind) |
| 143 | { |
| 144 | if (kind == GetByIDKind::Normal) |
| 145 | return operationGetById; |
| 146 | return operationTryGetById; |
| 147 | } |
| 148 | |
| 149 | static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 150 | { |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 151 | if (forceICFailure(exec)) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 152 | return GiveUpOnCache; |
fpizlo@apple.com | a502abe | 2014-03-30 18:43:41 +0000 | [diff] [blame] | 153 | |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 154 | // FIXME: Cache property access for immediates. |
| 155 | if (!baseValue.isCell()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 156 | return GiveUpOnCache; |
akling@apple.com | 1c7a38a | 2014-11-11 03:10:13 +0000 | [diff] [blame] | 157 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 158 | CodeBlock* codeBlock = exec->codeBlock(); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 159 | VM& vm = exec->vm(); |
akling@apple.com | 1c7a38a | 2014-11-11 03:10:13 +0000 | [diff] [blame] | 160 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 161 | std::unique_ptr<AccessCase> newCase; |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 162 | |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 163 | if (propertyName == vm.propertyNames->length) { |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 164 | if (isJSArray(baseValue)) { |
| 165 | if (stubInfo.cacheType == CacheType::Unset |
| 166 | && slot.slotBase() == baseValue |
| 167 | && InlineAccess::isCacheableArrayLength(stubInfo, jsCast<JSArray*>(baseValue))) { |
| 168 | |
| 169 | bool generatedCodeInline = InlineAccess::generateArrayLength(*codeBlock->vm(), stubInfo, jsCast<JSArray*>(baseValue)); |
| 170 | if (generatedCodeInline) { |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 171 | ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingGetByIdFunction(kind)); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 172 | stubInfo.initArrayLength(); |
| 173 | return RetryCacheLater; |
| 174 | } |
| 175 | } |
| 176 | |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 177 | newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ArrayLength); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 178 | } else if (isJSString(baseValue)) |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 179 | newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength); |
| 180 | else if (DirectArguments* arguments = jsDynamicCast<DirectArguments*>(baseValue)) { |
| 181 | // If there were overrides, then we can handle this as a normal property load! Guarding |
| 182 | // this with such a check enables us to add an IC case for that load if needed. |
| 183 | if (!arguments->overrodeThings()) |
| 184 | newCase = AccessCase::getLength(vm, codeBlock, AccessCase::DirectArgumentsLength); |
| 185 | } else if (ScopedArguments* arguments = jsDynamicCast<ScopedArguments*>(baseValue)) { |
| 186 | // Ditto. |
| 187 | if (!arguments->overrodeThings()) |
| 188 | newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ScopedArgumentsLength); |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | if (!newCase) { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 193 | if (!slot.isCacheable() && !slot.isUnset()) |
| 194 | return GiveUpOnCache; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 195 | |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 196 | ObjectPropertyConditionSet conditionSet; |
| 197 | JSCell* baseCell = baseValue.asCell(); |
| 198 | Structure* structure = baseCell->structure(vm); |
| 199 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 200 | bool loadTargetFromProxy = false; |
| 201 | if (baseCell->type() == PureForwardingProxyType) { |
| 202 | baseValue = jsCast<JSProxy*>(baseCell)->target(); |
| 203 | baseCell = baseValue.asCell(); |
| 204 | structure = baseCell->structure(vm); |
| 205 | loadTargetFromProxy = true; |
| 206 | } |
| 207 | |
| 208 | InlineCacheAction action = actionForCell(vm, baseCell); |
| 209 | if (action != AttemptToCache) |
| 210 | return action; |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 211 | |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 212 | // Optimize self access. |
| 213 | if (stubInfo.cacheType == CacheType::Unset |
| 214 | && slot.isCacheableValue() |
| 215 | && slot.slotBase() == baseValue |
| 216 | && !slot.watchpointSet() |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 217 | && !structure->needImpurePropertyWatchpoint() |
| 218 | && !loadTargetFromProxy) { |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 219 | |
| 220 | bool generatedCodeInline = InlineAccess::generateSelfPropertyAccess(*codeBlock->vm(), stubInfo, structure, slot.cachedOffset()); |
| 221 | if (generatedCodeInline) { |
| 222 | LOG_IC((ICEvent::GetByIdSelfPatch, structure->classInfo(), propertyName)); |
| 223 | structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset()); |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 224 | ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingGetByIdFunction(kind)); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 225 | stubInfo.initGetByIdSelf(codeBlock, structure, slot.cachedOffset()); |
| 226 | return RetryCacheLater; |
| 227 | } |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 228 | } |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 229 | |
| 230 | PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset(); |
keith_miller@apple.com | 59bba5d | 2015-10-16 22:18:42 +0000 | [diff] [blame] | 231 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 232 | if (slot.isUnset() || slot.slotBase() != baseValue) { |
ggaren@apple.com | f7c06fd | 2016-06-01 19:32:34 +0000 | [diff] [blame] | 233 | if (structure->typeInfo().prohibitsPropertyCaching()) |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 234 | return GiveUpOnCache; |
ggaren@apple.com | f7c06fd | 2016-06-01 19:32:34 +0000 | [diff] [blame] | 235 | |
| 236 | if (structure->isDictionary()) { |
| 237 | if (structure->hasBeenFlattenedBefore()) |
| 238 | return GiveUpOnCache; |
| 239 | structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseCell)); |
| 240 | } |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 241 | |
cdumez@apple.com | 431c102 | 2015-11-20 20:45:12 +0000 | [diff] [blame] | 242 | if (slot.isUnset() && structure->typeInfo().getOwnPropertySlotIsImpureForPropertyAbsence()) |
| 243 | return GiveUpOnCache; |
| 244 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 245 | if (slot.isUnset()) { |
| 246 | conditionSet = generateConditionsForPropertyMiss( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 247 | vm, codeBlock, exec, structure, propertyName.impl()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 248 | } else { |
| 249 | conditionSet = generateConditionsForPrototypePropertyHit( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 250 | vm, codeBlock, exec, structure, slot.slotBase(), |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 251 | propertyName.impl()); |
| 252 | } |
| 253 | |
| 254 | if (!conditionSet.isValid()) |
| 255 | return GiveUpOnCache; |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 256 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 257 | offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset(); |
| 258 | } |
| 259 | |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 260 | JSFunction* getter = nullptr; |
| 261 | if (slot.isCacheableGetter()) |
| 262 | getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 263 | |
utatane.tea@gmail.com | 9d300ae | 2016-10-04 19:34:52 +0000 | [diff] [blame] | 264 | DOMJIT::GetterSetter* domJIT = nullptr; |
| 265 | if (slot.isCacheableCustom() && slot.domJIT()) |
| 266 | domJIT = slot.domJIT(); |
| 267 | |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 268 | if (kind == GetByIDKind::Pure) { |
| 269 | AccessCase::AccessType type; |
| 270 | if (slot.isCacheableValue()) |
| 271 | type = AccessCase::Load; |
| 272 | else if (slot.isUnset()) |
| 273 | type = AccessCase::Miss; |
| 274 | else if (slot.isCacheableGetter()) |
| 275 | type = AccessCase::GetGetter; |
| 276 | else |
| 277 | RELEASE_ASSERT_NOT_REACHED(); |
| 278 | |
| 279 | newCase = AccessCase::tryGet(vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet()); |
| 280 | } else if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure)) |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 281 | newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet); |
| 282 | else { |
| 283 | AccessCase::AccessType type; |
| 284 | if (slot.isCacheableValue()) |
| 285 | type = AccessCase::Load; |
| 286 | else if (slot.isUnset()) |
| 287 | type = AccessCase::Miss; |
| 288 | else if (slot.isCacheableGetter()) |
| 289 | type = AccessCase::Getter; |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 290 | else if (slot.attributes() & CustomAccessor) |
| 291 | type = AccessCase::CustomAccessorGetter; |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 292 | else |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 293 | type = AccessCase::CustomValueGetter; |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 294 | |
| 295 | newCase = AccessCase::get( |
| 296 | vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, |
| 297 | slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr, |
utatane.tea@gmail.com | 9d300ae | 2016-10-04 19:34:52 +0000 | [diff] [blame] | 298 | slot.isCacheableCustom() ? slot.slotBase() : nullptr, |
| 299 | domJIT); |
keith_miller@apple.com | 5a877dd | 2015-12-23 23:45:17 +0000 | [diff] [blame] | 300 | } |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 301 | } |
oliver@apple.com | 22b40a6 | 2013-12-17 00:01:01 +0000 | [diff] [blame] | 302 | |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 303 | LOG_IC((ICEvent::GetByIdAddAccessCase, baseValue.classInfoOrNull(), propertyName)); |
| 304 | |
fpizlo@apple.com | 80d0656 | 2016-04-05 19:58:04 +0000 | [diff] [blame] | 305 | AccessGenerationResult result = stubInfo.addAccessCase(codeBlock, propertyName, WTFMove(newCase)); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 306 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 307 | if (result.generatedSomeCode()) { |
| 308 | LOG_IC((ICEvent::GetByIdReplaceWithJump, baseValue.classInfoOrNull(), propertyName)); |
| 309 | |
| 310 | RELEASE_ASSERT(result.code()); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 311 | InlineAccess::rewireStubAsJump(exec->vm(), stubInfo, CodeLocationLabel(result.code())); |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 312 | } |
fpizlo@apple.com | 80d0656 | 2016-04-05 19:58:04 +0000 | [diff] [blame] | 313 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 314 | return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 315 | } |
| 316 | |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 317 | void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 318 | { |
fpizlo@apple.com | 57aea1c | 2016-04-11 18:20:59 +0000 | [diff] [blame] | 319 | SuperSamplerScope superSamplerScope(false); |
mhahnenberg@apple.com | efd0d51 | 2013-10-16 23:47:45 +0000 | [diff] [blame] | 320 | GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); |
fpizlo@apple.com | 1cfa0a9 | 2013-10-16 02:19:20 +0000 | [diff] [blame] | 321 | |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 322 | if (tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo, kind) == GiveUpOnCache) |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 323 | ftlThunkAwareRepatchCall(exec->codeBlock(), stubInfo.slowPathCallLocation(), appropriateGenericGetByIdFunction(kind)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 324 | } |
| 325 | |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 326 | static V_JITOperation_ESsiJJI appropriateGenericPutByIdFunction(const PutPropertySlot &slot, PutKind putKind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 327 | { |
| 328 | if (slot.isStrictMode()) { |
| 329 | if (putKind == Direct) |
| 330 | return operationPutByIdDirectStrict; |
| 331 | return operationPutByIdStrict; |
| 332 | } |
| 333 | if (putKind == Direct) |
| 334 | return operationPutByIdDirectNonStrict; |
| 335 | return operationPutByIdNonStrict; |
| 336 | } |
| 337 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 338 | static V_JITOperation_ESsiJJI appropriateOptimizingPutByIdFunction(const PutPropertySlot &slot, PutKind putKind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 339 | { |
| 340 | if (slot.isStrictMode()) { |
| 341 | if (putKind == Direct) |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 342 | return operationPutByIdDirectStrictOptimize; |
| 343 | return operationPutByIdStrictOptimize; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 344 | } |
| 345 | if (putKind == Direct) |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 346 | return operationPutByIdDirectNonStrictOptimize; |
| 347 | return operationPutByIdNonStrictOptimize; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 348 | } |
| 349 | |
mmirman@apple.com | 21ee777 | 2015-01-14 21:00:52 +0000 | [diff] [blame] | 350 | static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 351 | { |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 352 | if (forceICFailure(exec)) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 353 | return GiveUpOnCache; |
fpizlo@apple.com | a502abe | 2014-03-30 18:43:41 +0000 | [diff] [blame] | 354 | |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 355 | CodeBlock* codeBlock = exec->codeBlock(); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 356 | VM& vm = exec->vm(); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 357 | |
| 358 | if (!baseValue.isCell()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 359 | return GiveUpOnCache; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 360 | |
fpizlo@apple.com | 1d55d36 | 2014-04-08 19:39:55 +0000 | [diff] [blame] | 361 | if (!slot.isCacheablePut() && !slot.isCacheableCustom() && !slot.isCacheableSetter()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 362 | return GiveUpOnCache; |
mmirman@apple.com | 21ee777 | 2015-01-14 21:00:52 +0000 | [diff] [blame] | 363 | |
fpizlo@apple.com | 6650f78 | 2013-10-16 23:49:53 +0000 | [diff] [blame] | 364 | if (!structure->propertyAccessesAreCacheable()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 365 | return GiveUpOnCache; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 366 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 367 | std::unique_ptr<AccessCase> newCase; |
mmirman@apple.com | 21ee777 | 2015-01-14 21:00:52 +0000 | [diff] [blame] | 368 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 369 | if (slot.base() == baseValue && slot.isCacheablePut()) { |
| 370 | if (slot.type() == PutPropertySlot::ExistingProperty) { |
| 371 | structure->didCachePropertyReplacement(vm, slot.cachedOffset()); |
| 372 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 373 | if (stubInfo.cacheType == CacheType::Unset |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 374 | && InlineAccess::canGenerateSelfPropertyReplace(stubInfo, slot.cachedOffset()) |
fpizlo@apple.com | 1283577 | 2015-09-21 20:49:04 +0000 | [diff] [blame] | 375 | && !structure->needImpurePropertyWatchpoint() |
| 376 | && !structure->inferredTypeFor(ident.impl())) { |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 377 | |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 378 | bool generatedCodeInline = InlineAccess::generateSelfPropertyReplace(vm, stubInfo, structure, slot.cachedOffset()); |
| 379 | if (generatedCodeInline) { |
| 380 | LOG_IC((ICEvent::PutByIdSelfPatch, structure->classInfo(), ident)); |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 381 | ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingPutByIdFunction(slot, putKind)); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 382 | stubInfo.initPutByIdReplace(codeBlock, structure, slot.cachedOffset()); |
| 383 | return RetryCacheLater; |
| 384 | } |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 385 | } |
| 386 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 387 | newCase = AccessCase::replace(vm, codeBlock, structure, slot.cachedOffset()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 388 | } else { |
| 389 | ASSERT(slot.type() == PutPropertySlot::NewProperty); |
| 390 | |
ggaren@apple.com | f7c06fd | 2016-06-01 19:32:34 +0000 | [diff] [blame] | 391 | if (!structure->isObject()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 392 | return GiveUpOnCache; |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 393 | |
ggaren@apple.com | f7c06fd | 2016-06-01 19:32:34 +0000 | [diff] [blame] | 394 | if (structure->isDictionary()) { |
| 395 | if (structure->hasBeenFlattenedBefore()) |
| 396 | return GiveUpOnCache; |
| 397 | structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseValue)); |
| 398 | } |
| 399 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 400 | PropertyOffset offset; |
| 401 | Structure* newStructure = |
| 402 | Structure::addPropertyTransitionToExistingStructureConcurrently( |
| 403 | structure, ident.impl(), 0, offset); |
| 404 | if (!newStructure || !newStructure->propertyAccessesAreCacheable()) |
| 405 | return GiveUpOnCache; |
| 406 | |
| 407 | ASSERT(newStructure->previousID() == structure); |
| 408 | ASSERT(!newStructure->isDictionary()); |
| 409 | ASSERT(newStructure->isObject()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 410 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 411 | ObjectPropertyConditionSet conditionSet; |
| 412 | if (putKind == NotDirect) { |
| 413 | conditionSet = |
| 414 | generateConditionsForPropertySetterMiss( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 415 | vm, codeBlock, exec, newStructure, ident.impl()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 416 | if (!conditionSet.isValid()) |
| 417 | return GiveUpOnCache; |
| 418 | } |
| 419 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 420 | newCase = AccessCase::transition(vm, codeBlock, structure, newStructure, offset, conditionSet); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 421 | } |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 422 | } else if (slot.isCacheableCustom() || slot.isCacheableSetter()) { |
| 423 | if (slot.isCacheableCustom()) { |
| 424 | ObjectPropertyConditionSet conditionSet; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 425 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 426 | if (slot.base() != baseValue) { |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 427 | conditionSet = |
| 428 | generateConditionsForPrototypePropertyHitCustom( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 429 | vm, codeBlock, exec, structure, slot.base(), ident.impl()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 430 | if (!conditionSet.isValid()) |
| 431 | return GiveUpOnCache; |
| 432 | } |
| 433 | |
| 434 | newCase = AccessCase::setter( |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 435 | vm, codeBlock, slot.isCustomAccessor() ? AccessCase::CustomAccessorSetter : AccessCase::CustomValueSetter, structure, invalidOffset, conditionSet, |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 436 | slot.customSetter(), slot.base()); |
| 437 | } else { |
| 438 | ObjectPropertyConditionSet conditionSet; |
| 439 | PropertyOffset offset; |
| 440 | |
| 441 | if (slot.base() != baseValue) { |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 442 | conditionSet = |
| 443 | generateConditionsForPrototypePropertyHit( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 444 | vm, codeBlock, exec, structure, slot.base(), ident.impl()); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 445 | if (!conditionSet.isValid()) |
| 446 | return GiveUpOnCache; |
| 447 | offset = conditionSet.slotBaseCondition().offset(); |
| 448 | } else |
| 449 | offset = slot.cachedOffset(); |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 450 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 451 | newCase = AccessCase::setter( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 452 | vm, codeBlock, AccessCase::Setter, structure, offset, conditionSet); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 453 | } |
oliver@apple.com | 11ce5ff | 2014-03-06 21:27:13 +0000 | [diff] [blame] | 454 | } |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 455 | |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 456 | LOG_IC((ICEvent::PutByIdAddAccessCase, structure->classInfo(), ident)); |
| 457 | |
fpizlo@apple.com | 80d0656 | 2016-04-05 19:58:04 +0000 | [diff] [blame] | 458 | AccessGenerationResult result = stubInfo.addAccessCase(codeBlock, ident, WTFMove(newCase)); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 459 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 460 | if (result.generatedSomeCode()) { |
| 461 | LOG_IC((ICEvent::PutByIdReplaceWithJump, structure->classInfo(), ident)); |
| 462 | |
| 463 | RELEASE_ASSERT(result.code()); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 464 | |
| 465 | InlineAccess::rewireStubAsJump(vm, stubInfo, CodeLocationLabel(result.code())); |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 466 | } |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 467 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 468 | return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 469 | } |
| 470 | |
mmirman@apple.com | 21ee777 | 2015-01-14 21:00:52 +0000 | [diff] [blame] | 471 | void repatchPutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 472 | { |
fpizlo@apple.com | 57aea1c | 2016-04-11 18:20:59 +0000 | [diff] [blame] | 473 | SuperSamplerScope superSamplerScope(false); |
mhahnenberg@apple.com | efd0d51 | 2013-10-16 23:47:45 +0000 | [diff] [blame] | 474 | GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); |
fpizlo@apple.com | d2d4f0a | 2013-10-15 00:05:45 +0000 | [diff] [blame] | 475 | |
mmirman@apple.com | 21ee777 | 2015-01-14 21:00:52 +0000 | [diff] [blame] | 476 | if (tryCachePutByID(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache) |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 477 | ftlThunkAwareRepatchCall(exec->codeBlock(), stubInfo.slowPathCallLocation(), appropriateGenericPutByIdFunction(slot, putKind)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 478 | } |
| 479 | |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 480 | static InlineCacheAction tryRepatchIn( |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 481 | ExecState* exec, JSCell* base, const Identifier& ident, bool wasFound, |
| 482 | const PropertySlot& slot, StructureStubInfo& stubInfo) |
| 483 | { |
fpizlo@apple.com | 547fbff | 2015-09-12 20:52:26 +0000 | [diff] [blame] | 484 | if (forceICFailure(exec)) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 485 | return GiveUpOnCache; |
fpizlo@apple.com | a502abe | 2014-03-30 18:43:41 +0000 | [diff] [blame] | 486 | |
cdumez@apple.com | 431c102 | 2015-11-20 20:45:12 +0000 | [diff] [blame] | 487 | if (!base->structure()->propertyAccessesAreCacheable() || (!wasFound && !base->structure()->propertyAccessesAreCacheableForAbsence())) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 488 | return GiveUpOnCache; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 489 | |
| 490 | if (wasFound) { |
| 491 | if (!slot.isCacheable()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 492 | return GiveUpOnCache; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 493 | } |
| 494 | |
| 495 | CodeBlock* codeBlock = exec->codeBlock(); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 496 | VM& vm = exec->vm(); |
| 497 | Structure* structure = base->structure(vm); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 498 | |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 499 | ObjectPropertyConditionSet conditionSet; |
| 500 | if (wasFound) { |
| 501 | if (slot.slotBase() != base) { |
| 502 | conditionSet = generateConditionsForPrototypePropertyHit( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 503 | vm, codeBlock, exec, structure, slot.slotBase(), ident.impl()); |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 504 | } |
| 505 | } else { |
| 506 | conditionSet = generateConditionsForPropertyMiss( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 507 | vm, codeBlock, exec, structure, ident.impl()); |
fpizlo@apple.com | 6b62eaf | 2015-08-03 23:13:56 +0000 | [diff] [blame] | 508 | } |
| 509 | if (!conditionSet.isValid()) |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 510 | return GiveUpOnCache; |
rniwa@webkit.org | 1293295 | 2013-12-16 05:56:25 +0000 | [diff] [blame] | 511 | |
fpizlo@apple.com | f0e9c5d | 2016-04-08 19:37:04 +0000 | [diff] [blame] | 512 | LOG_IC((ICEvent::InAddAccessCase, structure->classInfo(), ident)); |
| 513 | |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 514 | std::unique_ptr<AccessCase> newCase = AccessCase::in( |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 515 | vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet); |
rniwa@webkit.org | 1293295 | 2013-12-16 05:56:25 +0000 | [diff] [blame] | 516 | |
fpizlo@apple.com | 80d0656 | 2016-04-05 19:58:04 +0000 | [diff] [blame] | 517 | AccessGenerationResult result = stubInfo.addAccessCase(codeBlock, ident, WTFMove(newCase)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 518 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 519 | if (result.generatedSomeCode()) { |
| 520 | LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident)); |
| 521 | |
| 522 | RELEASE_ASSERT(result.code()); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 523 | |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 524 | MacroAssembler::repatchJump( |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 525 | stubInfo.patchableJumpForIn(), |
fpizlo@apple.com | 6e1a6d4 | 2016-04-12 20:06:26 +0000 | [diff] [blame] | 526 | CodeLocationLabel(result.code())); |
| 527 | } |
| 528 | |
| 529 | return result.shouldGiveUpNow() ? GiveUpOnCache : RetryCacheLater; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 530 | } |
| 531 | |
| 532 | void repatchIn( |
| 533 | ExecState* exec, JSCell* base, const Identifier& ident, bool wasFound, |
| 534 | const PropertySlot& slot, StructureStubInfo& stubInfo) |
| 535 | { |
fpizlo@apple.com | 57aea1c | 2016-04-11 18:20:59 +0000 | [diff] [blame] | 536 | SuperSamplerScope superSamplerScope(false); |
mhahnenberg@apple.com | 304c25df | 2014-06-11 22:55:34 +0000 | [diff] [blame] | 537 | if (tryRepatchIn(exec, base, ident, wasFound, slot, stubInfo) == GiveUpOnCache) |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 538 | ftlThunkAwareRepatchCall(exec->codeBlock(), stubInfo.slowPathCallLocation(), operationIn); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 539 | } |
| 540 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 541 | static void linkSlowFor(VM*, CallLinkInfo& callLinkInfo, MacroAssemblerCodeRef codeRef) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 542 | { |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 543 | MacroAssembler::repatchNearCall(callLinkInfo.callReturnLocation(), CodeLocationLabel(codeRef.code())); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 544 | } |
| 545 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 546 | static void linkSlowFor(VM* vm, CallLinkInfo& callLinkInfo, ThunkGenerator generator) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 547 | { |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 548 | linkSlowFor(vm, callLinkInfo, vm->getCTIStub(generator)); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 549 | } |
| 550 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 551 | static void linkSlowFor(VM* vm, CallLinkInfo& callLinkInfo) |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 552 | { |
| 553 | MacroAssemblerCodeRef virtualThunk = virtualThunkFor(vm, callLinkInfo); |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 554 | linkSlowFor(vm, callLinkInfo, virtualThunk); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 555 | callLinkInfo.setSlowStub(createJITStubRoutine(virtualThunk, *vm, nullptr, true)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 556 | } |
| 557 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 558 | void linkFor( |
| 559 | ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 560 | JSFunction* callee, MacroAssemblerCodePtr codePtr) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 561 | { |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 562 | ASSERT(!callLinkInfo.stub()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 563 | |
fpizlo@apple.com | 8e88c8a | 2014-02-21 19:48:25 +0000 | [diff] [blame] | 564 | CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); |
| 565 | |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 566 | VM* vm = callerCodeBlock->vm(); |
| 567 | |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 568 | ASSERT(!callLinkInfo.isLinked()); |
fpizlo@apple.com | 636c302 | 2016-10-12 16:56:34 +0000 | [diff] [blame] | 569 | callLinkInfo.setCallee(exec->callerFrame()->vm(), callerCodeBlock, callee); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 570 | callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock, callee); |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 571 | if (shouldDumpDisassemblyFor(callerCodeBlock)) |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 572 | dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n"); |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 573 | MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), CodeLocationLabel(codePtr)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 574 | |
| 575 | if (calleeCodeBlock) |
| 576 | calleeCodeBlock->linkIncomingCall(exec->callerFrame(), &callLinkInfo); |
| 577 | |
fpizlo@apple.com | cfb280c | 2015-09-08 17:25:28 +0000 | [diff] [blame] | 578 | if (callLinkInfo.specializationKind() == CodeForCall && callLinkInfo.allowStubs()) { |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 579 | linkSlowFor(vm, callLinkInfo, linkPolymorphicCallThunkGenerator); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 580 | return; |
| 581 | } |
| 582 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 583 | linkSlowFor(vm, callLinkInfo); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 584 | } |
| 585 | |
fpizlo@apple.com | f0b30cb | 2016-10-18 18:30:05 +0000 | [diff] [blame] | 586 | void linkDirectFor( |
| 587 | ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, |
| 588 | MacroAssemblerCodePtr codePtr) |
| 589 | { |
| 590 | ASSERT(!callLinkInfo.stub()); |
| 591 | |
| 592 | CodeBlock* callerCodeBlock = exec->codeBlock(); |
| 593 | |
| 594 | VM* vm = callerCodeBlock->vm(); |
| 595 | |
| 596 | ASSERT(!callLinkInfo.isLinked()); |
| 597 | callLinkInfo.setCodeBlock(*vm, callerCodeBlock, jsCast<FunctionCodeBlock*>(calleeCodeBlock)); |
| 598 | if (shouldDumpDisassemblyFor(callerCodeBlock)) |
| 599 | dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n"); |
| 600 | if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall) |
| 601 | MacroAssembler::repatchJumpToNop(callLinkInfo.patchableJump()); |
| 602 | MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), CodeLocationLabel(codePtr)); |
| 603 | |
| 604 | if (calleeCodeBlock) |
| 605 | calleeCodeBlock->linkIncomingCall(exec, &callLinkInfo); |
| 606 | } |
| 607 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 608 | void linkSlowFor( |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 609 | ExecState* exec, CallLinkInfo& callLinkInfo) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 610 | { |
| 611 | CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); |
| 612 | VM* vm = callerCodeBlock->vm(); |
| 613 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 614 | linkSlowFor(vm, callLinkInfo); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 615 | } |
| 616 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 617 | static void revertCall(VM* vm, CallLinkInfo& callLinkInfo, MacroAssemblerCodeRef codeRef) |
fpizlo@apple.com | 4569a3e8 | 2015-01-29 20:33:45 +0000 | [diff] [blame] | 618 | { |
fpizlo@apple.com | f0b30cb | 2016-10-18 18:30:05 +0000 | [diff] [blame] | 619 | if (callLinkInfo.isDirect()) { |
| 620 | callLinkInfo.clearCodeBlock(); |
| 621 | if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall) |
| 622 | MacroAssembler::repatchJump(callLinkInfo.patchableJump(), callLinkInfo.slowPathStart()); |
| 623 | else |
| 624 | MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), callLinkInfo.slowPathStart()); |
| 625 | } else { |
| 626 | MacroAssembler::revertJumpReplacementToBranchPtrWithPatch( |
| 627 | MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()), |
| 628 | static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0); |
| 629 | linkSlowFor(vm, callLinkInfo, codeRef); |
| 630 | callLinkInfo.clearCallee(); |
| 631 | } |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 632 | callLinkInfo.clearSeen(); |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 633 | callLinkInfo.clearStub(); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 634 | callLinkInfo.clearSlowStub(); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 635 | if (callLinkInfo.isOnList()) |
| 636 | callLinkInfo.remove(); |
| 637 | } |
| 638 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 639 | void unlinkFor(VM& vm, CallLinkInfo& callLinkInfo) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 640 | { |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 641 | if (Options::dumpDisassembly()) |
fpizlo@apple.com | f0b30cb | 2016-10-18 18:30:05 +0000 | [diff] [blame] | 642 | dataLog("Unlinking call at ", callLinkInfo.hotPathOther(), "\n"); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 643 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 644 | revertCall(&vm, callLinkInfo, vm.getCTIStub(linkCallThunkGenerator)); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 645 | } |
| 646 | |
| 647 | void linkVirtualFor( |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 648 | ExecState* exec, CallLinkInfo& callLinkInfo) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 649 | { |
fpizlo@apple.com | 4569a3e8 | 2015-01-29 20:33:45 +0000 | [diff] [blame] | 650 | CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); |
| 651 | VM* vm = callerCodeBlock->vm(); |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 652 | |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 653 | if (shouldDumpDisassemblyFor(callerCodeBlock)) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 654 | dataLog("Linking virtual call at ", *callerCodeBlock, " ", exec->callerFrame()->codeOrigin(), "\n"); |
| 655 | |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 656 | MacroAssemblerCodeRef virtualThunk = virtualThunkFor(vm, callLinkInfo); |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 657 | revertCall(vm, callLinkInfo, virtualThunk); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 658 | callLinkInfo.setSlowStub(createJITStubRoutine(virtualThunk, *vm, nullptr, true)); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 659 | } |
| 660 | |
| 661 | namespace { |
| 662 | struct CallToCodePtr { |
| 663 | CCallHelpers::Call call; |
| 664 | MacroAssemblerCodePtr codePtr; |
| 665 | }; |
| 666 | } // annonymous namespace |
| 667 | |
| 668 | void linkPolymorphicCall( |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 669 | ExecState* exec, CallLinkInfo& callLinkInfo, CallVariant newVariant) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 670 | { |
fpizlo@apple.com | cfb280c | 2015-09-08 17:25:28 +0000 | [diff] [blame] | 671 | RELEASE_ASSERT(callLinkInfo.allowStubs()); |
| 672 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 673 | // Currently we can't do anything for non-function callees. |
| 674 | // https://bugs.webkit.org/show_bug.cgi?id=140685 |
| 675 | if (!newVariant || !newVariant.executable()) { |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 676 | linkVirtualFor(exec, callLinkInfo); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 677 | return; |
| 678 | } |
| 679 | |
| 680 | CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock(); |
| 681 | VM* vm = callerCodeBlock->vm(); |
| 682 | |
| 683 | CallVariantList list; |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 684 | if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub()) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 685 | list = stub->variants(); |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 686 | else if (JSFunction* oldCallee = callLinkInfo.callee()) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 687 | list = CallVariantList{ CallVariant(oldCallee) }; |
| 688 | |
| 689 | list = variantListWithVariant(list, newVariant); |
| 690 | |
| 691 | // If there are any closure calls then it makes sense to treat all of them as closure calls. |
| 692 | // This makes switching on callee cheaper. It also produces profiling that's easier on the DFG; |
| 693 | // the DFG doesn't really want to deal with a combination of closure and non-closure callees. |
| 694 | bool isClosureCall = false; |
| 695 | for (CallVariant variant : list) { |
| 696 | if (variant.isClosureCall()) { |
| 697 | list = despecifiedVariantList(list); |
| 698 | isClosureCall = true; |
| 699 | break; |
| 700 | } |
| 701 | } |
| 702 | |
fpizlo@apple.com | 23bc584 | 2015-06-03 20:08:01 +0000 | [diff] [blame] | 703 | if (isClosureCall) |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 704 | callLinkInfo.setHasSeenClosure(); |
fpizlo@apple.com | 23bc584 | 2015-06-03 20:08:01 +0000 | [diff] [blame] | 705 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 706 | Vector<PolymorphicCallCase> callCases; |
| 707 | |
| 708 | // Figure out what our cases are. |
| 709 | for (CallVariant variant : list) { |
| 710 | CodeBlock* codeBlock; |
| 711 | if (variant.executable()->isHostFunction()) |
| 712 | codeBlock = nullptr; |
| 713 | else { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 714 | ExecutableBase* executable = variant.executable(); |
| 715 | #if ENABLE(WEBASSEMBLY) |
| 716 | if (executable->isWebAssemblyExecutable()) |
| 717 | codeBlock = jsCast<WebAssemblyExecutable*>(executable)->codeBlockForCall(); |
| 718 | else |
| 719 | #endif |
| 720 | codeBlock = jsCast<FunctionExecutable*>(executable)->codeBlockForCall(); |
msaboff@apple.com | f046795 | 2015-10-24 01:45:30 +0000 | [diff] [blame] | 721 | // If we cannot handle a callee, either because we don't have a CodeBlock or because arity mismatch, |
| 722 | // assume that it's better for this whole thing to be a virtual call. |
| 723 | if (!codeBlock || exec->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.isVarargs()) { |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 724 | linkVirtualFor(exec, callLinkInfo); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 725 | return; |
| 726 | } |
| 727 | } |
| 728 | |
| 729 | callCases.append(PolymorphicCallCase(variant, codeBlock)); |
| 730 | } |
| 731 | |
| 732 | // If we are over the limit, just use a normal virtual call. |
| 733 | unsigned maxPolymorphicCallVariantListSize; |
| 734 | if (callerCodeBlock->jitType() == JITCode::topTierJIT()) |
| 735 | maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSizeForTopTier(); |
| 736 | else |
| 737 | maxPolymorphicCallVariantListSize = Options::maxPolymorphicCallVariantListSize(); |
| 738 | if (list.size() > maxPolymorphicCallVariantListSize) { |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 739 | linkVirtualFor(exec, callLinkInfo); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 740 | return; |
| 741 | } |
| 742 | |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 743 | GPRReg calleeGPR = static_cast<GPRReg>(callLinkInfo.calleeGPR()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 744 | |
| 745 | CCallHelpers stubJit(vm, callerCodeBlock); |
| 746 | |
| 747 | CCallHelpers::JumpList slowPath; |
| 748 | |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 749 | std::unique_ptr<CallFrameShuffler> frameShuffler; |
| 750 | if (callLinkInfo.frameShuffleData()) { |
| 751 | ASSERT(callLinkInfo.isTailCall()); |
| 752 | frameShuffler = std::make_unique<CallFrameShuffler>(stubJit, *callLinkInfo.frameShuffleData()); |
| 753 | #if USE(JSVALUE32_64) |
| 754 | // We would have already checked that the callee is a cell, and we can |
| 755 | // use the additional register this buys us. |
| 756 | frameShuffler->assumeCalleeIsCell(); |
| 757 | #endif |
| 758 | frameShuffler->lockGPR(calleeGPR); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 759 | } |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 760 | GPRReg comparisonValueGPR; |
| 761 | |
| 762 | if (isClosureCall) { |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 763 | GPRReg scratchGPR; |
| 764 | if (frameShuffler) |
| 765 | scratchGPR = frameShuffler->acquireGPR(); |
| 766 | else |
| 767 | scratchGPR = AssemblyHelpers::selectScratchGPR(calleeGPR); |
| 768 | // Verify that we have a function and stash the executable in scratchGPR. |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 769 | |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 770 | #if USE(JSVALUE64) |
fpizlo@apple.com | 4d03e0e | 2016-04-18 17:13:33 +0000 | [diff] [blame] | 771 | slowPath.append(stubJit.branchTest64(CCallHelpers::NonZero, calleeGPR, GPRInfo::tagMaskRegister)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 772 | #else |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 773 | // We would have already checked that the callee is a cell. |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 774 | #endif |
| 775 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 776 | slowPath.append( |
| 777 | stubJit.branch8( |
| 778 | CCallHelpers::NotEqual, |
| 779 | CCallHelpers::Address(calleeGPR, JSCell::typeInfoTypeOffset()), |
| 780 | CCallHelpers::TrustedImm32(JSFunctionType))); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 781 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 782 | stubJit.loadPtr( |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 783 | CCallHelpers::Address(calleeGPR, JSFunction::offsetOfExecutable()), |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 784 | scratchGPR); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 785 | |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 786 | comparisonValueGPR = scratchGPR; |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 787 | } else |
| 788 | comparisonValueGPR = calleeGPR; |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 789 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 790 | Vector<int64_t> caseValues(callCases.size()); |
| 791 | Vector<CallToCodePtr> calls(callCases.size()); |
| 792 | std::unique_ptr<uint32_t[]> fastCounts; |
| 793 | |
| 794 | if (callerCodeBlock->jitType() != JITCode::topTierJIT()) |
| 795 | fastCounts = std::make_unique<uint32_t[]>(callCases.size()); |
| 796 | |
fpizlo@apple.com | b1e1c2d | 2015-05-05 20:42:44 +0000 | [diff] [blame] | 797 | for (size_t i = 0; i < callCases.size(); ++i) { |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 798 | if (fastCounts) |
| 799 | fastCounts[i] = 0; |
| 800 | |
| 801 | CallVariant variant = callCases[i].variant(); |
fpizlo@apple.com | b1e1c2d | 2015-05-05 20:42:44 +0000 | [diff] [blame] | 802 | int64_t newCaseValue; |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 803 | if (isClosureCall) |
fpizlo@apple.com | b1e1c2d | 2015-05-05 20:42:44 +0000 | [diff] [blame] | 804 | newCaseValue = bitwise_cast<intptr_t>(variant.executable()); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 805 | else |
fpizlo@apple.com | b1e1c2d | 2015-05-05 20:42:44 +0000 | [diff] [blame] | 806 | newCaseValue = bitwise_cast<intptr_t>(variant.function()); |
| 807 | |
| 808 | if (!ASSERT_DISABLED) { |
| 809 | for (size_t j = 0; j < i; ++j) { |
| 810 | if (caseValues[j] != newCaseValue) |
| 811 | continue; |
| 812 | |
| 813 | dataLog("ERROR: Attempt to add duplicate case value.\n"); |
| 814 | dataLog("Existing case values: "); |
| 815 | CommaPrinter comma; |
| 816 | for (size_t k = 0; k < i; ++k) |
| 817 | dataLog(comma, caseValues[k]); |
| 818 | dataLog("\n"); |
| 819 | dataLog("Attempting to add: ", newCaseValue, "\n"); |
| 820 | dataLog("Variant list: ", listDump(callCases), "\n"); |
| 821 | RELEASE_ASSERT_NOT_REACHED(); |
| 822 | } |
| 823 | } |
| 824 | |
| 825 | caseValues[i] = newCaseValue; |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 826 | } |
| 827 | |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 828 | GPRReg fastCountsBaseGPR; |
| 829 | if (frameShuffler) |
| 830 | fastCountsBaseGPR = frameShuffler->acquireGPR(); |
| 831 | else { |
| 832 | fastCountsBaseGPR = |
| 833 | AssemblyHelpers::selectScratchGPR(calleeGPR, comparisonValueGPR, GPRInfo::regT3); |
| 834 | } |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 835 | stubJit.move(CCallHelpers::TrustedImmPtr(fastCounts.get()), fastCountsBaseGPR); |
msaboff@apple.com | 87a33cf | 2015-11-14 21:13:02 +0000 | [diff] [blame] | 836 | if (!frameShuffler && callLinkInfo.isTailCall()) |
| 837 | stubJit.emitRestoreCalleeSaves(); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 838 | BinarySwitch binarySwitch(comparisonValueGPR, caseValues, BinarySwitch::IntPtr); |
| 839 | CCallHelpers::JumpList done; |
| 840 | while (binarySwitch.advance(stubJit)) { |
| 841 | size_t caseIndex = binarySwitch.caseIndex(); |
| 842 | |
| 843 | CallVariant variant = callCases[caseIndex].variant(); |
| 844 | |
| 845 | ASSERT(variant.executable()->hasJITCodeForCall()); |
| 846 | MacroAssemblerCodePtr codePtr = |
msaboff@apple.com | 21bd737 | 2015-09-18 16:21:08 +0000 | [diff] [blame] | 847 | variant.executable()->generatedJITCodeForCall()->addressForCall(ArityCheckNotRequired); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 848 | |
| 849 | if (fastCounts) { |
| 850 | stubJit.add32( |
| 851 | CCallHelpers::TrustedImm32(1), |
| 852 | CCallHelpers::Address(fastCountsBaseGPR, caseIndex * sizeof(uint32_t))); |
| 853 | } |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 854 | if (frameShuffler) { |
| 855 | CallFrameShuffler(stubJit, frameShuffler->snapshot()).prepareForTailCall(); |
| 856 | calls[caseIndex].call = stubJit.nearTailCall(); |
| 857 | } else if (callLinkInfo.isTailCall()) { |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 858 | stubJit.prepareForTailCallSlow(); |
| 859 | calls[caseIndex].call = stubJit.nearTailCall(); |
| 860 | } else |
| 861 | calls[caseIndex].call = stubJit.nearCall(); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 862 | calls[caseIndex].codePtr = codePtr; |
| 863 | done.append(stubJit.jump()); |
| 864 | } |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 865 | |
| 866 | slowPath.link(&stubJit); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 867 | binarySwitch.fallThrough().link(&stubJit); |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 868 | |
| 869 | if (frameShuffler) { |
| 870 | frameShuffler->releaseGPR(calleeGPR); |
| 871 | frameShuffler->releaseGPR(comparisonValueGPR); |
| 872 | frameShuffler->releaseGPR(fastCountsBaseGPR); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 873 | #if USE(JSVALUE32_64) |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 874 | frameShuffler->setCalleeJSValueRegs(JSValueRegs(GPRInfo::regT1, GPRInfo::regT0)); |
| 875 | #else |
| 876 | frameShuffler->setCalleeJSValueRegs(JSValueRegs(GPRInfo::regT0)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 877 | #endif |
msaboff@apple.com | 4cd77e6 | 2015-09-18 23:51:41 +0000 | [diff] [blame] | 878 | frameShuffler->prepareForSlowPath(); |
| 879 | } else { |
| 880 | stubJit.move(calleeGPR, GPRInfo::regT0); |
| 881 | #if USE(JSVALUE32_64) |
| 882 | stubJit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1); |
| 883 | #endif |
| 884 | } |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 885 | stubJit.move(CCallHelpers::TrustedImmPtr(&callLinkInfo), GPRInfo::regT2); |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 886 | stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.callReturnLocation().executableAddress()), GPRInfo::regT4); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 887 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 888 | stubJit.restoreReturnAddressBeforeReturn(GPRInfo::regT4); |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 889 | AssemblyHelpers::Jump slow = stubJit.jump(); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 890 | |
fpizlo@apple.com | 616e7b5 | 2015-03-26 01:26:56 +0000 | [diff] [blame] | 891 | LinkBuffer patchBuffer(*vm, stubJit, callerCodeBlock, JITCompilationCanFail); |
| 892 | if (patchBuffer.didFailToAllocate()) { |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 893 | linkVirtualFor(exec, callLinkInfo); |
fpizlo@apple.com | 616e7b5 | 2015-03-26 01:26:56 +0000 | [diff] [blame] | 894 | return; |
| 895 | } |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 896 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 897 | RELEASE_ASSERT(callCases.size() == calls.size()); |
| 898 | for (CallToCodePtr callToCodePtr : calls) { |
commit-queue@webkit.org | c857681 | 2016-04-15 09:07:36 +0000 | [diff] [blame] | 899 | // Tail call special-casing ensures proper linking on ARM Thumb2, where a tail call jumps to an address |
| 900 | // with a non-decorated bottom bit but a normal call calls an address with a decorated bottom bit. |
| 901 | bool isTailCall = callToCodePtr.call.isFlagSet(CCallHelpers::Call::Tail); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 902 | patchBuffer.link( |
commit-queue@webkit.org | c857681 | 2016-04-15 09:07:36 +0000 | [diff] [blame] | 903 | callToCodePtr.call, FunctionPtr(isTailCall ? callToCodePtr.codePtr.dataLocation() : callToCodePtr.codePtr.executableAddress())); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 904 | } |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 905 | if (JITCode::isOptimizingJIT(callerCodeBlock->jitType())) |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 906 | patchBuffer.link(done, callLinkInfo.callReturnLocation().labelAtOffset(0)); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 907 | else |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 908 | patchBuffer.link(done, callLinkInfo.hotPathOther().labelAtOffset(0)); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 909 | patchBuffer.link(slow, CodeLocationLabel(vm->getCTIStub(linkPolymorphicCallThunkGenerator).code())); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 910 | |
krollin@apple.com | 77db180 | 2016-06-20 20:52:45 +0000 | [diff] [blame] | 911 | auto stubRoutine = adoptRef(*new PolymorphicCallStubRoutine( |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 912 | FINALIZE_CODE_FOR( |
| 913 | callerCodeBlock, patchBuffer, |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 914 | ("Polymorphic call stub for %s, return point %p, targets %s", |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 915 | toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation().labelAtOffset(0).executableAddress(), |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 916 | toCString(listDump(callCases)).data())), |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 917 | *vm, callerCodeBlock, exec->callerFrame(), callLinkInfo, callCases, |
aestes@apple.com | 13aae08 | 2016-01-02 08:03:08 +0000 | [diff] [blame] | 918 | WTFMove(fastCounts))); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 919 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 920 | MacroAssembler::replaceWithJump( |
| 921 | MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()), |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 922 | CodeLocationLabel(stubRoutine->code().code())); |
basile_clement@apple.com | 7d9a709 | 2015-07-28 20:12:33 +0000 | [diff] [blame] | 923 | // The original slow path is unreachable on 64-bits, but still |
| 924 | // reachable on 32-bits since a non-cell callee will always |
| 925 | // trigger the slow path |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 926 | linkSlowFor(vm, callLinkInfo); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 927 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 928 | // If there had been a previous stub routine, that one will die as soon as the GC runs and sees |
| 929 | // that it's no longer on stack. |
krollin@apple.com | 77db180 | 2016-06-20 20:52:45 +0000 | [diff] [blame] | 930 | callLinkInfo.setStub(WTFMove(stubRoutine)); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 931 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 932 | // The call link info no longer has a call cache apart from the jump to the polymorphic call |
| 933 | // stub. |
| 934 | if (callLinkInfo.isOnList()) |
| 935 | callLinkInfo.remove(); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 936 | } |
| 937 | |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 938 | void resetGetByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo, GetByIDKind kind) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 939 | { |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 940 | ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingGetByIdFunction(kind)); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 941 | InlineAccess::rewireStubAsJump(*codeBlock->vm(), stubInfo, stubInfo.slowPathStartLocation()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 942 | } |
| 943 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 944 | void resetPutByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 945 | { |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 946 | V_JITOperation_ESsiJJI unoptimizedFunction = bitwise_cast<V_JITOperation_ESsiJJI>(readCallTarget(codeBlock, stubInfo.slowPathCallLocation()).executableAddress()); |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 947 | V_JITOperation_ESsiJJI optimizedFunction; |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 948 | if (unoptimizedFunction == operationPutByIdStrict || unoptimizedFunction == operationPutByIdStrictOptimize) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 949 | optimizedFunction = operationPutByIdStrictOptimize; |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 950 | else if (unoptimizedFunction == operationPutByIdNonStrict || unoptimizedFunction == operationPutByIdNonStrictOptimize) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 951 | optimizedFunction = operationPutByIdNonStrictOptimize; |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 952 | else if (unoptimizedFunction == operationPutByIdDirectStrict || unoptimizedFunction == operationPutByIdDirectStrictOptimize) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 953 | optimizedFunction = operationPutByIdDirectStrictOptimize; |
| 954 | else { |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 955 | ASSERT(unoptimizedFunction == operationPutByIdDirectNonStrict || unoptimizedFunction == operationPutByIdDirectNonStrictOptimize); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 956 | optimizedFunction = operationPutByIdDirectNonStrictOptimize; |
| 957 | } |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 958 | |
sbarati@apple.com | b0b1eb5 | 2016-07-21 23:41:44 +0000 | [diff] [blame] | 959 | ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), optimizedFunction); |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 960 | InlineAccess::rewireStubAsJump(*codeBlock->vm(), stubInfo, stubInfo.slowPathStartLocation()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 961 | } |
| 962 | |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 963 | void resetIn(CodeBlock*, StructureStubInfo& stubInfo) |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 964 | { |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 965 | MacroAssembler::repatchJump(stubInfo.patchableJumpForIn(), stubInfo.slowPathStartLocation()); |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 966 | } |
| 967 | |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 968 | } // namespace JSC |
fpizlo@apple.com | da4645e | 2013-09-22 00:24:36 +0000 | [diff] [blame] | 969 | |
| 970 | #endif |