mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1 | /* |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 2 | * Copyright (C) 2008-2010, 2012-2016 Apple Inc. All rights reserved. |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 3 | * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * |
| 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer. |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer in the |
| 13 | * documentation and/or other materials provided with the distribution. |
mjs@apple.com | 9204733 | 2014-03-15 04:08:27 +0000 | [diff] [blame] | 14 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 15 | * its contributors may be used to endorse or promote products derived |
| 16 | * from this software without specific prior written permission. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 21 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #include "config.h" |
| 31 | #include "CodeBlock.h" |
| 32 | |
saambarati1@gmail.com | b4f28a5 | 2014-12-05 05:58:07 +0000 | [diff] [blame] | 33 | #include "BasicBlockLocation.h" |
barraclough@apple.com | c2527d6 | 2010-08-11 19:52:41 +0000 | [diff] [blame] | 34 | #include "BytecodeGenerator.h" |
fpizlo@apple.com | 0309686b | 2013-12-02 19:49:43 +0000 | [diff] [blame] | 35 | #include "BytecodeUseDef.h" |
fpizlo@apple.com | 806b582 | 2013-01-08 01:23:38 +0000 | [diff] [blame] | 36 | #include "CallLinkStatus.h" |
fpizlo@apple.com | 452cb41 | 2011-09-08 21:38:04 +0000 | [diff] [blame] | 37 | #include "DFGCapabilities.h" |
fpizlo@apple.com | 1e89af3 | 2012-11-19 02:55:14 +0000 | [diff] [blame] | 38 | #include "DFGCommon.h" |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 39 | #include "DFGDriver.h" |
fpizlo@apple.com | b426f86 | 2014-02-10 02:51:13 +0000 | [diff] [blame] | 40 | #include "DFGJITCode.h" |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 41 | #include "DFGWorklist.h" |
barraclough@apple.com | c2527d6 | 2010-08-11 19:52:41 +0000 | [diff] [blame] | 42 | #include "Debugger.h" |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 43 | #include "FunctionExecutableDump.h" |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 44 | #include "GetPutInfo.h" |
ggaren@apple.com | 0dc469d | 2015-08-18 19:28:37 +0000 | [diff] [blame] | 45 | #include "InlineCallFrame.h" |
ggaren@apple.com | 901a8a2 | 2008-11-17 20:57:18 +0000 | [diff] [blame] | 46 | #include "Interpreter.h" |
fpizlo@apple.com | 81bb8bb | 2013-11-23 00:36:55 +0000 | [diff] [blame] | 47 | #include "JIT.h" |
oliver@apple.com | d04e0a0 | 2014-02-01 01:37:59 +0000 | [diff] [blame] | 48 | #include "JSCJSValue.h" |
barraclough@apple.com | 3dc1233 | 2009-08-12 05:22:33 +0000 | [diff] [blame] | 49 | #include "JSFunction.h" |
oliver@apple.com | a7dfb4d | 2014-09-11 18:18:14 +0000 | [diff] [blame] | 50 | #include "JSLexicalEnvironment.h" |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 51 | #include "JSModuleEnvironment.h" |
fpizlo@apple.com | 81bb8bb | 2013-11-23 00:36:55 +0000 | [diff] [blame] | 52 | #include "LLIntEntrypoint.h" |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 53 | #include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h" |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 54 | #include "LowLevelInterpreter.h" |
fpizlo@apple.com | fb7eff2 | 2014-02-11 01:45:50 +0000 | [diff] [blame] | 55 | #include "JSCInlines.h" |
sbarati@apple.com | d3d0c00 | 2016-01-30 01:11:05 +0000 | [diff] [blame] | 56 | #include "PCToCodeOriginMap.h" |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 57 | #include "PolymorphicAccess.h" |
akling@apple.com | 5a0a87e | 2014-03-22 20:57:04 +0000 | [diff] [blame] | 58 | #include "ProfilerDatabase.h" |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 59 | #include "ReduceWhitespace.h" |
mark.lam@apple.com | 9df8b83 | 2013-09-26 20:27:14 +0000 | [diff] [blame] | 60 | #include "Repatch.h" |
mark.lam@apple.com | a4fe7ab | 2012-11-09 03:03:44 +0000 | [diff] [blame] | 61 | #include "SlotVisitorInlines.h" |
msaboff@apple.com | 4d563e4 | 2014-08-16 01:45:40 +0000 | [diff] [blame] | 62 | #include "StackVisitor.h" |
fpizlo@apple.com | d5f9946 | 2016-04-11 19:31:04 +0000 | [diff] [blame] | 63 | #include "StructureStubInfo.h" |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 64 | #include "TypeLocationCache.h" |
| 65 | #include "TypeProfiler.h" |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 66 | #include "UnlinkedInstructionStream.h" |
fpizlo@apple.com | 4a528d0 | 2016-05-11 00:08:50 +0000 | [diff] [blame] | 67 | #include "VMInlines.h" |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 68 | #include <wtf/BagToHashMap.h> |
fpizlo@apple.com | 806b582 | 2013-01-08 01:23:38 +0000 | [diff] [blame] | 69 | #include <wtf/CommaPrinter.h> |
aroben@apple.com | a2fd570 | 2008-09-02 15:15:21 +0000 | [diff] [blame] | 70 | #include <wtf/StringExtras.h> |
fpizlo@apple.com | 9fe4913 | 2012-12-04 19:29:13 +0000 | [diff] [blame] | 71 | #include <wtf/StringPrintStream.h> |
utatane.tea@gmail.com | 8268d39 | 2015-05-23 18:41:53 +0000 | [diff] [blame] | 72 | #include <wtf/text/UniquedStringImpl.h> |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 73 | |
msaboff@apple.com | 0208546 | 2015-09-10 17:47:16 +0000 | [diff] [blame] | 74 | #if ENABLE(JIT) |
| 75 | #include "RegisterAtOffsetList.h" |
| 76 | #endif |
| 77 | |
commit-queue@webkit.org | 4ea4892 | 2011-07-06 00:56:49 +0000 | [diff] [blame] | 78 | #if ENABLE(DFG_JIT) |
| 79 | #include "DFGOperations.h" |
| 80 | #endif |
| 81 | |
carlosgc@webkit.org | 13f6daf2 | 2013-07-30 06:42:00 +0000 | [diff] [blame] | 82 | #if ENABLE(FTL_JIT) |
| 83 | #include "FTLJITCode.h" |
| 84 | #endif |
| 85 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 86 | namespace JSC { |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 87 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 88 | const ClassInfo CodeBlock::s_info = { |
| 89 | "CodeBlock", 0, 0, |
| 90 | CREATE_METHOD_TABLE(CodeBlock) |
| 91 | }; |
| 92 | |
| 93 | const ClassInfo FunctionCodeBlock::s_info = { |
| 94 | "FunctionCodeBlock", &Base::s_info, 0, |
| 95 | CREATE_METHOD_TABLE(FunctionCodeBlock) |
| 96 | }; |
| 97 | |
| 98 | #if ENABLE(WEBASSEMBLY) |
| 99 | const ClassInfo WebAssemblyCodeBlock::s_info = { |
| 100 | "WebAssemblyCodeBlock", &Base::s_info, 0, |
| 101 | CREATE_METHOD_TABLE(WebAssemblyCodeBlock) |
| 102 | }; |
| 103 | #endif |
| 104 | |
| 105 | const ClassInfo GlobalCodeBlock::s_info = { |
| 106 | "GlobalCodeBlock", &Base::s_info, 0, |
| 107 | CREATE_METHOD_TABLE(GlobalCodeBlock) |
| 108 | }; |
| 109 | |
| 110 | const ClassInfo ProgramCodeBlock::s_info = { |
| 111 | "ProgramCodeBlock", &Base::s_info, 0, |
| 112 | CREATE_METHOD_TABLE(ProgramCodeBlock) |
| 113 | }; |
| 114 | |
| 115 | const ClassInfo ModuleProgramCodeBlock::s_info = { |
| 116 | "ModuleProgramCodeBlock", &Base::s_info, 0, |
| 117 | CREATE_METHOD_TABLE(ModuleProgramCodeBlock) |
| 118 | }; |
| 119 | |
| 120 | const ClassInfo EvalCodeBlock::s_info = { |
| 121 | "EvalCodeBlock", &Base::s_info, 0, |
| 122 | CREATE_METHOD_TABLE(EvalCodeBlock) |
| 123 | }; |
| 124 | |
| 125 | void FunctionCodeBlock::destroy(JSCell* cell) |
| 126 | { |
| 127 | jsCast<FunctionCodeBlock*>(cell)->~FunctionCodeBlock(); |
| 128 | } |
| 129 | |
| 130 | #if ENABLE(WEBASSEMBLY) |
| 131 | void WebAssemblyCodeBlock::destroy(JSCell* cell) |
| 132 | { |
| 133 | jsCast<WebAssemblyCodeBlock*>(cell)->~WebAssemblyCodeBlock(); |
| 134 | } |
| 135 | #endif |
| 136 | |
| 137 | void ProgramCodeBlock::destroy(JSCell* cell) |
| 138 | { |
| 139 | jsCast<ProgramCodeBlock*>(cell)->~ProgramCodeBlock(); |
| 140 | } |
| 141 | |
| 142 | void ModuleProgramCodeBlock::destroy(JSCell* cell) |
| 143 | { |
| 144 | jsCast<ModuleProgramCodeBlock*>(cell)->~ModuleProgramCodeBlock(); |
| 145 | } |
| 146 | |
| 147 | void EvalCodeBlock::destroy(JSCell* cell) |
| 148 | { |
| 149 | jsCast<EvalCodeBlock*>(cell)->~EvalCodeBlock(); |
| 150 | } |
| 151 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 152 | CString CodeBlock::inferredName() const |
fpizlo@apple.com | 1a6da21 | 2012-12-10 18:38:15 +0000 | [diff] [blame] | 153 | { |
| 154 | switch (codeType()) { |
| 155 | case GlobalCode: |
| 156 | return "<global>"; |
| 157 | case EvalCode: |
| 158 | return "<eval>"; |
| 159 | case FunctionCode: |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 160 | return jsCast<FunctionExecutable*>(ownerExecutable())->inferredName().utf8(); |
utatane.tea@gmail.com | a8309d9 | 2015-09-01 02:05:30 +0000 | [diff] [blame] | 161 | case ModuleCode: |
| 162 | return "<module>"; |
fpizlo@apple.com | 1a6da21 | 2012-12-10 18:38:15 +0000 | [diff] [blame] | 163 | default: |
| 164 | CRASH(); |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 165 | return CString("", 0); |
fpizlo@apple.com | 1a6da21 | 2012-12-10 18:38:15 +0000 | [diff] [blame] | 166 | } |
| 167 | } |
| 168 | |
mhahnenberg@apple.com | 0c662a4 | 2013-08-02 21:50:56 +0000 | [diff] [blame] | 169 | bool CodeBlock::hasHash() const |
| 170 | { |
| 171 | return !!m_hash; |
| 172 | } |
| 173 | |
| 174 | bool CodeBlock::isSafeToComputeHash() const |
| 175 | { |
| 176 | return !isCompilationThread(); |
| 177 | } |
| 178 | |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 179 | CodeBlockHash CodeBlock::hash() const |
| 180 | { |
oliver@apple.com | acdde49 | 2013-07-25 04:02:57 +0000 | [diff] [blame] | 181 | if (!m_hash) { |
mhahnenberg@apple.com | 0c662a4 | 2013-08-02 21:50:56 +0000 | [diff] [blame] | 182 | RELEASE_ASSERT(isSafeToComputeHash()); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 183 | m_hash = CodeBlockHash(ownerScriptExecutable()->source(), specializationKind()); |
oliver@apple.com | acdde49 | 2013-07-25 04:02:57 +0000 | [diff] [blame] | 184 | } |
| 185 | return m_hash; |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 186 | } |
| 187 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 188 | CString CodeBlock::sourceCodeForTools() const |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 189 | { |
| 190 | if (codeType() != FunctionCode) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 191 | return ownerScriptExecutable()->source().toUTF8(); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 192 | |
| 193 | SourceProvider* provider = source(); |
| 194 | FunctionExecutable* executable = jsCast<FunctionExecutable*>(ownerExecutable()); |
| 195 | UnlinkedFunctionExecutable* unlinked = executable->unlinkedExecutable(); |
| 196 | unsigned unlinkedStartOffset = unlinked->startOffset(); |
| 197 | unsigned linkedStartOffset = executable->source().startOffset(); |
| 198 | int delta = linkedStartOffset - unlinkedStartOffset; |
mark.lam@apple.com | fa35e78 | 2013-11-19 21:55:16 +0000 | [diff] [blame] | 199 | unsigned rangeStart = delta + unlinked->unlinkedFunctionNameStart(); |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 200 | unsigned rangeEnd = delta + unlinked->startOffset() + unlinked->sourceLength(); |
| 201 | return toCString( |
| 202 | "function ", |
akling@apple.com | 7332098 | 2015-12-13 20:03:24 +0000 | [diff] [blame] | 203 | provider->source().substring(rangeStart, rangeEnd - rangeStart).utf8()); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 204 | } |
| 205 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 206 | CString CodeBlock::sourceCodeOnOneLine() const |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 207 | { |
| 208 | return reduceWhitespace(sourceCodeForTools()); |
| 209 | } |
| 210 | |
fpizlo@apple.com | f285f71 | 2014-03-13 01:50:41 +0000 | [diff] [blame] | 211 | CString CodeBlock::hashAsStringIfPossible() const |
| 212 | { |
| 213 | if (hasHash() || isSafeToComputeHash()) |
| 214 | return toCString(hash()); |
| 215 | return "<no-hash>"; |
| 216 | } |
| 217 | |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 218 | void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const |
| 219 | { |
fpizlo@apple.com | f285f71 | 2014-03-13 01:50:41 +0000 | [diff] [blame] | 220 | out.print(inferredName(), "#", hashAsStringIfPossible()); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 221 | out.print(":[", RawPointer(this), "->"); |
| 222 | if (!!m_alternative) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 223 | out.print(RawPointer(alternative()), "->"); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 224 | out.print(RawPointer(ownerExecutable()), ", ", jitType, codeType()); |
mhahnenberg@apple.com | 0c662a4 | 2013-08-02 21:50:56 +0000 | [diff] [blame] | 225 | |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 226 | if (codeType() == FunctionCode) |
| 227 | out.print(specializationKind()); |
fpizlo@apple.com | 9df7fef | 2013-12-29 21:50:55 +0000 | [diff] [blame] | 228 | out.print(", ", instructionCount()); |
oliver@apple.com | b3e5acb | 2013-07-25 04:02:53 +0000 | [diff] [blame] | 229 | if (this->jitType() == JITCode::BaselineJIT && m_shouldAlwaysBeInlined) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 230 | out.print(" (ShouldAlwaysBeInlined)"); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 231 | if (ownerScriptExecutable()->neverInline()) |
oliver@apple.com | 4e67ae5 | 2013-07-25 04:01:24 +0000 | [diff] [blame] | 232 | out.print(" (NeverInline)"); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 233 | if (ownerScriptExecutable()->neverOptimize()) |
mark.lam@apple.com | 49e71b9 | 2015-08-28 05:59:44 +0000 | [diff] [blame] | 234 | out.print(" (NeverOptimize)"); |
keith_miller@apple.com | a64964a | 2016-04-22 02:28:00 +0000 | [diff] [blame] | 235 | else if (ownerScriptExecutable()->neverFTLOptimize()) |
| 236 | out.print(" (NeverFTLOptimize)"); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 237 | if (ownerScriptExecutable()->didTryToEnterInLoop()) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 238 | out.print(" (DidTryToEnterInLoop)"); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 239 | if (ownerScriptExecutable()->isStrictMode()) |
fpizlo@apple.com | 018818d | 2013-09-13 23:18:19 +0000 | [diff] [blame] | 240 | out.print(" (StrictMode)"); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 241 | if (this->jitType() == JITCode::BaselineJIT && m_didFailFTLCompilation) |
| 242 | out.print(" (FTLFail)"); |
| 243 | if (this->jitType() == JITCode::BaselineJIT && m_hasBeenCompiledWithFTL) |
| 244 | out.print(" (HadFTLReplacement)"); |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 245 | out.print("]"); |
| 246 | } |
| 247 | |
| 248 | void CodeBlock::dump(PrintStream& out) const |
| 249 | { |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 250 | dumpAssumingJITType(out, jitType()); |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 251 | } |
| 252 | |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 253 | static CString idName(int id0, const Identifier& ident) |
| 254 | { |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 255 | return toCString(ident.impl(), "(@id", id0, ")"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 256 | } |
| 257 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 258 | CString CodeBlock::registerName(int r) const |
mrowe@apple.com | d531609 | 2009-11-05 02:22:08 +0000 | [diff] [blame] | 259 | { |
mrowe@apple.com | d531609 | 2009-11-05 02:22:08 +0000 | [diff] [blame] | 260 | if (isConstantRegisterIndex(r)) |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 261 | return constantName(r); |
mrowe@apple.com | d531609 | 2009-11-05 02:22:08 +0000 | [diff] [blame] | 262 | |
fpizlo@apple.com | 240c7a5 | 2015-02-02 23:32:00 +0000 | [diff] [blame] | 263 | return toCString(VirtualRegister(r)); |
mrowe@apple.com | d531609 | 2009-11-05 02:22:08 +0000 | [diff] [blame] | 264 | } |
| 265 | |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 266 | CString CodeBlock::constantName(int index) const |
| 267 | { |
| 268 | JSValue value = getConstant(index); |
| 269 | return toCString(value, "(", VirtualRegister(index), ")"); |
| 270 | } |
| 271 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 272 | static CString regexpToSourceString(RegExp* regExp) |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 273 | { |
| 274 | char postfix[5] = { '/', 0, 0, 0, 0 }; |
| 275 | int index = 1; |
| 276 | if (regExp->global()) |
| 277 | postfix[index++] = 'g'; |
| 278 | if (regExp->ignoreCase()) |
| 279 | postfix[index++] = 'i'; |
| 280 | if (regExp->multiline()) |
| 281 | postfix[index] = 'm'; |
msaboff@apple.com | 3f19465 | 2016-03-09 20:11:46 +0000 | [diff] [blame] | 282 | if (regExp->sticky()) |
| 283 | postfix[index++] = 'y'; |
| 284 | if (regExp->unicode()) |
| 285 | postfix[index++] = 'u'; |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 286 | |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 287 | return toCString("/", regExp->pattern().impl(), postfix); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 288 | } |
| 289 | |
| 290 | static CString regexpName(int re, RegExp* regexp) |
| 291 | { |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 292 | return toCString(regexpToSourceString(regexp), "(@re", re, ")"); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 293 | } |
| 294 | |
ggaren@apple.com | d0740c8 | 2008-05-28 20:47:13 +0000 | [diff] [blame] | 295 | NEVER_INLINE static const char* debugHookName(int debugHookID) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 296 | { |
weinig@apple.com | a963b96 | 2008-06-05 05:36:55 +0000 | [diff] [blame] | 297 | switch (static_cast<DebugHookID>(debugHookID)) { |
| 298 | case DidEnterCallFrame: |
| 299 | return "didEnterCallFrame"; |
| 300 | case WillLeaveCallFrame: |
| 301 | return "willLeaveCallFrame"; |
| 302 | case WillExecuteStatement: |
| 303 | return "willExecuteStatement"; |
| 304 | case WillExecuteProgram: |
| 305 | return "willExecuteProgram"; |
| 306 | case DidExecuteProgram: |
| 307 | return "didExecuteProgram"; |
| 308 | case DidReachBreakpoint: |
| 309 | return "didReachBreakpoint"; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 310 | } |
weinig@apple.com | a963b96 | 2008-06-05 05:36:55 +0000 | [diff] [blame] | 311 | |
oliver@apple.com | 5598c18 | 2013-01-23 22:25:07 +0000 | [diff] [blame] | 312 | RELEASE_ASSERT_NOT_REACHED(); |
ggaren@apple.com | d0740c8 | 2008-05-28 20:47:13 +0000 | [diff] [blame] | 313 | return ""; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 314 | } |
| 315 | |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 316 | void CodeBlock::printUnaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 317 | { |
| 318 | int r0 = (++it)->u.operand; |
| 319 | int r1 = (++it)->u.operand; |
| 320 | |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 321 | printLocationAndOp(out, exec, location, it, op); |
| 322 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 323 | } |
| 324 | |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 325 | void CodeBlock::printBinaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 326 | { |
| 327 | int r0 = (++it)->u.operand; |
| 328 | int r1 = (++it)->u.operand; |
| 329 | int r2 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 330 | printLocationAndOp(out, exec, location, it, op); |
| 331 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 332 | } |
| 333 | |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 334 | void CodeBlock::printConditionalJump(PrintStream& out, ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 335 | { |
| 336 | int r0 = (++it)->u.operand; |
| 337 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 338 | printLocationAndOp(out, exec, location, it, op); |
| 339 | out.printf("%s, %d(->%d)", registerName(r0).data(), offset, location + offset); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 340 | } |
| 341 | |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 342 | void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it) |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 343 | { |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 344 | const char* op; |
| 345 | switch (exec->interpreter()->getOpcodeID(it->u.opcode)) { |
| 346 | case op_get_by_id: |
| 347 | op = "get_by_id"; |
| 348 | break; |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 349 | case op_get_by_id_proto_load: |
| 350 | op = "get_by_id_proto_load"; |
| 351 | break; |
keith_miller@apple.com | 785c651 | 2016-05-27 18:36:30 +0000 | [diff] [blame^] | 352 | case op_get_by_id_unset: |
| 353 | op = "get_by_id_unset"; |
| 354 | break; |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 355 | case op_get_array_length: |
| 356 | op = "array_length"; |
| 357 | break; |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 358 | default: |
oliver@apple.com | 5598c18 | 2013-01-23 22:25:07 +0000 | [diff] [blame] | 359 | RELEASE_ASSERT_NOT_REACHED(); |
mjs@apple.com | 0a66116 | 2014-09-08 02:16:47 +0000 | [diff] [blame] | 360 | #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE) |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 361 | op = 0; |
mjs@apple.com | 0a66116 | 2014-09-08 02:16:47 +0000 | [diff] [blame] | 362 | #endif |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 363 | } |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 364 | int r0 = (++it)->u.operand; |
| 365 | int r1 = (++it)->u.operand; |
| 366 | int id0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 367 | printLocationAndOp(out, exec, location, it, op); |
| 368 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 369 | it += 4; // Increment up to the value profiler. |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 370 | } |
| 371 | |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 372 | static void dumpStructure(PrintStream& out, const char* name, Structure* structure, const Identifier& ident) |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 373 | { |
| 374 | if (!structure) |
| 375 | return; |
| 376 | |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 377 | out.printf("%s = %p", name, structure); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 378 | |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 379 | PropertyOffset offset = structure->getConcurrently(ident.impl()); |
fpizlo@apple.com | 961a956 | 2012-07-24 02:13:19 +0000 | [diff] [blame] | 380 | if (offset != invalidOffset) |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 381 | out.printf(" (offset = %d)", offset); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 382 | } |
| 383 | |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 384 | static void dumpChain(PrintStream& out, StructureChain* chain, const Identifier& ident) |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 385 | { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 386 | out.printf("chain = %p: [", chain); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 387 | bool first = true; |
| 388 | for (WriteBarrier<Structure>* currentStructure = chain->head(); |
| 389 | *currentStructure; |
| 390 | ++currentStructure) { |
| 391 | if (first) |
| 392 | first = false; |
| 393 | else |
fpizlo@apple.com | 304fbca | 2012-12-17 21:38:51 +0000 | [diff] [blame] | 394 | out.printf(", "); |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 395 | dumpStructure(out, "struct", currentStructure->get(), ident); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 396 | } |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 397 | out.printf("]"); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 398 | } |
| 399 | |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 400 | void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int location, const StubInfoMap& map) |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 401 | { |
| 402 | Instruction* instruction = instructions().begin() + location; |
| 403 | |
oliver@apple.com | 9b65276 | 2013-08-12 22:39:13 +0000 | [diff] [blame] | 404 | const Identifier& ident = identifier(instruction[3].u.operand); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 405 | |
fpizlo@apple.com | b75911b | 2012-06-13 20:53:52 +0000 | [diff] [blame] | 406 | UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations. |
| 407 | |
fpizlo@apple.com | 4cafdbd | 2012-09-11 20:00:31 +0000 | [diff] [blame] | 408 | if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length) |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 409 | out.printf(" llint(array_length)"); |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 410 | else if (StructureID structureID = instruction[4].u.structureID) { |
| 411 | Structure* structure = m_vm->heap.structureIDTable().get(structureID); |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 412 | out.printf(" llint("); |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 413 | dumpStructure(out, "struct", structure, ident); |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 414 | out.printf(")"); |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 415 | if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_by_id_proto_load) |
| 416 | out.printf(" proto(%p)", instruction[6].u.pointer); |
fpizlo@apple.com | 4cafdbd | 2012-09-11 20:00:31 +0000 | [diff] [blame] | 417 | } |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 418 | |
| 419 | #if ENABLE(JIT) |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 420 | if (StructureStubInfo* stubPtr = map.get(CodeOrigin(location))) { |
| 421 | StructureStubInfo& stubInfo = *stubPtr; |
fpizlo@apple.com | 12803e2 | 2014-02-02 06:38:51 +0000 | [diff] [blame] | 422 | if (stubInfo.resetByGC) |
| 423 | out.print(" (Reset By GC)"); |
| 424 | |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 425 | out.printf(" jit("); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 426 | |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 427 | Structure* baseStructure = nullptr; |
| 428 | PolymorphicAccess* stub = nullptr; |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 429 | |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 430 | switch (stubInfo.cacheType) { |
| 431 | case CacheType::GetByIdSelf: |
| 432 | out.printf("self"); |
| 433 | baseStructure = stubInfo.u.byIdSelf.baseObjectStructure.get(); |
| 434 | break; |
| 435 | case CacheType::Stub: |
| 436 | out.printf("stub"); |
| 437 | stub = stubInfo.u.stub; |
| 438 | break; |
| 439 | case CacheType::Unset: |
| 440 | out.printf("unset"); |
| 441 | break; |
| 442 | default: |
| 443 | RELEASE_ASSERT_NOT_REACHED(); |
| 444 | break; |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 445 | } |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 446 | |
| 447 | if (baseStructure) { |
| 448 | out.printf(", "); |
| 449 | dumpStructure(out, "struct", baseStructure, ident); |
| 450 | } |
| 451 | |
| 452 | if (stub) |
| 453 | out.print(", ", *stub); |
| 454 | |
| 455 | out.printf(")"); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 456 | } |
mark.lam@apple.com | b1ea3ea | 2013-10-24 16:10:59 +0000 | [diff] [blame] | 457 | #else |
| 458 | UNUSED_PARAM(map); |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 459 | #endif |
| 460 | } |
| 461 | |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 462 | void CodeBlock::printPutByIdCacheStatus(PrintStream& out, int location, const StubInfoMap& map) |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 463 | { |
| 464 | Instruction* instruction = instructions().begin() + location; |
| 465 | |
| 466 | const Identifier& ident = identifier(instruction[2].u.operand); |
| 467 | |
| 468 | UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations. |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 469 | |
| 470 | out.print(", ", instruction[8].u.putByIdFlags); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 471 | |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 472 | if (StructureID structureID = instruction[4].u.structureID) { |
| 473 | Structure* structure = m_vm->heap.structureIDTable().get(structureID); |
| 474 | out.print(" llint("); |
| 475 | if (StructureID newStructureID = instruction[6].u.structureID) { |
| 476 | Structure* newStructure = m_vm->heap.structureIDTable().get(newStructureID); |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 477 | dumpStructure(out, "prev", structure, ident); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 478 | out.print(", "); |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 479 | dumpStructure(out, "next", newStructure, ident); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 480 | if (StructureChain* chain = instruction[7].u.structureChain.get()) { |
| 481 | out.print(", "); |
fpizlo@apple.com | 15ec1b2 | 2014-09-21 19:18:40 +0000 | [diff] [blame] | 482 | dumpChain(out, chain, ident); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 483 | } |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 484 | } else |
| 485 | dumpStructure(out, "struct", structure, ident); |
| 486 | out.print(")"); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 487 | } |
| 488 | |
| 489 | #if ENABLE(JIT) |
| 490 | if (StructureStubInfo* stubPtr = map.get(CodeOrigin(location))) { |
| 491 | StructureStubInfo& stubInfo = *stubPtr; |
| 492 | if (stubInfo.resetByGC) |
| 493 | out.print(" (Reset By GC)"); |
| 494 | |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 495 | out.printf(" jit("); |
| 496 | |
| 497 | switch (stubInfo.cacheType) { |
| 498 | case CacheType::PutByIdReplace: |
| 499 | out.print("replace, "); |
| 500 | dumpStructure(out, "struct", stubInfo.u.byIdSelf.baseObjectStructure.get(), ident); |
| 501 | break; |
| 502 | case CacheType::Stub: { |
| 503 | out.print("stub, ", *stubInfo.u.stub); |
| 504 | break; |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 505 | } |
fpizlo@apple.com | 5566f23 | 2015-10-05 17:05:24 +0000 | [diff] [blame] | 506 | case CacheType::Unset: |
| 507 | out.printf("unset"); |
| 508 | break; |
| 509 | default: |
| 510 | RELEASE_ASSERT_NOT_REACHED(); |
| 511 | break; |
| 512 | } |
| 513 | out.printf(")"); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 514 | } |
| 515 | #else |
| 516 | UNUSED_PARAM(map); |
| 517 | #endif |
| 518 | } |
| 519 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 520 | void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap& map) |
ggaren@apple.com | 6f82ad5 | 2012-01-12 01:00:58 +0000 | [diff] [blame] | 521 | { |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 522 | int dst = (++it)->u.operand; |
ggaren@apple.com | 6f82ad5 | 2012-01-12 01:00:58 +0000 | [diff] [blame] | 523 | int func = (++it)->u.operand; |
| 524 | int argCount = (++it)->u.operand; |
| 525 | int registerOffset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 526 | printLocationAndOp(out, exec, location, it, op); |
| 527 | out.printf("%s, %s, %d, %d", registerName(dst).data(), registerName(func).data(), argCount, registerOffset); |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 528 | if (cacheDumpMode == DumpCaches) { |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 529 | LLIntCallLinkInfo* callLinkInfo = it[1].u.callLinkInfo; |
| 530 | if (callLinkInfo->lastSeenCallee) { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 531 | out.printf( |
| 532 | " llint(%p, exec %p)", |
| 533 | callLinkInfo->lastSeenCallee.get(), |
| 534 | callLinkInfo->lastSeenCallee->executable()); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 535 | } |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 536 | #if ENABLE(JIT) |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 537 | if (CallLinkInfo* info = map.get(CodeOrigin(location))) { |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 538 | JSFunction* target = info->lastSeenCallee(); |
fpizlo@apple.com | 5e3852d | 2012-05-24 00:05:21 +0000 | [diff] [blame] | 539 | if (target) |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 540 | out.printf(" jit(%p, exec %p)", target, target->executable()); |
fpizlo@apple.com | 5e3852d | 2012-05-24 00:05:21 +0000 | [diff] [blame] | 541 | } |
mark.lam@apple.com | 507b94e | 2015-04-17 00:25:14 +0000 | [diff] [blame] | 542 | |
| 543 | if (jitType() != JITCode::FTLJIT) |
| 544 | out.print(" status(", CallLinkStatus::computeFor(this, location, map), ")"); |
fpizlo@apple.com | f7100b6 | 2014-03-24 17:29:51 +0000 | [diff] [blame] | 545 | #else |
| 546 | UNUSED_PARAM(map); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 547 | #endif |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 548 | } |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 549 | ++it; |
oliver@apple.com | 7ff89b1 | 2014-02-21 22:37:29 +0000 | [diff] [blame] | 550 | ++it; |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 551 | dumpArrayProfiling(out, it, hasPrintedProfiling); |
| 552 | dumpValueProfiling(out, it, hasPrintedProfiling); |
ggaren@apple.com | 6f82ad5 | 2012-01-12 01:00:58 +0000 | [diff] [blame] | 553 | } |
| 554 | |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 555 | void CodeBlock::printPutByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op) |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 556 | { |
| 557 | int r0 = (++it)->u.operand; |
| 558 | int id0 = (++it)->u.operand; |
| 559 | int r1 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 560 | printLocationAndOp(out, exec, location, it, op); |
| 561 | out.printf("%s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data()); |
oliver@apple.com | ef690aa | 2010-07-15 20:00:31 +0000 | [diff] [blame] | 562 | it += 5; |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 563 | } |
| 564 | |
mark.lam@apple.com | e7f8884 | 2015-04-02 22:46:52 +0000 | [diff] [blame] | 565 | void CodeBlock::dumpSource() |
| 566 | { |
| 567 | dumpSource(WTF::dataFile()); |
| 568 | } |
| 569 | |
| 570 | void CodeBlock::dumpSource(PrintStream& out) |
| 571 | { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 572 | ScriptExecutable* executable = ownerScriptExecutable(); |
mark.lam@apple.com | e7f8884 | 2015-04-02 22:46:52 +0000 | [diff] [blame] | 573 | if (executable->isFunctionExecutable()) { |
| 574 | FunctionExecutable* functionExecutable = reinterpret_cast<FunctionExecutable*>(executable); |
akling@apple.com | 7332098 | 2015-12-13 20:03:24 +0000 | [diff] [blame] | 575 | StringView source = functionExecutable->source().provider()->getRange( |
mark.lam@apple.com | e7f8884 | 2015-04-02 22:46:52 +0000 | [diff] [blame] | 576 | functionExecutable->parametersStartOffset(), |
| 577 | functionExecutable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'. |
| 578 | |
| 579 | out.print("function ", inferredName(), source); |
| 580 | return; |
| 581 | } |
akling@apple.com | 7332098 | 2015-12-13 20:03:24 +0000 | [diff] [blame] | 582 | out.print(executable->source().view()); |
mark.lam@apple.com | e7f8884 | 2015-04-02 22:46:52 +0000 | [diff] [blame] | 583 | } |
| 584 | |
| 585 | void CodeBlock::dumpBytecode() |
| 586 | { |
| 587 | dumpBytecode(WTF::dataFile()); |
| 588 | } |
| 589 | |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 590 | void CodeBlock::dumpBytecode(PrintStream& out) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 591 | { |
fpizlo@apple.com | 1949f32 | 2012-11-22 00:46:57 +0000 | [diff] [blame] | 592 | // We only use the ExecState* for things that don't actually lead to JS execution, |
| 593 | // like converting a JSString to a String. Hence the globalExec is appropriate. |
| 594 | ExecState* exec = m_globalObject->globalExec(); |
| 595 | |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 596 | size_t instructionCount = 0; |
weinig@apple.com | 0aaf82a | 2008-12-12 08:02:09 +0000 | [diff] [blame] | 597 | |
fpizlo@apple.com | 9ac73f1 | 2011-11-10 04:37:32 +0000 | [diff] [blame] | 598 | for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)]) |
weinig@apple.com | 0aaf82a | 2008-12-12 08:02:09 +0000 | [diff] [blame] | 599 | ++instructionCount; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 600 | |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 601 | out.print(*this); |
| 602 | out.printf( |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 603 | ": %lu m_instructions; %lu bytes; %d parameter(s); %d callee register(s); %d variable(s)", |
fpizlo@apple.com | ebe232e | 2012-02-27 02:07:34 +0000 | [diff] [blame] | 604 | static_cast<unsigned long>(instructions().size()), |
fpizlo@apple.com | 9ac73f1 | 2011-11-10 04:37:32 +0000 | [diff] [blame] | 605 | static_cast<unsigned long>(instructions().size() * sizeof(Instruction)), |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 606 | m_numParameters, m_numCalleeLocals, m_numVars); |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 607 | out.printf("\n"); |
| 608 | |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 609 | StubInfoMap stubInfos; |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 610 | CallLinkInfoMap callLinkInfos; |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 611 | getStubInfoMap(stubInfos); |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 612 | getCallLinkInfoMap(callLinkInfos); |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 613 | |
fpizlo@apple.com | 1949f32 | 2012-11-22 00:46:57 +0000 | [diff] [blame] | 614 | const Instruction* begin = instructions().begin(); |
| 615 | const Instruction* end = instructions().end(); |
| 616 | for (const Instruction* it = begin; it != end; ++it) |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 617 | dumpBytecode(out, exec, begin, it, stubInfos, callLinkInfos); |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 618 | |
oliver@apple.com | 9b65276 | 2013-08-12 22:39:13 +0000 | [diff] [blame] | 619 | if (numberOfIdentifiers()) { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 620 | out.printf("\nIdentifiers:\n"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 621 | size_t i = 0; |
| 622 | do { |
oliver@apple.com | 9b65276 | 2013-08-12 22:39:13 +0000 | [diff] [blame] | 623 | out.printf(" id%u = %s\n", static_cast<unsigned>(i), identifier(i).string().utf8().data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 624 | ++i; |
oliver@apple.com | 9b65276 | 2013-08-12 22:39:13 +0000 | [diff] [blame] | 625 | } while (i != numberOfIdentifiers()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 626 | } |
| 627 | |
weinig@apple.com | cb26d81 | 2008-12-06 22:01:05 +0000 | [diff] [blame] | 628 | if (!m_constantRegisters.isEmpty()) { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 629 | out.printf("\nConstants:\n"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 630 | size_t i = 0; |
| 631 | do { |
mark.lam@apple.com | 61ba1f3 | 2015-03-10 19:29:13 +0000 | [diff] [blame] | 632 | const char* sourceCodeRepresentationDescription = nullptr; |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 633 | switch (m_constantsSourceCodeRepresentation[i]) { |
| 634 | case SourceCodeRepresentation::Double: |
| 635 | sourceCodeRepresentationDescription = ": in source as double"; |
| 636 | break; |
| 637 | case SourceCodeRepresentation::Integer: |
| 638 | sourceCodeRepresentationDescription = ": in source as integer"; |
| 639 | break; |
| 640 | case SourceCodeRepresentation::Other: |
| 641 | sourceCodeRepresentationDescription = ""; |
| 642 | break; |
| 643 | } |
| 644 | out.printf(" k%u = %s%s\n", static_cast<unsigned>(i), toCString(m_constantRegisters[i].get()).data(), sourceCodeRepresentationDescription); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 645 | ++i; |
weinig@apple.com | cb26d81 | 2008-12-06 22:01:05 +0000 | [diff] [blame] | 646 | } while (i < m_constantRegisters.size()); |
cwzwarich@webkit.org | 300bb75 | 2008-08-06 10:37:34 +0000 | [diff] [blame] | 647 | } |
| 648 | |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 649 | if (size_t count = m_unlinkedCode->numberOfRegExps()) { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 650 | out.printf("\nm_regexps:\n"); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 651 | size_t i = 0; |
| 652 | do { |
oliver@apple.com | 0203946 | 2013-07-25 03:59:29 +0000 | [diff] [blame] | 653 | out.printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).data()); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 654 | ++i; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 655 | } while (i < count); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 656 | } |
| 657 | |
fpizlo@apple.com | 2101428 | 2016-01-08 21:42:23 +0000 | [diff] [blame] | 658 | dumpExceptionHandlers(out); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 659 | |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 660 | if (m_rareData && !m_rareData->m_switchJumpTables.isEmpty()) { |
| 661 | out.printf("Switch Jump Tables:\n"); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 662 | unsigned i = 0; |
| 663 | do { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 664 | out.printf(" %1d = {\n", i); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 665 | int entry = 0; |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 666 | Vector<int32_t>::const_iterator end = m_rareData->m_switchJumpTables[i].branchOffsets.end(); |
| 667 | for (Vector<int32_t>::const_iterator iter = m_rareData->m_switchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) { |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 668 | if (!*iter) |
| 669 | continue; |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 670 | out.printf("\t\t%4d => %04d\n", entry + m_rareData->m_switchJumpTables[i].min, *iter); |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 671 | } |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 672 | out.printf(" }\n"); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 673 | ++i; |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 674 | } while (i < m_rareData->m_switchJumpTables.size()); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 675 | } |
| 676 | |
weinig@apple.com | 4557e84 | 2008-12-09 01:06:14 +0000 | [diff] [blame] | 677 | if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 678 | out.printf("\nString Switch Jump Tables:\n"); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 679 | unsigned i = 0; |
| 680 | do { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 681 | out.printf(" %1d = {\n", i); |
weinig@apple.com | 4557e84 | 2008-12-09 01:06:14 +0000 | [diff] [blame] | 682 | StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end(); |
| 683 | for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter) |
msaboff@apple.com | c2d9471 | 2014-04-29 01:36:14 +0000 | [diff] [blame] | 684 | out.printf("\t\t\"%s\" => %04d\n", iter->key->utf8().data(), iter->value.branchOffset); |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 685 | out.printf(" }\n"); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 686 | ++i; |
weinig@apple.com | 4557e84 | 2008-12-09 01:06:14 +0000 | [diff] [blame] | 687 | } while (i < m_rareData->m_stringSwitchJumpTables.size()); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 688 | } |
| 689 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 690 | if (m_rareData && !m_rareData->m_liveCalleeLocalsAtYield.isEmpty()) { |
| 691 | out.printf("\nLive Callee Locals:\n"); |
| 692 | unsigned i = 0; |
| 693 | do { |
| 694 | const FastBitVector& liveness = m_rareData->m_liveCalleeLocalsAtYield[i]; |
| 695 | out.printf(" live%1u = ", i); |
| 696 | liveness.dump(out); |
| 697 | out.printf("\n"); |
| 698 | ++i; |
| 699 | } while (i < m_rareData->m_liveCalleeLocalsAtYield.size()); |
| 700 | } |
| 701 | |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 702 | out.printf("\n"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 703 | } |
| 704 | |
fpizlo@apple.com | 2101428 | 2016-01-08 21:42:23 +0000 | [diff] [blame] | 705 | void CodeBlock::dumpExceptionHandlers(PrintStream& out) |
| 706 | { |
| 707 | if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) { |
| 708 | out.printf("\nException Handlers:\n"); |
| 709 | unsigned i = 0; |
| 710 | do { |
| 711 | HandlerInfo& handler = m_rareData->m_exceptionHandlers[i]; |
| 712 | out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] } %s\n", |
| 713 | i + 1, handler.start, handler.end, handler.target, handler.typeName()); |
| 714 | ++i; |
| 715 | } while (i < m_rareData->m_exceptionHandlers.size()); |
| 716 | } |
| 717 | } |
| 718 | |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 719 | void CodeBlock::beginDumpProfiling(PrintStream& out, bool& hasPrintedProfiling) |
| 720 | { |
| 721 | if (hasPrintedProfiling) { |
| 722 | out.print("; "); |
| 723 | return; |
| 724 | } |
| 725 | |
| 726 | out.print(" "); |
| 727 | hasPrintedProfiling = true; |
| 728 | } |
| 729 | |
| 730 | void CodeBlock::dumpValueProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling) |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 731 | { |
oliver@apple.com | d205666 | 2013-07-25 04:00:37 +0000 | [diff] [blame] | 732 | ConcurrentJITLocker locker(m_lock); |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 733 | |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 734 | ++it; |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 735 | CString description = it->u.profile->briefDescription(locker); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 736 | if (!description.length()) |
| 737 | return; |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 738 | beginDumpProfiling(out, hasPrintedProfiling); |
| 739 | out.print(description); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 740 | } |
| 741 | |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 742 | void CodeBlock::dumpArrayProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling) |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 743 | { |
oliver@apple.com | d205666 | 2013-07-25 04:00:37 +0000 | [diff] [blame] | 744 | ConcurrentJITLocker locker(m_lock); |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 745 | |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 746 | ++it; |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 747 | if (!it->u.arrayProfile) |
| 748 | return; |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 749 | CString description = it->u.arrayProfile->briefDescription(locker, this); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 750 | if (!description.length()) |
| 751 | return; |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 752 | beginDumpProfiling(out, hasPrintedProfiling); |
| 753 | out.print(description); |
fpizlo@apple.com | 77ef0e3 | 2012-12-12 00:21:43 +0000 | [diff] [blame] | 754 | } |
| 755 | |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 756 | void CodeBlock::dumpRareCaseProfile(PrintStream& out, const char* name, RareCaseProfile* profile, bool& hasPrintedProfiling) |
| 757 | { |
| 758 | if (!profile || !profile->m_counter) |
| 759 | return; |
| 760 | |
| 761 | beginDumpProfiling(out, hasPrintedProfiling); |
| 762 | out.print(name, profile->m_counter); |
| 763 | } |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 764 | |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 765 | void CodeBlock::dumpResultProfile(PrintStream& out, ResultProfile* profile, bool& hasPrintedProfiling) |
| 766 | { |
| 767 | if (!profile) |
| 768 | return; |
| 769 | |
| 770 | beginDumpProfiling(out, hasPrintedProfiling); |
| 771 | out.print("results: ", *profile); |
| 772 | } |
| 773 | |
fpizlo@apple.com | 12803e2 | 2014-02-02 06:38:51 +0000 | [diff] [blame] | 774 | void CodeBlock::printLocationAndOp(PrintStream& out, ExecState*, int location, const Instruction*&, const char* op) |
| 775 | { |
| 776 | out.printf("[%4d] %-17s ", location, op); |
| 777 | } |
| 778 | |
| 779 | void CodeBlock::printLocationOpAndRegisterOperand(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, int operand) |
| 780 | { |
| 781 | printLocationAndOp(out, exec, location, it, op); |
| 782 | out.printf("%s", registerName(operand).data()); |
| 783 | } |
| 784 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 785 | void CodeBlock::dumpBytecode( |
| 786 | PrintStream& out, ExecState* exec, const Instruction* begin, const Instruction*& it, |
| 787 | const StubInfoMap& stubInfos, const CallLinkInfoMap& callLinkInfos) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 788 | { |
| 789 | int location = it - begin; |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 790 | bool hasPrintedProfiling = false; |
oliver@apple.com | 177c2b9 | 2014-03-28 01:10:25 +0000 | [diff] [blame] | 791 | OpcodeID opcode = exec->interpreter()->getOpcodeID(it->u.opcode); |
| 792 | switch (opcode) { |
mjs@apple.com | 8b246d6 | 2008-10-04 07:15:33 +0000 | [diff] [blame] | 793 | case op_enter: { |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 794 | printLocationAndOp(out, exec, location, it, "enter"); |
oliver@apple.com | ecfd224 | 2008-09-20 03:00:43 +0000 | [diff] [blame] | 795 | break; |
| 796 | } |
msaboff@apple.com | 8b6b341 | 2014-11-04 03:36:28 +0000 | [diff] [blame] | 797 | case op_get_scope: { |
| 798 | int r0 = (++it)->u.operand; |
| 799 | printLocationOpAndRegisterOperand(out, exec, location, it, "get_scope", r0); |
| 800 | break; |
| 801 | } |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 802 | case op_create_direct_arguments: { |
ggaren@apple.com | 83ce11c | 2010-05-19 05:10:11 +0000 | [diff] [blame] | 803 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 804 | printLocationAndOp(out, exec, location, it, "create_direct_arguments"); |
| 805 | out.printf("%s", registerName(r0).data()); |
cwzwarich@webkit.org | 9e464ca | 2008-09-29 03:04:08 +0000 | [diff] [blame] | 806 | break; |
| 807 | } |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 808 | case op_create_scoped_arguments: { |
ggaren@apple.com | 83ce11c | 2010-05-19 05:10:11 +0000 | [diff] [blame] | 809 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 810 | int r1 = (++it)->u.operand; |
| 811 | printLocationAndOp(out, exec, location, it, "create_scoped_arguments"); |
| 812 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
| 813 | break; |
| 814 | } |
keith_miller@apple.com | 2636739 | 2016-03-14 20:55:15 +0000 | [diff] [blame] | 815 | case op_create_cloned_arguments: { |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 816 | int r0 = (++it)->u.operand; |
keith_miller@apple.com | 2636739 | 2016-03-14 20:55:15 +0000 | [diff] [blame] | 817 | printLocationAndOp(out, exec, location, it, "create_cloned_arguments"); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 818 | out.printf("%s", registerName(r0).data()); |
oliver@apple.com | be38ac4 | 2009-05-12 08:58:56 +0000 | [diff] [blame] | 819 | break; |
| 820 | } |
sbarati@apple.com | c0722da | 2015-11-20 02:37:47 +0000 | [diff] [blame] | 821 | case op_copy_rest: { |
| 822 | int r0 = (++it)->u.operand; |
sbarati@apple.com | 855d560 | 2015-11-30 20:36:54 +0000 | [diff] [blame] | 823 | int r1 = (++it)->u.operand; |
| 824 | unsigned argumentOffset = (++it)->u.unsignedValue; |
sbarati@apple.com | c0722da | 2015-11-20 02:37:47 +0000 | [diff] [blame] | 825 | printLocationAndOp(out, exec, location, it, "copy_rest"); |
sbarati@apple.com | 855d560 | 2015-11-30 20:36:54 +0000 | [diff] [blame] | 826 | out.printf("%s, %s, ", registerName(r0).data(), registerName(r1).data()); |
| 827 | out.printf("ArgumentsOffset: %u", argumentOffset); |
| 828 | break; |
| 829 | } |
| 830 | case op_get_rest_length: { |
| 831 | int r0 = (++it)->u.operand; |
| 832 | printLocationAndOp(out, exec, location, it, "get_rest_length"); |
sbarati@apple.com | c0722da | 2015-11-20 02:37:47 +0000 | [diff] [blame] | 833 | out.printf("%s, ", registerName(r0).data()); |
| 834 | unsigned argumentOffset = (++it)->u.unsignedValue; |
| 835 | out.printf("ArgumentsOffset: %u", argumentOffset); |
| 836 | break; |
| 837 | } |
barraclough@apple.com | fd8c28a | 2010-05-25 03:04:43 +0000 | [diff] [blame] | 838 | case op_create_this: { |
| 839 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | c2c6763 | 2012-11-17 08:37:14 +0000 | [diff] [blame] | 840 | int r1 = (++it)->u.operand; |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 841 | unsigned inferredInlineCapacity = (++it)->u.operand; |
rniwa@webkit.org | 1b971d7 | 2015-05-14 04:19:18 +0000 | [diff] [blame] | 842 | unsigned cachedFunction = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 843 | printLocationAndOp(out, exec, location, it, "create_this"); |
rniwa@webkit.org | 1b971d7 | 2015-05-14 04:19:18 +0000 | [diff] [blame] | 844 | out.printf("%s, %s, %u, %u", registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity, cachedFunction); |
barraclough@apple.com | fd8c28a | 2010-05-25 03:04:43 +0000 | [diff] [blame] | 845 | break; |
| 846 | } |
oliver@apple.com | e2fe4ce | 2013-07-25 03:59:41 +0000 | [diff] [blame] | 847 | case op_to_this: { |
mjs@apple.com | 8b246d6 | 2008-10-04 07:15:33 +0000 | [diff] [blame] | 848 | int r0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 849 | printLocationOpAndRegisterOperand(out, exec, location, it, "to_this", r0); |
fpizlo@apple.com | 12803e2 | 2014-02-02 06:38:51 +0000 | [diff] [blame] | 850 | Structure* structure = (++it)->u.structure.get(); |
| 851 | if (structure) |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 852 | out.print(", cache(struct = ", RawPointer(structure), ")"); |
| 853 | out.print(", ", (++it)->u.toThisStatus); |
mjs@apple.com | 8b246d6 | 2008-10-04 07:15:33 +0000 | [diff] [blame] | 854 | break; |
| 855 | } |
rniwa@webkit.org | eb7ac19 | 2015-03-13 01:11:15 +0000 | [diff] [blame] | 856 | case op_check_tdz: { |
| 857 | int r0 = (++it)->u.operand; |
| 858 | printLocationOpAndRegisterOperand(out, exec, location, it, "op_check_tdz", r0); |
| 859 | break; |
| 860 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 861 | case op_new_object: { |
| 862 | int r0 = (++it)->u.operand; |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 863 | unsigned inferredInlineCapacity = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 864 | printLocationAndOp(out, exec, location, it, "new_object"); |
| 865 | out.printf("%s, %u", registerName(r0).data(), inferredInlineCapacity); |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 866 | ++it; // Skip object allocation profile. |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 867 | break; |
| 868 | } |
| 869 | case op_new_array: { |
darin@apple.com | 9ce7902 | 2008-06-28 15:50:49 +0000 | [diff] [blame] | 870 | int dst = (++it)->u.operand; |
| 871 | int argv = (++it)->u.operand; |
| 872 | int argc = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 873 | printLocationAndOp(out, exec, location, it, "new_array"); |
| 874 | out.printf("%s, %s, %d", registerName(dst).data(), registerName(argv).data(), argc); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 875 | ++it; // Skip array allocation profile. |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 876 | break; |
| 877 | } |
fpizlo@apple.com | 4500e35 | 2012-10-17 21:39:11 +0000 | [diff] [blame] | 878 | case op_new_array_with_size: { |
| 879 | int dst = (++it)->u.operand; |
| 880 | int length = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 881 | printLocationAndOp(out, exec, location, it, "new_array_with_size"); |
| 882 | out.printf("%s, %s", registerName(dst).data(), registerName(length).data()); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 883 | ++it; // Skip array allocation profile. |
fpizlo@apple.com | 4500e35 | 2012-10-17 21:39:11 +0000 | [diff] [blame] | 884 | break; |
| 885 | } |
oliver@apple.com | a991d69 | 2011-06-14 23:39:25 +0000 | [diff] [blame] | 886 | case op_new_array_buffer: { |
| 887 | int dst = (++it)->u.operand; |
| 888 | int argv = (++it)->u.operand; |
| 889 | int argc = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 890 | printLocationAndOp(out, exec, location, it, "new_array_buffer"); |
| 891 | out.printf("%s, %d, %d", registerName(dst).data(), argv, argc); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 892 | ++it; // Skip array allocation profile. |
oliver@apple.com | a991d69 | 2011-06-14 23:39:25 +0000 | [diff] [blame] | 893 | break; |
| 894 | } |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 895 | case op_new_regexp: { |
| 896 | int r0 = (++it)->u.operand; |
| 897 | int re0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 898 | printLocationAndOp(out, exec, location, it, "new_regexp"); |
| 899 | out.printf("%s, ", registerName(r0).data()); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 900 | if (r0 >=0 && r0 < (int)m_unlinkedCode->numberOfRegExps()) |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 901 | out.printf("%s", regexpName(re0, regexp(re0)).data()); |
fpizlo@apple.com | 68186e1 | 2011-08-17 20:54:32 +0000 | [diff] [blame] | 902 | else |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 903 | out.printf("bad_regexp(%d)", re0); |
oliver@apple.com | 22d55c3 | 2010-05-10 01:41:07 +0000 | [diff] [blame] | 904 | break; |
| 905 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 906 | case op_mov: { |
| 907 | int r0 = (++it)->u.operand; |
| 908 | int r1 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 909 | printLocationAndOp(out, exec, location, it, "mov"); |
| 910 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 911 | break; |
| 912 | } |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 913 | case op_profile_type: { |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 914 | int r0 = (++it)->u.operand; |
| 915 | ++it; |
| 916 | ++it; |
commit-queue@webkit.org | 0163f12 | 2014-08-21 02:29:47 +0000 | [diff] [blame] | 917 | ++it; |
| 918 | ++it; |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 919 | printLocationAndOp(out, exec, location, it, "op_profile_type"); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 920 | out.printf("%s", registerName(r0).data()); |
| 921 | break; |
| 922 | } |
saambarati1@gmail.com | b4f28a5 | 2014-12-05 05:58:07 +0000 | [diff] [blame] | 923 | case op_profile_control_flow: { |
| 924 | BasicBlockLocation* basicBlockLocation = (++it)->u.basicBlockLocation; |
| 925 | printLocationAndOp(out, exec, location, it, "profile_control_flow"); |
| 926 | out.printf("[%d, %d]", basicBlockLocation->startOffset(), basicBlockLocation->endOffset()); |
| 927 | break; |
| 928 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 929 | case op_not: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 930 | printUnaryOp(out, exec, location, it, "not"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 931 | break; |
| 932 | } |
| 933 | case op_eq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 934 | printBinaryOp(out, exec, location, it, "eq"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 935 | break; |
| 936 | } |
ggaren@apple.com | f15b1880 | 2008-09-03 02:58:14 +0000 | [diff] [blame] | 937 | case op_eq_null: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 938 | printUnaryOp(out, exec, location, it, "eq_null"); |
ggaren@apple.com | f15b1880 | 2008-09-03 02:58:14 +0000 | [diff] [blame] | 939 | break; |
| 940 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 941 | case op_neq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 942 | printBinaryOp(out, exec, location, it, "neq"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 943 | break; |
| 944 | } |
ggaren@apple.com | f15b1880 | 2008-09-03 02:58:14 +0000 | [diff] [blame] | 945 | case op_neq_null: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 946 | printUnaryOp(out, exec, location, it, "neq_null"); |
ggaren@apple.com | f15b1880 | 2008-09-03 02:58:14 +0000 | [diff] [blame] | 947 | break; |
| 948 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 949 | case op_stricteq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 950 | printBinaryOp(out, exec, location, it, "stricteq"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 951 | break; |
| 952 | } |
| 953 | case op_nstricteq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 954 | printBinaryOp(out, exec, location, it, "nstricteq"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 955 | break; |
| 956 | } |
| 957 | case op_less: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 958 | printBinaryOp(out, exec, location, it, "less"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 959 | break; |
| 960 | } |
| 961 | case op_lesseq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 962 | printBinaryOp(out, exec, location, it, "lesseq"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 963 | break; |
| 964 | } |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 965 | case op_greater: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 966 | printBinaryOp(out, exec, location, it, "greater"); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 967 | break; |
| 968 | } |
| 969 | case op_greatereq: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 970 | printBinaryOp(out, exec, location, it, "greatereq"); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 971 | break; |
| 972 | } |
ggaren@apple.com | f303611 | 2013-04-27 23:14:04 +0000 | [diff] [blame] | 973 | case op_inc: { |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 974 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | 9bca4b8 | 2013-11-11 21:46:37 +0000 | [diff] [blame] | 975 | printLocationOpAndRegisterOperand(out, exec, location, it, "inc", r0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 976 | break; |
| 977 | } |
ggaren@apple.com | f303611 | 2013-04-27 23:14:04 +0000 | [diff] [blame] | 978 | case op_dec: { |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 979 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | 9bca4b8 | 2013-11-11 21:46:37 +0000 | [diff] [blame] | 980 | printLocationOpAndRegisterOperand(out, exec, location, it, "dec", r0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 981 | break; |
| 982 | } |
ggaren@apple.com | f303611 | 2013-04-27 23:14:04 +0000 | [diff] [blame] | 983 | case op_to_number: { |
| 984 | printUnaryOp(out, exec, location, it, "to_number"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 985 | break; |
| 986 | } |
utatane.tea@gmail.com | 4014aea | 2015-04-27 00:27:28 +0000 | [diff] [blame] | 987 | case op_to_string: { |
| 988 | printUnaryOp(out, exec, location, it, "to_string"); |
| 989 | break; |
| 990 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 991 | case op_negate: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 992 | printUnaryOp(out, exec, location, it, "negate"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 993 | break; |
| 994 | } |
| 995 | case op_add: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 996 | printBinaryOp(out, exec, location, it, "add"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 997 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 998 | break; |
| 999 | } |
| 1000 | case op_mul: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1001 | printBinaryOp(out, exec, location, it, "mul"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 1002 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1003 | break; |
| 1004 | } |
| 1005 | case op_div: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1006 | printBinaryOp(out, exec, location, it, "div"); |
ggaren@apple.com | 540d71a6 | 2009-07-30 20:57:44 +0000 | [diff] [blame] | 1007 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1008 | break; |
| 1009 | } |
| 1010 | case op_mod: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1011 | printBinaryOp(out, exec, location, it, "mod"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1012 | break; |
| 1013 | } |
| 1014 | case op_sub: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1015 | printBinaryOp(out, exec, location, it, "sub"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 1016 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1017 | break; |
| 1018 | } |
| 1019 | case op_lshift: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1020 | printBinaryOp(out, exec, location, it, "lshift"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1021 | break; |
| 1022 | } |
| 1023 | case op_rshift: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1024 | printBinaryOp(out, exec, location, it, "rshift"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1025 | break; |
| 1026 | } |
| 1027 | case op_urshift: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1028 | printBinaryOp(out, exec, location, it, "urshift"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1029 | break; |
| 1030 | } |
| 1031 | case op_bitand: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1032 | printBinaryOp(out, exec, location, it, "bitand"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 1033 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1034 | break; |
| 1035 | } |
| 1036 | case op_bitxor: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1037 | printBinaryOp(out, exec, location, it, "bitxor"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 1038 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1039 | break; |
| 1040 | } |
| 1041 | case op_bitor: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1042 | printBinaryOp(out, exec, location, it, "bitor"); |
barraclough@apple.com | b8b15e2 | 2008-09-27 01:44:15 +0000 | [diff] [blame] | 1043 | ++it; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1044 | break; |
| 1045 | } |
keith_miller@apple.com | cb11fe4 | 2015-12-18 00:37:35 +0000 | [diff] [blame] | 1046 | case op_overrides_has_instance: { |
barraclough@apple.com | b46d57b4 | 2012-09-22 00:43:03 +0000 | [diff] [blame] | 1047 | int r0 = (++it)->u.operand; |
| 1048 | int r1 = (++it)->u.operand; |
| 1049 | int r2 = (++it)->u.operand; |
keith_miller@apple.com | cb11fe4 | 2015-12-18 00:37:35 +0000 | [diff] [blame] | 1050 | printLocationAndOp(out, exec, location, it, "overrides_has_instance"); |
| 1051 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
barraclough@apple.com | 8da6d97 | 2010-11-16 21:11:26 +0000 | [diff] [blame] | 1052 | break; |
| 1053 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1054 | case op_instanceof: { |
mjs@apple.com | 988df6c | 2008-09-15 02:13:10 +0000 | [diff] [blame] | 1055 | int r0 = (++it)->u.operand; |
| 1056 | int r1 = (++it)->u.operand; |
| 1057 | int r2 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1058 | printLocationAndOp(out, exec, location, it, "instanceof"); |
| 1059 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1060 | break; |
| 1061 | } |
keith_miller@apple.com | cb11fe4 | 2015-12-18 00:37:35 +0000 | [diff] [blame] | 1062 | case op_instanceof_custom: { |
| 1063 | int r0 = (++it)->u.operand; |
| 1064 | int r1 = (++it)->u.operand; |
| 1065 | int r2 = (++it)->u.operand; |
| 1066 | int r3 = (++it)->u.operand; |
| 1067 | printLocationAndOp(out, exec, location, it, "instanceof_custom"); |
| 1068 | out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); |
| 1069 | break; |
| 1070 | } |
fpizlo@apple.com | 9089acb | 2013-12-14 06:33:42 +0000 | [diff] [blame] | 1071 | case op_unsigned: { |
| 1072 | printUnaryOp(out, exec, location, it, "unsigned"); |
| 1073 | break; |
| 1074 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1075 | case op_typeof: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1076 | printUnaryOp(out, exec, location, it, "typeof"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1077 | break; |
| 1078 | } |
gskachkov@gmail.com | 086f8f6 | 2016-04-26 18:40:41 +0000 | [diff] [blame] | 1079 | case op_is_empty: { |
| 1080 | printUnaryOp(out, exec, location, it, "is_empty"); |
| 1081 | break; |
| 1082 | } |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1083 | case op_is_undefined: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1084 | printUnaryOp(out, exec, location, it, "is_undefined"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1085 | break; |
| 1086 | } |
| 1087 | case op_is_boolean: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1088 | printUnaryOp(out, exec, location, it, "is_boolean"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1089 | break; |
| 1090 | } |
| 1091 | case op_is_number: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1092 | printUnaryOp(out, exec, location, it, "is_number"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1093 | break; |
| 1094 | } |
| 1095 | case op_is_string: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1096 | printUnaryOp(out, exec, location, it, "is_string"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1097 | break; |
| 1098 | } |
| 1099 | case op_is_object: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1100 | printUnaryOp(out, exec, location, it, "is_object"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1101 | break; |
| 1102 | } |
utatane.tea@gmail.com | 0bfb74c | 2015-02-24 23:01:58 +0000 | [diff] [blame] | 1103 | case op_is_object_or_null: { |
| 1104 | printUnaryOp(out, exec, location, it, "is_object_or_null"); |
| 1105 | break; |
| 1106 | } |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1107 | case op_is_function: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1108 | printUnaryOp(out, exec, location, it, "is_function"); |
cwzwarich@webkit.org | 3234662 | 2008-09-15 00:26:08 +0000 | [diff] [blame] | 1109 | break; |
| 1110 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1111 | case op_in: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1112 | printBinaryOp(out, exec, location, it, "in"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1113 | break; |
| 1114 | } |
keith_miller@apple.com | 8844d30 | 2016-04-07 19:38:00 +0000 | [diff] [blame] | 1115 | case op_try_get_by_id: { |
| 1116 | int r0 = (++it)->u.operand; |
| 1117 | int r1 = (++it)->u.operand; |
| 1118 | int id0 = (++it)->u.operand; |
| 1119 | printLocationAndOp(out, exec, location, it, "try_get_by_id"); |
| 1120 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); |
| 1121 | break; |
| 1122 | } |
fpizlo@apple.com | d52a794 | 2012-05-21 22:32:40 +0000 | [diff] [blame] | 1123 | case op_get_by_id: |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 1124 | case op_get_by_id_proto_load: |
keith_miller@apple.com | 785c651 | 2016-05-27 18:36:30 +0000 | [diff] [blame^] | 1125 | case op_get_by_id_unset: |
fpizlo@apple.com | 970d8a9 | 2014-02-14 05:37:38 +0000 | [diff] [blame] | 1126 | case op_get_array_length: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1127 | printGetByIdOp(out, exec, location, it); |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1128 | printGetByIdCacheStatus(out, exec, location, stubInfos); |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1129 | dumpValueProfiling(out, it, hasPrintedProfiling); |
ggaren@apple.com | bc36309 | 2008-09-03 05:04:39 +0000 | [diff] [blame] | 1130 | break; |
| 1131 | } |
sbarati@apple.com | 23315d6 | 2016-05-09 20:17:23 +0000 | [diff] [blame] | 1132 | case op_get_by_id_with_this: { |
| 1133 | printLocationAndOp(out, exec, location, it, "get_by_id_with_this"); |
| 1134 | int r0 = (++it)->u.operand; |
| 1135 | int r1 = (++it)->u.operand; |
| 1136 | int r2 = (++it)->u.operand; |
| 1137 | int id0 = (++it)->u.operand; |
| 1138 | out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), idName(id0, identifier(id0)).data()); |
| 1139 | break; |
| 1140 | } |
| 1141 | case op_get_by_val_with_this: { |
| 1142 | int r0 = (++it)->u.operand; |
| 1143 | int r1 = (++it)->u.operand; |
| 1144 | int r2 = (++it)->u.operand; |
| 1145 | int r3 = (++it)->u.operand; |
| 1146 | printLocationAndOp(out, exec, location, it, "get_by_val_with_this"); |
| 1147 | out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); |
| 1148 | break; |
| 1149 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1150 | case op_put_by_id: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1151 | printPutByIdOp(out, exec, location, it, "put_by_id"); |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 1152 | printPutByIdCacheStatus(out, location, stubInfos); |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 1153 | break; |
| 1154 | } |
sbarati@apple.com | 23315d6 | 2016-05-09 20:17:23 +0000 | [diff] [blame] | 1155 | case op_put_by_id_with_this: { |
| 1156 | int r0 = (++it)->u.operand; |
| 1157 | int r1 = (++it)->u.operand; |
| 1158 | int id0 = (++it)->u.operand; |
| 1159 | int r2 = (++it)->u.operand; |
| 1160 | printLocationAndOp(out, exec, location, it, "put_by_id_with_this"); |
| 1161 | out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(), registerName(r2).data()); |
| 1162 | break; |
| 1163 | } |
| 1164 | case op_put_by_val_with_this: { |
| 1165 | int r0 = (++it)->u.operand; |
| 1166 | int r1 = (++it)->u.operand; |
| 1167 | int r2 = (++it)->u.operand; |
| 1168 | int r3 = (++it)->u.operand; |
| 1169 | printLocationAndOp(out, exec, location, it, "put_by_val_with_this"); |
| 1170 | out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); |
| 1171 | break; |
| 1172 | } |
commit-queue@webkit.org | fb471b4 | 2015-05-14 01:32:25 +0000 | [diff] [blame] | 1173 | case op_put_getter_by_id: { |
| 1174 | int r0 = (++it)->u.operand; |
| 1175 | int id0 = (++it)->u.operand; |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1176 | int n0 = (++it)->u.operand; |
commit-queue@webkit.org | fb471b4 | 2015-05-14 01:32:25 +0000 | [diff] [blame] | 1177 | int r1 = (++it)->u.operand; |
| 1178 | printLocationAndOp(out, exec, location, it, "put_getter_by_id"); |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1179 | out.printf("%s, %s, %d, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data()); |
commit-queue@webkit.org | fb471b4 | 2015-05-14 01:32:25 +0000 | [diff] [blame] | 1180 | break; |
| 1181 | } |
| 1182 | case op_put_setter_by_id: { |
| 1183 | int r0 = (++it)->u.operand; |
| 1184 | int id0 = (++it)->u.operand; |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1185 | int n0 = (++it)->u.operand; |
commit-queue@webkit.org | fb471b4 | 2015-05-14 01:32:25 +0000 | [diff] [blame] | 1186 | int r1 = (++it)->u.operand; |
| 1187 | printLocationAndOp(out, exec, location, it, "put_setter_by_id"); |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1188 | out.printf("%s, %s, %d, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data()); |
commit-queue@webkit.org | fb471b4 | 2015-05-14 01:32:25 +0000 | [diff] [blame] | 1189 | break; |
| 1190 | } |
utatane.tea@gmail.com | 059a71f | 2015-11-02 18:32:55 +0000 | [diff] [blame] | 1191 | case op_put_getter_setter_by_id: { |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1192 | int r0 = (++it)->u.operand; |
| 1193 | int id0 = (++it)->u.operand; |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1194 | int n0 = (++it)->u.operand; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1195 | int r1 = (++it)->u.operand; |
barraclough@apple.com | 09a5568 | 2012-01-30 18:28:39 +0000 | [diff] [blame] | 1196 | int r2 = (++it)->u.operand; |
utatane.tea@gmail.com | 059a71f | 2015-11-02 18:32:55 +0000 | [diff] [blame] | 1197 | printLocationAndOp(out, exec, location, it, "put_getter_setter_by_id"); |
rniwa@webkit.org | 87ae29c | 2015-08-14 23:50:25 +0000 | [diff] [blame] | 1198 | out.printf("%s, %s, %d, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data(), registerName(r2).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1199 | break; |
| 1200 | } |
utatane.tea@gmail.com | f0153d0 | 2015-09-08 19:43:58 +0000 | [diff] [blame] | 1201 | case op_put_getter_by_val: { |
| 1202 | int r0 = (++it)->u.operand; |
| 1203 | int r1 = (++it)->u.operand; |
| 1204 | int n0 = (++it)->u.operand; |
| 1205 | int r2 = (++it)->u.operand; |
| 1206 | printLocationAndOp(out, exec, location, it, "put_getter_by_val"); |
| 1207 | out.printf("%s, %s, %d, %s", registerName(r0).data(), registerName(r1).data(), n0, registerName(r2).data()); |
| 1208 | break; |
| 1209 | } |
| 1210 | case op_put_setter_by_val: { |
| 1211 | int r0 = (++it)->u.operand; |
| 1212 | int r1 = (++it)->u.operand; |
| 1213 | int n0 = (++it)->u.operand; |
| 1214 | int r2 = (++it)->u.operand; |
| 1215 | printLocationAndOp(out, exec, location, it, "put_setter_by_val"); |
| 1216 | out.printf("%s, %s, %d, %s", registerName(r0).data(), registerName(r1).data(), n0, registerName(r2).data()); |
| 1217 | break; |
| 1218 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1219 | case op_del_by_id: { |
| 1220 | int r0 = (++it)->u.operand; |
| 1221 | int r1 = (++it)->u.operand; |
| 1222 | int id0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1223 | printLocationAndOp(out, exec, location, it, "del_by_id"); |
| 1224 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1225 | break; |
| 1226 | } |
| 1227 | case op_get_by_val: { |
| 1228 | int r0 = (++it)->u.operand; |
| 1229 | int r1 = (++it)->u.operand; |
| 1230 | int r2 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1231 | printLocationAndOp(out, exec, location, it, "get_by_val"); |
| 1232 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1233 | dumpArrayProfiling(out, it, hasPrintedProfiling); |
| 1234 | dumpValueProfiling(out, it, hasPrintedProfiling); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1235 | break; |
| 1236 | } |
| 1237 | case op_put_by_val: { |
| 1238 | int r0 = (++it)->u.operand; |
| 1239 | int r1 = (++it)->u.operand; |
| 1240 | int r2 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1241 | printLocationAndOp(out, exec, location, it, "put_by_val"); |
| 1242 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1243 | dumpArrayProfiling(out, it, hasPrintedProfiling); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1244 | break; |
| 1245 | } |
oliver@apple.com | e050d64 | 2013-10-19 00:09:28 +0000 | [diff] [blame] | 1246 | case op_put_by_val_direct: { |
| 1247 | int r0 = (++it)->u.operand; |
| 1248 | int r1 = (++it)->u.operand; |
| 1249 | int r2 = (++it)->u.operand; |
| 1250 | printLocationAndOp(out, exec, location, it, "put_by_val_direct"); |
| 1251 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
| 1252 | dumpArrayProfiling(out, it, hasPrintedProfiling); |
| 1253 | break; |
| 1254 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1255 | case op_del_by_val: { |
| 1256 | int r0 = (++it)->u.operand; |
| 1257 | int r1 = (++it)->u.operand; |
| 1258 | int r2 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1259 | printLocationAndOp(out, exec, location, it, "del_by_val"); |
| 1260 | out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1261 | break; |
| 1262 | } |
| 1263 | case op_put_by_index: { |
| 1264 | int r0 = (++it)->u.operand; |
| 1265 | unsigned n0 = (++it)->u.operand; |
| 1266 | int r1 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1267 | printLocationAndOp(out, exec, location, it, "put_by_index"); |
| 1268 | out.printf("%s, %u, %s", registerName(r0).data(), n0, registerName(r1).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1269 | break; |
| 1270 | } |
| 1271 | case op_jmp: { |
| 1272 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1273 | printLocationAndOp(out, exec, location, it, "jmp"); |
| 1274 | out.printf("%d(->%d)", offset, location + offset); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1275 | break; |
| 1276 | } |
| 1277 | case op_jtrue: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1278 | printConditionalJump(out, exec, begin, it, location, "jtrue"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1279 | break; |
| 1280 | } |
| 1281 | case op_jfalse: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1282 | printConditionalJump(out, exec, begin, it, location, "jfalse"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1283 | break; |
| 1284 | } |
cwzwarich@webkit.org | b8b3024 | 2008-10-22 21:06:30 +0000 | [diff] [blame] | 1285 | case op_jeq_null: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1286 | printConditionalJump(out, exec, begin, it, location, "jeq_null"); |
cwzwarich@webkit.org | b8b3024 | 2008-10-22 21:06:30 +0000 | [diff] [blame] | 1287 | break; |
| 1288 | } |
| 1289 | case op_jneq_null: { |
fpizlo@apple.com | 1afcdf0 | 2012-12-02 08:00:14 +0000 | [diff] [blame] | 1290 | printConditionalJump(out, exec, begin, it, location, "jneq_null"); |
cwzwarich@webkit.org | b8b3024 | 2008-10-22 21:06:30 +0000 | [diff] [blame] | 1291 | break; |
| 1292 | } |
oliver@apple.com | 6c10600 | 2009-03-28 03:50:39 +0000 | [diff] [blame] | 1293 | case op_jneq_ptr: { |
cwzwarich@webkit.org | 7b04fef | 2008-06-30 06:17:01 +0000 | [diff] [blame] | 1294 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | 4500e35 | 2012-10-17 21:39:11 +0000 | [diff] [blame] | 1295 | Special::Pointer pointer = (++it)->u.specialPointer; |
cwzwarich@webkit.org | 7b04fef | 2008-06-30 06:17:01 +0000 | [diff] [blame] | 1296 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1297 | printLocationAndOp(out, exec, location, it, "jneq_ptr"); |
| 1298 | out.printf("%s, %d (%p), %d(->%d)", registerName(r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset); |
oliver@apple.com | 6c10600 | 2009-03-28 03:50:39 +0000 | [diff] [blame] | 1299 | break; |
| 1300 | } |
mjs@apple.com | a46c49c | 2009-12-06 09:42:03 +0000 | [diff] [blame] | 1301 | case op_jless: { |
| 1302 | int r0 = (++it)->u.operand; |
| 1303 | int r1 = (++it)->u.operand; |
| 1304 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1305 | printLocationAndOp(out, exec, location, it, "jless"); |
| 1306 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
mjs@apple.com | a46c49c | 2009-12-06 09:42:03 +0000 | [diff] [blame] | 1307 | break; |
| 1308 | } |
oliver@apple.com | 5230bd3 | 2010-05-06 19:39:54 +0000 | [diff] [blame] | 1309 | case op_jlesseq: { |
| 1310 | int r0 = (++it)->u.operand; |
| 1311 | int r1 = (++it)->u.operand; |
| 1312 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1313 | printLocationAndOp(out, exec, location, it, "jlesseq"); |
| 1314 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
oliver@apple.com | 5230bd3 | 2010-05-06 19:39:54 +0000 | [diff] [blame] | 1315 | break; |
| 1316 | } |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1317 | case op_jgreater: { |
| 1318 | int r0 = (++it)->u.operand; |
| 1319 | int r1 = (++it)->u.operand; |
| 1320 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1321 | printLocationAndOp(out, exec, location, it, "jgreater"); |
| 1322 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1323 | break; |
| 1324 | } |
| 1325 | case op_jgreatereq: { |
| 1326 | int r0 = (++it)->u.operand; |
| 1327 | int r1 = (++it)->u.operand; |
| 1328 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1329 | printLocationAndOp(out, exec, location, it, "jgreatereq"); |
| 1330 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1331 | break; |
| 1332 | } |
| 1333 | case op_jnless: { |
| 1334 | int r0 = (++it)->u.operand; |
| 1335 | int r1 = (++it)->u.operand; |
| 1336 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1337 | printLocationAndOp(out, exec, location, it, "jnless"); |
| 1338 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1339 | break; |
| 1340 | } |
| 1341 | case op_jnlesseq: { |
| 1342 | int r0 = (++it)->u.operand; |
| 1343 | int r1 = (++it)->u.operand; |
| 1344 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1345 | printLocationAndOp(out, exec, location, it, "jnlesseq"); |
| 1346 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1347 | break; |
| 1348 | } |
| 1349 | case op_jngreater: { |
| 1350 | int r0 = (++it)->u.operand; |
| 1351 | int r1 = (++it)->u.operand; |
| 1352 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1353 | printLocationAndOp(out, exec, location, it, "jngreater"); |
| 1354 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1355 | break; |
| 1356 | } |
| 1357 | case op_jngreatereq: { |
| 1358 | int r0 = (++it)->u.operand; |
| 1359 | int r1 = (++it)->u.operand; |
| 1360 | int offset = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1361 | printLocationAndOp(out, exec, location, it, "jngreatereq"); |
| 1362 | out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); |
barraclough@apple.com | 57b4bdb8 | 2011-07-04 19:26:05 +0000 | [diff] [blame] | 1363 | break; |
| 1364 | } |
fpizlo@apple.com | a71ab05 | 2011-09-13 05:35:53 +0000 | [diff] [blame] | 1365 | case op_loop_hint: { |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1366 | printLocationAndOp(out, exec, location, it, "loop_hint"); |
fpizlo@apple.com | a71ab05 | 2011-09-13 05:35:53 +0000 | [diff] [blame] | 1367 | break; |
| 1368 | } |
sbarati@apple.com | 390337b | 2015-12-07 22:03:48 +0000 | [diff] [blame] | 1369 | case op_watchdog: { |
| 1370 | printLocationAndOp(out, exec, location, it, "watchdog"); |
| 1371 | break; |
| 1372 | } |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 1373 | case op_log_shadow_chicken_prologue: { |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 1374 | int r0 = (++it)->u.operand; |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 1375 | printLocationAndOp(out, exec, location, it, "log_shadow_chicken_prologue"); |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 1376 | out.printf("%s", registerName(r0).data()); |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 1377 | break; |
| 1378 | } |
| 1379 | case op_log_shadow_chicken_tail: { |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 1380 | int r0 = (++it)->u.operand; |
| 1381 | int r1 = (++it)->u.operand; |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 1382 | printLocationAndOp(out, exec, location, it, "log_shadow_chicken_tail"); |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 1383 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 1384 | break; |
| 1385 | } |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 1386 | case op_switch_imm: { |
| 1387 | int tableIndex = (++it)->u.operand; |
| 1388 | int defaultTarget = (++it)->u.operand; |
| 1389 | int scrutineeRegister = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1390 | printLocationAndOp(out, exec, location, it, "switch_imm"); |
| 1391 | out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 1392 | break; |
| 1393 | } |
| 1394 | case op_switch_char: { |
| 1395 | int tableIndex = (++it)->u.operand; |
| 1396 | int defaultTarget = (++it)->u.operand; |
| 1397 | int scrutineeRegister = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1398 | printLocationAndOp(out, exec, location, it, "switch_char"); |
| 1399 | out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 1400 | break; |
| 1401 | } |
| 1402 | case op_switch_string: { |
| 1403 | int tableIndex = (++it)->u.operand; |
| 1404 | int defaultTarget = (++it)->u.operand; |
| 1405 | int scrutineeRegister = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1406 | printLocationAndOp(out, exec, location, it, "switch_string"); |
| 1407 | out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); |
oliver@apple.com | 8007f46 | 2008-07-24 00:49:46 +0000 | [diff] [blame] | 1408 | break; |
| 1409 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1410 | case op_new_func: { |
| 1411 | int r0 = (++it)->u.operand; |
msaboff@apple.com | ea77cd0 | 2014-11-14 01:07:48 +0000 | [diff] [blame] | 1412 | int r1 = (++it)->u.operand; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1413 | int f0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1414 | printLocationAndOp(out, exec, location, it, "new_func"); |
commit-queue@webkit.org | 9c3b1a5 | 2016-03-09 22:34:08 +0000 | [diff] [blame] | 1415 | out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1416 | break; |
| 1417 | } |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1418 | case op_new_generator_func: { |
| 1419 | int r0 = (++it)->u.operand; |
| 1420 | int r1 = (++it)->u.operand; |
| 1421 | int f0 = (++it)->u.operand; |
| 1422 | printLocationAndOp(out, exec, location, it, "new_generator_func"); |
commit-queue@webkit.org | 9c3b1a5 | 2016-03-09 22:34:08 +0000 | [diff] [blame] | 1423 | out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1424 | break; |
| 1425 | } |
commit-queue@webkit.org | a4201b0 | 2015-08-17 22:24:20 +0000 | [diff] [blame] | 1426 | case op_new_arrow_func_exp: { |
| 1427 | int r0 = (++it)->u.operand; |
| 1428 | int r1 = (++it)->u.operand; |
| 1429 | int f0 = (++it)->u.operand; |
commit-queue@webkit.org | a4201b0 | 2015-08-17 22:24:20 +0000 | [diff] [blame] | 1430 | printLocationAndOp(out, exec, location, it, "op_new_arrow_func_exp"); |
commit-queue@webkit.org | 9c3b1a5 | 2016-03-09 22:34:08 +0000 | [diff] [blame] | 1431 | out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); |
commit-queue@webkit.org | a4201b0 | 2015-08-17 22:24:20 +0000 | [diff] [blame] | 1432 | break; |
| 1433 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1434 | case op_new_func_exp: { |
| 1435 | int r0 = (++it)->u.operand; |
msaboff@apple.com | ea77cd0 | 2014-11-14 01:07:48 +0000 | [diff] [blame] | 1436 | int r1 = (++it)->u.operand; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1437 | int f0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1438 | printLocationAndOp(out, exec, location, it, "new_func_exp"); |
commit-queue@webkit.org | 9c3b1a5 | 2016-03-09 22:34:08 +0000 | [diff] [blame] | 1439 | out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1440 | break; |
| 1441 | } |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1442 | case op_new_generator_func_exp: { |
| 1443 | int r0 = (++it)->u.operand; |
| 1444 | int r1 = (++it)->u.operand; |
| 1445 | int f0 = (++it)->u.operand; |
| 1446 | printLocationAndOp(out, exec, location, it, "new_generator_func_exp"); |
commit-queue@webkit.org | 9c3b1a5 | 2016-03-09 22:34:08 +0000 | [diff] [blame] | 1447 | out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1448 | break; |
| 1449 | } |
mark.lam@apple.com | 47c2f14 | 2016-03-16 18:16:32 +0000 | [diff] [blame] | 1450 | case op_set_function_name: { |
| 1451 | int funcReg = (++it)->u.operand; |
| 1452 | int nameReg = (++it)->u.operand; |
| 1453 | printLocationAndOp(out, exec, location, it, "set_function_name"); |
| 1454 | out.printf("%s, %s", registerName(funcReg).data(), registerName(nameReg).data()); |
| 1455 | break; |
| 1456 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1457 | case op_call: { |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1458 | printCallOp(out, exec, location, it, "call", DumpCaches, hasPrintedProfiling, callLinkInfos); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1459 | break; |
| 1460 | } |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 1461 | case op_tail_call: { |
| 1462 | printCallOp(out, exec, location, it, "tail_call", DumpCaches, hasPrintedProfiling, callLinkInfos); |
| 1463 | break; |
| 1464 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1465 | case op_call_eval: { |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1466 | printCallOp(out, exec, location, it, "call_eval", DontDumpCaches, hasPrintedProfiling, callLinkInfos); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1467 | break; |
| 1468 | } |
oliver@apple.com | 177c2b9 | 2014-03-28 01:10:25 +0000 | [diff] [blame] | 1469 | |
| 1470 | case op_construct_varargs: |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 1471 | case op_call_varargs: |
| 1472 | case op_tail_call_varargs: { |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 1473 | int result = (++it)->u.operand; |
ggaren@apple.com | 539d1bb | 2011-11-14 19:21:40 +0000 | [diff] [blame] | 1474 | int callee = (++it)->u.operand; |
| 1475 | int thisValue = (++it)->u.operand; |
| 1476 | int arguments = (++it)->u.operand; |
| 1477 | int firstFreeRegister = (++it)->u.operand; |
oliver@apple.com | 2f5c83b | 2014-02-25 06:59:38 +0000 | [diff] [blame] | 1478 | int varArgOffset = (++it)->u.operand; |
oliver@apple.com | dc48dc3 | 2013-07-25 04:01:42 +0000 | [diff] [blame] | 1479 | ++it; |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 1480 | printLocationAndOp(out, exec, location, it, opcode == op_call_varargs ? "call_varargs" : opcode == op_construct_varargs ? "construct_varargs" : "tail_call_varargs"); |
oliver@apple.com | 2f5c83b | 2014-02-25 06:59:38 +0000 | [diff] [blame] | 1481 | out.printf("%s, %s, %s, %s, %d, %d", registerName(result).data(), registerName(callee).data(), registerName(thisValue).data(), registerName(arguments).data(), firstFreeRegister, varArgOffset); |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 1482 | dumpValueProfiling(out, it, hasPrintedProfiling); |
oliver@apple.com | 65e286e | 2009-04-08 23:08:28 +0000 | [diff] [blame] | 1483 | break; |
| 1484 | } |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 1485 | |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1486 | case op_ret: { |
| 1487 | int r0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1488 | printLocationOpAndRegisterOperand(out, exec, location, it, "ret", r0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1489 | break; |
| 1490 | } |
| 1491 | case op_construct: { |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1492 | printCallOp(out, exec, location, it, "construct", DumpCaches, hasPrintedProfiling, callLinkInfos); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1493 | break; |
| 1494 | } |
barraclough@apple.com | 14dc4e1 | 2009-05-07 00:06:07 +0000 | [diff] [blame] | 1495 | case op_strcat: { |
| 1496 | int r0 = (++it)->u.operand; |
| 1497 | int r1 = (++it)->u.operand; |
| 1498 | int count = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1499 | printLocationAndOp(out, exec, location, it, "strcat"); |
| 1500 | out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), count); |
barraclough@apple.com | 14dc4e1 | 2009-05-07 00:06:07 +0000 | [diff] [blame] | 1501 | break; |
| 1502 | } |
| 1503 | case op_to_primitive: { |
| 1504 | int r0 = (++it)->u.operand; |
| 1505 | int r1 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1506 | printLocationAndOp(out, exec, location, it, "to_primitive"); |
| 1507 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
barraclough@apple.com | 14dc4e1 | 2009-05-07 00:06:07 +0000 | [diff] [blame] | 1508 | break; |
| 1509 | } |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1510 | case op_get_enumerable_length: { |
| 1511 | int dst = it[1].u.operand; |
| 1512 | int base = it[2].u.operand; |
| 1513 | printLocationAndOp(out, exec, location, it, "op_get_enumerable_length"); |
| 1514 | out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); |
| 1515 | it += OPCODE_LENGTH(op_get_enumerable_length) - 1; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1516 | break; |
| 1517 | } |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1518 | case op_has_indexed_property: { |
| 1519 | int dst = it[1].u.operand; |
xan@webkit.org | b469f50 | 2010-10-13 15:39:37 +0000 | [diff] [blame] | 1520 | int base = it[2].u.operand; |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1521 | int propertyName = it[3].u.operand; |
| 1522 | ArrayProfile* arrayProfile = it[4].u.arrayProfile; |
| 1523 | printLocationAndOp(out, exec, location, it, "op_has_indexed_property"); |
| 1524 | out.printf("%s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), arrayProfile); |
| 1525 | it += OPCODE_LENGTH(op_has_indexed_property) - 1; |
| 1526 | break; |
| 1527 | } |
| 1528 | case op_has_structure_property: { |
| 1529 | int dst = it[1].u.operand; |
| 1530 | int base = it[2].u.operand; |
| 1531 | int propertyName = it[3].u.operand; |
| 1532 | int enumerator = it[4].u.operand; |
| 1533 | printLocationAndOp(out, exec, location, it, "op_has_structure_property"); |
| 1534 | out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(enumerator).data()); |
| 1535 | it += OPCODE_LENGTH(op_has_structure_property) - 1; |
| 1536 | break; |
| 1537 | } |
| 1538 | case op_has_generic_property: { |
| 1539 | int dst = it[1].u.operand; |
| 1540 | int base = it[2].u.operand; |
| 1541 | int propertyName = it[3].u.operand; |
| 1542 | printLocationAndOp(out, exec, location, it, "op_has_generic_property"); |
| 1543 | out.printf("%s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data()); |
| 1544 | it += OPCODE_LENGTH(op_has_generic_property) - 1; |
| 1545 | break; |
| 1546 | } |
| 1547 | case op_get_direct_pname: { |
| 1548 | int dst = it[1].u.operand; |
| 1549 | int base = it[2].u.operand; |
| 1550 | int propertyName = it[3].u.operand; |
| 1551 | int index = it[4].u.operand; |
| 1552 | int enumerator = it[5].u.operand; |
| 1553 | ValueProfile* profile = it[6].u.profile; |
| 1554 | printLocationAndOp(out, exec, location, it, "op_get_direct_pname"); |
| 1555 | out.printf("%s, %s, %s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(index).data(), registerName(enumerator).data(), profile); |
| 1556 | it += OPCODE_LENGTH(op_get_direct_pname) - 1; |
| 1557 | break; |
| 1558 | |
| 1559 | } |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1560 | case op_get_property_enumerator: { |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1561 | int dst = it[1].u.operand; |
| 1562 | int base = it[2].u.operand; |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1563 | printLocationAndOp(out, exec, location, it, "op_get_property_enumerator"); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1564 | out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1565 | it += OPCODE_LENGTH(op_get_property_enumerator) - 1; |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1566 | break; |
| 1567 | } |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1568 | case op_enumerator_structure_pname: { |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1569 | int dst = it[1].u.operand; |
| 1570 | int enumerator = it[2].u.operand; |
| 1571 | int index = it[3].u.operand; |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1572 | printLocationAndOp(out, exec, location, it, "op_enumerator_structure_pname"); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1573 | out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data()); |
msaboff@apple.com | b644c25 | 2015-03-24 10:05:21 +0000 | [diff] [blame] | 1574 | it += OPCODE_LENGTH(op_enumerator_structure_pname) - 1; |
| 1575 | break; |
| 1576 | } |
| 1577 | case op_enumerator_generic_pname: { |
| 1578 | int dst = it[1].u.operand; |
| 1579 | int enumerator = it[2].u.operand; |
| 1580 | int index = it[3].u.operand; |
| 1581 | printLocationAndOp(out, exec, location, it, "op_enumerator_generic_pname"); |
| 1582 | out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data()); |
| 1583 | it += OPCODE_LENGTH(op_enumerator_generic_pname) - 1; |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1584 | break; |
| 1585 | } |
| 1586 | case op_to_index_string: { |
| 1587 | int dst = it[1].u.operand; |
| 1588 | int index = it[2].u.operand; |
| 1589 | printLocationAndOp(out, exec, location, it, "op_to_index_string"); |
| 1590 | out.printf("%s, %s", registerName(dst).data(), registerName(index).data()); |
| 1591 | it += OPCODE_LENGTH(op_to_index_string) - 1; |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1592 | break; |
| 1593 | } |
ggaren@apple.com | 170d6f2 | 2012-09-02 21:27:23 +0000 | [diff] [blame] | 1594 | case op_push_with_scope: { |
msaboff@apple.com | c5b9539 | 2014-10-31 21:27:10 +0000 | [diff] [blame] | 1595 | int dst = (++it)->u.operand; |
| 1596 | int newScope = (++it)->u.operand; |
saambarati1@gmail.com | e85426c | 2015-08-07 17:41:22 +0000 | [diff] [blame] | 1597 | int currentScope = (++it)->u.operand; |
msaboff@apple.com | c5b9539 | 2014-10-31 21:27:10 +0000 | [diff] [blame] | 1598 | printLocationAndOp(out, exec, location, it, "push_with_scope"); |
saambarati1@gmail.com | e85426c | 2015-08-07 17:41:22 +0000 | [diff] [blame] | 1599 | out.printf("%s, %s, %s", registerName(dst).data(), registerName(newScope).data(), registerName(currentScope).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1600 | break; |
| 1601 | } |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 1602 | case op_get_parent_scope: { |
| 1603 | int dst = (++it)->u.operand; |
| 1604 | int parentScope = (++it)->u.operand; |
| 1605 | printLocationAndOp(out, exec, location, it, "get_parent_scope"); |
| 1606 | out.printf("%s, %s", registerName(dst).data(), registerName(parentScope).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1607 | break; |
| 1608 | } |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 1609 | case op_create_lexical_environment: { |
| 1610 | int dst = (++it)->u.operand; |
| 1611 | int scope = (++it)->u.operand; |
| 1612 | int symbolTable = (++it)->u.operand; |
| 1613 | int initialValue = (++it)->u.operand; |
| 1614 | printLocationAndOp(out, exec, location, it, "create_lexical_environment"); |
| 1615 | out.printf("%s, %s, %s, %s", |
| 1616 | registerName(dst).data(), registerName(scope).data(), registerName(symbolTable).data(), registerName(initialValue).data()); |
| 1617 | break; |
| 1618 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1619 | case op_catch: { |
| 1620 | int r0 = (++it)->u.operand; |
mark.lam@apple.com | 6ed0827 | 2015-06-05 18:52:12 +0000 | [diff] [blame] | 1621 | int r1 = (++it)->u.operand; |
| 1622 | printLocationAndOp(out, exec, location, it, "catch"); |
| 1623 | out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1624 | break; |
| 1625 | } |
| 1626 | case op_throw: { |
| 1627 | int r0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1628 | printLocationOpAndRegisterOperand(out, exec, location, it, "throw", r0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1629 | break; |
| 1630 | } |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1631 | case op_throw_static_error: { |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1632 | int k0 = (++it)->u.operand; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1633 | int k1 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1634 | printLocationAndOp(out, exec, location, it, "throw_static_error"); |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 1635 | out.printf("%s, %s", constantName(k0).data(), k1 ? "true" : "false"); |
barraclough@apple.com | 4920ae9 | 2010-11-12 03:06:07 +0000 | [diff] [blame] | 1636 | break; |
| 1637 | } |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1638 | case op_debug: { |
| 1639 | int debugHookID = (++it)->u.operand; |
mark.lam@apple.com | 945b139 | 2014-01-23 07:39:58 +0000 | [diff] [blame] | 1640 | int hasBreakpointFlag = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1641 | printLocationAndOp(out, exec, location, it, "debug"); |
youenn.fablet@crf.canon.fr | 5f0b7be | 2015-11-09 14:15:21 +0000 | [diff] [blame] | 1642 | out.printf("%s, %d", debugHookName(debugHookID), hasBreakpointFlag); |
| 1643 | break; |
| 1644 | } |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1645 | case op_save: { |
| 1646 | int generator = (++it)->u.operand; |
| 1647 | unsigned liveCalleeLocalsIndex = (++it)->u.unsignedValue; |
| 1648 | int offset = (++it)->u.operand; |
| 1649 | const FastBitVector& liveness = m_rareData->m_liveCalleeLocalsAtYield[liveCalleeLocalsIndex]; |
| 1650 | printLocationAndOp(out, exec, location, it, "save"); |
| 1651 | out.printf("%s, ", registerName(generator).data()); |
| 1652 | liveness.dump(out); |
| 1653 | out.printf("(@live%1u), %d(->%d)", liveCalleeLocalsIndex, offset, location + offset); |
| 1654 | break; |
| 1655 | } |
| 1656 | case op_resume: { |
| 1657 | int generator = (++it)->u.operand; |
| 1658 | unsigned liveCalleeLocalsIndex = (++it)->u.unsignedValue; |
| 1659 | const FastBitVector& liveness = m_rareData->m_liveCalleeLocalsAtYield[liveCalleeLocalsIndex]; |
| 1660 | printLocationAndOp(out, exec, location, it, "resume"); |
| 1661 | out.printf("%s, ", registerName(generator).data()); |
| 1662 | liveness.dump(out); |
| 1663 | out.printf("(@live%1u)", liveCalleeLocalsIndex); |
| 1664 | break; |
| 1665 | } |
youenn.fablet@crf.canon.fr | 5f0b7be | 2015-11-09 14:15:21 +0000 | [diff] [blame] | 1666 | case op_assert: { |
| 1667 | int condition = (++it)->u.operand; |
| 1668 | int line = (++it)->u.operand; |
| 1669 | printLocationAndOp(out, exec, location, it, "assert"); |
| 1670 | out.printf("%s, %d", registerName(condition).data(), line); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1671 | break; |
| 1672 | } |
| 1673 | case op_end: { |
| 1674 | int r0 = (++it)->u.operand; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1675 | printLocationOpAndRegisterOperand(out, exec, location, it, "end", r0); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1676 | break; |
| 1677 | } |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1678 | case op_resolve_scope: { |
| 1679 | int r0 = (++it)->u.operand; |
msaboff@apple.com | 44641f0 | 2014-11-03 17:56:29 +0000 | [diff] [blame] | 1680 | int scope = (++it)->u.operand; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1681 | int id0 = (++it)->u.operand; |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1682 | ResolveType resolveType = static_cast<ResolveType>((++it)->u.operand); |
mark.lam@apple.com | 65a636f | 2014-02-01 01:24:39 +0000 | [diff] [blame] | 1683 | int depth = (++it)->u.operand; |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1684 | void* pointer = (++it)->u.pointer; |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1685 | printLocationAndOp(out, exec, location, it, "resolve_scope"); |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1686 | out.printf("%s, %s, %s, <%s>, %d, %p", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data(), resolveTypeName(resolveType), depth, pointer); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1687 | break; |
| 1688 | } |
| 1689 | case op_get_from_scope: { |
| 1690 | int r0 = (++it)->u.operand; |
| 1691 | int r1 = (++it)->u.operand; |
| 1692 | int id0 = (++it)->u.operand; |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1693 | GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1694 | ++it; // Structure |
mark.lam@apple.com | 65a636f | 2014-02-01 01:24:39 +0000 | [diff] [blame] | 1695 | int operand = (++it)->u.operand; // Operand |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1696 | printLocationAndOp(out, exec, location, it, "get_from_scope"); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 1697 | out.print(registerName(r0), ", ", registerName(r1)); |
| 1698 | if (static_cast<unsigned>(id0) == UINT_MAX) |
| 1699 | out.print(", anonymous"); |
| 1700 | else |
| 1701 | out.print(", ", idName(id0, identifier(id0))); |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1702 | out.print(", ", getPutInfo.operand(), "<", resolveModeName(getPutInfo.resolveMode()), "|", resolveTypeName(getPutInfo.resolveType()), "|", initializationModeName(getPutInfo.initializationMode()), ">, ", operand); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 1703 | dumpValueProfiling(out, it, hasPrintedProfiling); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1704 | break; |
| 1705 | } |
| 1706 | case op_put_to_scope: { |
| 1707 | int r0 = (++it)->u.operand; |
| 1708 | int id0 = (++it)->u.operand; |
| 1709 | int r1 = (++it)->u.operand; |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1710 | GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1711 | ++it; // Structure |
mark.lam@apple.com | 65a636f | 2014-02-01 01:24:39 +0000 | [diff] [blame] | 1712 | int operand = (++it)->u.operand; // Operand |
msaboff@apple.com | c580864 | 2013-09-05 23:27:41 +0000 | [diff] [blame] | 1713 | printLocationAndOp(out, exec, location, it, "put_to_scope"); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 1714 | out.print(registerName(r0)); |
| 1715 | if (static_cast<unsigned>(id0) == UINT_MAX) |
| 1716 | out.print(", anonymous"); |
| 1717 | else |
| 1718 | out.print(", ", idName(id0, identifier(id0))); |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 1719 | out.print(", ", registerName(r1), ", ", getPutInfo.operand(), "<", resolveModeName(getPutInfo.resolveMode()), "|", resolveTypeName(getPutInfo.resolveType()), "|", initializationModeName(getPutInfo.initializationMode()), ">, <structure>, ", operand); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 1720 | break; |
| 1721 | } |
| 1722 | case op_get_from_arguments: { |
| 1723 | int r0 = (++it)->u.operand; |
| 1724 | int r1 = (++it)->u.operand; |
| 1725 | int offset = (++it)->u.operand; |
| 1726 | printLocationAndOp(out, exec, location, it, "get_from_arguments"); |
| 1727 | out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), offset); |
| 1728 | dumpValueProfiling(out, it, hasPrintedProfiling); |
| 1729 | break; |
| 1730 | } |
| 1731 | case op_put_to_arguments: { |
| 1732 | int r0 = (++it)->u.operand; |
| 1733 | int offset = (++it)->u.operand; |
| 1734 | int r1 = (++it)->u.operand; |
| 1735 | printLocationAndOp(out, exec, location, it, "put_to_arguments"); |
| 1736 | out.printf("%s, %d, %s", registerName(r0).data(), offset, registerName(r1).data()); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 1737 | break; |
| 1738 | } |
commit-queue@webkit.org | e13567f | 2012-09-01 17:36:51 +0000 | [diff] [blame] | 1739 | default: |
oliver@apple.com | 903b0c0 | 2013-01-24 01:40:37 +0000 | [diff] [blame] | 1740 | RELEASE_ASSERT_NOT_REACHED(); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1741 | } |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1742 | |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1743 | dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling); |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 1744 | dumpResultProfile(out, resultProfileForBytecodeOffset(location), hasPrintedProfiling); |
fpizlo@apple.com | ca3a85b | 2012-12-17 07:16:18 +0000 | [diff] [blame] | 1745 | |
fpizlo@apple.com | 105ea9b | 2013-02-17 05:36:48 +0000 | [diff] [blame] | 1746 | #if ENABLE(DFG_JIT) |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 1747 | Vector<DFG::FrequentExitSite> exitSites = exitProfile().exitSitesFor(location); |
fpizlo@apple.com | 105ea9b | 2013-02-17 05:36:48 +0000 | [diff] [blame] | 1748 | if (!exitSites.isEmpty()) { |
| 1749 | out.print(" !! frequent exits: "); |
| 1750 | CommaPrinter comma; |
| 1751 | for (unsigned i = 0; i < exitSites.size(); ++i) |
fpizlo@apple.com | 51614cc | 2014-02-17 06:35:32 +0000 | [diff] [blame] | 1752 | out.print(comma, exitSites[i].kind(), " ", exitSites[i].jitType()); |
fpizlo@apple.com | 105ea9b | 2013-02-17 05:36:48 +0000 | [diff] [blame] | 1753 | } |
| 1754 | #else // ENABLE(DFG_JIT) |
| 1755 | UNUSED_PARAM(location); |
| 1756 | #endif // ENABLE(DFG_JIT) |
| 1757 | out.print("\n"); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 1758 | } |
| 1759 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1760 | void CodeBlock::dumpBytecode( |
| 1761 | PrintStream& out, unsigned bytecodeOffset, |
| 1762 | const StubInfoMap& stubInfos, const CallLinkInfoMap& callLinkInfos) |
fpizlo@apple.com | 1949f32 | 2012-11-22 00:46:57 +0000 | [diff] [blame] | 1763 | { |
| 1764 | ExecState* exec = m_globalObject->globalExec(); |
| 1765 | const Instruction* it = instructions().begin() + bytecodeOffset; |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 1766 | dumpBytecode(out, exec, instructions().begin(), it, stubInfos, callLinkInfos); |
fpizlo@apple.com | 1949f32 | 2012-11-22 00:46:57 +0000 | [diff] [blame] | 1767 | } |
| 1768 | |
weinig@apple.com | 67940d5 | 2008-12-09 00:14:58 +0000 | [diff] [blame] | 1769 | #define FOR_EACH_MEMBER_VECTOR(macro) \ |
| 1770 | macro(instructions) \ |
weinig@apple.com | 67940d5 | 2008-12-09 00:14:58 +0000 | [diff] [blame] | 1771 | macro(callLinkInfos) \ |
| 1772 | macro(linkedCallerList) \ |
| 1773 | macro(identifiers) \ |
| 1774 | macro(functionExpressions) \ |
weinig@apple.com | 9367554 | 2009-01-09 18:47:37 +0000 | [diff] [blame] | 1775 | macro(constantRegisters) |
weinig@apple.com | 4557e84 | 2008-12-09 01:06:14 +0000 | [diff] [blame] | 1776 | |
| 1777 | #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \ |
weinig@apple.com | 67940d5 | 2008-12-09 00:14:58 +0000 | [diff] [blame] | 1778 | macro(regexps) \ |
| 1779 | macro(functions) \ |
weinig@apple.com | 67940d5 | 2008-12-09 00:14:58 +0000 | [diff] [blame] | 1780 | macro(exceptionHandlers) \ |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 1781 | macro(switchJumpTables) \ |
weinig@apple.com | c7b1989 | 2008-12-18 00:00:01 +0000 | [diff] [blame] | 1782 | macro(stringSwitchJumpTables) \ |
barraclough@apple.com | 87dbd5e | 2010-11-19 02:35:25 +0000 | [diff] [blame] | 1783 | macro(evalCodeCache) \ |
weinig@apple.com | af0231a | 2009-01-08 01:46:14 +0000 | [diff] [blame] | 1784 | macro(expressionInfo) \ |
| 1785 | macro(lineInfo) \ |
barraclough@apple.com | 87dbd5e | 2010-11-19 02:35:25 +0000 | [diff] [blame] | 1786 | macro(callReturnIndexVector) |
weinig@apple.com | af0231a | 2009-01-08 01:46:14 +0000 | [diff] [blame] | 1787 | |
weinig@apple.com | ff037a0 | 2008-12-10 20:05:53 +0000 | [diff] [blame] | 1788 | template<typename T> |
| 1789 | static size_t sizeInBytes(const Vector<T>& vector) |
| 1790 | { |
| 1791 | return vector.capacity() * sizeof(T); |
| 1792 | } |
| 1793 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 1794 | namespace { |
| 1795 | |
| 1796 | class PutToScopeFireDetail : public FireDetail { |
| 1797 | public: |
| 1798 | PutToScopeFireDetail(CodeBlock* codeBlock, const Identifier& ident) |
| 1799 | : m_codeBlock(codeBlock) |
| 1800 | , m_ident(ident) |
| 1801 | { |
| 1802 | } |
| 1803 | |
darin@apple.com | 11ff47c | 2016-03-04 16:47:55 +0000 | [diff] [blame] | 1804 | void dump(PrintStream& out) const override |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 1805 | { |
| 1806 | out.print("Linking put_to_scope in ", FunctionExecutableDump(jsCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())), " for ", m_ident); |
| 1807 | } |
| 1808 | |
| 1809 | private: |
| 1810 | CodeBlock* m_codeBlock; |
| 1811 | const Identifier& m_ident; |
| 1812 | }; |
| 1813 | |
| 1814 | } // anonymous namespace |
| 1815 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1816 | CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other) |
| 1817 | : JSCell(*vm, structure) |
| 1818 | , m_globalObject(other.m_globalObject) |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1819 | , m_numCalleeLocals(other.m_numCalleeLocals) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1820 | , m_numVars(other.m_numVars) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 1821 | , m_shouldAlwaysBeInlined(true) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1822 | #if ENABLE(JIT) |
| 1823 | , m_capabilityLevelState(DFG::CapabilityLevelNotSet) |
| 1824 | #endif |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 1825 | , m_didFailFTLCompilation(false) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 1826 | , m_hasBeenCompiledWithFTL(false) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1827 | , m_isConstructor(other.m_isConstructor) |
| 1828 | , m_isStrictMode(other.m_isStrictMode) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1829 | , m_codeType(other.m_codeType) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1830 | , m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get()) |
mark.lam@apple.com | 3dec4c6 | 2014-03-03 22:12:10 +0000 | [diff] [blame] | 1831 | , m_hasDebuggerStatement(false) |
mark.lam@apple.com | 9c30488 | 2014-01-24 19:07:31 +0000 | [diff] [blame] | 1832 | , m_steppingMode(SteppingModeDisabled) |
mark.lam@apple.com | 945b139 | 2014-01-23 07:39:58 +0000 | [diff] [blame] | 1833 | , m_numBreakpoints(0) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1834 | , m_ownerExecutable(*other.m_vm, this, other.m_ownerExecutable.get()) |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 1835 | , m_vm(other.m_vm) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1836 | , m_instructions(other.m_instructions) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1837 | , m_thisRegister(other.m_thisRegister) |
msaboff@apple.com | 5e62e3f | 2014-11-21 23:41:26 +0000 | [diff] [blame] | 1838 | , m_scopeRegister(other.m_scopeRegister) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1839 | , m_hash(other.m_hash) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1840 | , m_source(other.m_source) |
| 1841 | , m_sourceOffset(other.m_sourceOffset) |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 1842 | , m_firstLineColumnOffset(other.m_firstLineColumnOffset) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1843 | , m_constantRegisters(other.m_constantRegisters) |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 1844 | , m_constantsSourceCodeRepresentation(other.m_constantsSourceCodeRepresentation) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1845 | , m_functionDecls(other.m_functionDecls) |
| 1846 | , m_functionExprs(other.m_functionExprs) |
fpizlo@apple.com | 39c94a4 | 2012-07-10 09:18:47 +0000 | [diff] [blame] | 1847 | , m_osrExitCounter(0) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1848 | , m_optimizationDelayCounter(0) |
| 1849 | , m_reoptimizationRetryCounter(0) |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 1850 | , m_creationTime(std::chrono::steady_clock::now()) |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1851 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1852 | m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed); |
mark.lam@apple.com | 5d1b2b6 | 2015-03-13 18:02:40 +0000 | [diff] [blame] | 1853 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1854 | ASSERT(heap()->isDeferred()); |
msaboff@apple.com | 2f145bc | 2015-01-23 19:52:25 +0000 | [diff] [blame] | 1855 | ASSERT(m_scopeRegister.isLocal()); |
| 1856 | |
fpizlo@apple.com | c4d5496 | 2012-01-10 22:08:47 +0000 | [diff] [blame] | 1857 | setNumParameters(other.numParameters()); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1858 | } |
| 1859 | |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 1860 | struct AbstractResolveKey { |
| 1861 | AbstractResolveKey() |
| 1862 | : m_impl(nullptr) |
| 1863 | { } |
| 1864 | AbstractResolveKey(size_t depth, const Identifier& ident, GetOrPut getOrPut, ResolveType resolveType, InitializationMode initializationMode) |
| 1865 | : m_depth(depth) |
| 1866 | , m_impl(ident.impl()) |
| 1867 | , m_getOrPut(getOrPut) |
| 1868 | , m_resolveType(resolveType) |
| 1869 | , m_initializationMode(initializationMode) |
| 1870 | { } |
| 1871 | |
| 1872 | |
| 1873 | bool operator==(const AbstractResolveKey& other) const |
| 1874 | { |
| 1875 | return m_impl == other.m_impl |
| 1876 | && m_depth == other.m_depth |
| 1877 | && m_getOrPut == other.m_getOrPut |
| 1878 | && m_resolveType == other.m_resolveType |
| 1879 | && m_initializationMode == other.m_initializationMode; |
| 1880 | } |
| 1881 | |
| 1882 | bool isNull() const { return !m_impl; } |
| 1883 | |
| 1884 | size_t m_depth; |
| 1885 | UniquedStringImpl* m_impl; |
| 1886 | GetOrPut m_getOrPut; |
| 1887 | ResolveType m_resolveType; |
| 1888 | InitializationMode m_initializationMode; |
| 1889 | }; |
| 1890 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1891 | void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other) |
| 1892 | { |
| 1893 | Base::finishCreation(vm); |
| 1894 | |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1895 | optimizeAfterWarmUp(); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 1896 | jitAfterWarmUp(); |
commit-queue@webkit.org | 3e0a1a0 | 2012-06-19 06:07:28 +0000 | [diff] [blame] | 1897 | |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1898 | if (other.m_rareData) { |
| 1899 | createRareDataIfNecessary(); |
| 1900 | |
| 1901 | m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers; |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1902 | m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers; |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 1903 | m_rareData->m_switchJumpTables = other.m_rareData->m_switchJumpTables; |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1904 | m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables; |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1905 | m_rareData->m_liveCalleeLocalsAtYield = other.m_rareData->m_liveCalleeLocalsAtYield; |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1906 | } |
fpizlo@apple.com | 195d7b8 | 2013-09-03 16:39:29 +0000 | [diff] [blame] | 1907 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1908 | heap()->m_codeBlocks.add(this); |
fpizlo@apple.com | f5e1fe1 | 2011-11-10 21:59:39 +0000 | [diff] [blame] | 1909 | } |
| 1910 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1911 | CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, |
| 1912 | JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset) |
| 1913 | : JSCell(*vm, structure) |
| 1914 | , m_globalObject(scope->globalObject()->vm(), this, scope->globalObject()) |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 1915 | , m_numCalleeLocals(unlinkedCodeBlock->m_numCalleeLocals) |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1916 | , m_numVars(unlinkedCodeBlock->m_numVars) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 1917 | , m_shouldAlwaysBeInlined(true) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1918 | #if ENABLE(JIT) |
| 1919 | , m_capabilityLevelState(DFG::CapabilityLevelNotSet) |
| 1920 | #endif |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 1921 | , m_didFailFTLCompilation(false) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 1922 | , m_hasBeenCompiledWithFTL(false) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1923 | , m_isConstructor(unlinkedCodeBlock->isConstructor()) |
| 1924 | , m_isStrictMode(unlinkedCodeBlock->isStrictMode()) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1925 | , m_codeType(unlinkedCodeBlock->codeType()) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1926 | , m_unlinkedCode(m_globalObject->vm(), this, unlinkedCodeBlock) |
mark.lam@apple.com | 3dec4c6 | 2014-03-03 22:12:10 +0000 | [diff] [blame] | 1927 | , m_hasDebuggerStatement(false) |
mark.lam@apple.com | 9c30488 | 2014-01-24 19:07:31 +0000 | [diff] [blame] | 1928 | , m_steppingMode(SteppingModeDisabled) |
mark.lam@apple.com | 945b139 | 2014-01-23 07:39:58 +0000 | [diff] [blame] | 1929 | , m_numBreakpoints(0) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1930 | , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable) |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 1931 | , m_vm(unlinkedCodeBlock->vm()) |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1932 | , m_thisRegister(unlinkedCodeBlock->thisRegister()) |
msaboff@apple.com | 5e62e3f | 2014-11-21 23:41:26 +0000 | [diff] [blame] | 1933 | , m_scopeRegister(unlinkedCodeBlock->scopeRegister()) |
weinig@apple.com | 0e9a7ee | 2008-12-06 22:31:14 +0000 | [diff] [blame] | 1934 | , m_source(sourceProvider) |
| 1935 | , m_sourceOffset(sourceOffset) |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 1936 | , m_firstLineColumnOffset(firstLineColumnOffset) |
fpizlo@apple.com | 39c94a4 | 2012-07-10 09:18:47 +0000 | [diff] [blame] | 1937 | , m_osrExitCounter(0) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 1938 | , m_optimizationDelayCounter(0) |
fpizlo@apple.com | 706f5f3 | 2011-09-21 23:36:35 +0000 | [diff] [blame] | 1939 | , m_reoptimizationRetryCounter(0) |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 1940 | , m_creationTime(std::chrono::steady_clock::now()) |
weinig@apple.com | 0e9a7ee | 2008-12-06 22:31:14 +0000 | [diff] [blame] | 1941 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1942 | m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed); |
mark.lam@apple.com | 5d1b2b6 | 2015-03-13 18:02:40 +0000 | [diff] [blame] | 1943 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1944 | ASSERT(heap()->isDeferred()); |
msaboff@apple.com | 2f145bc | 2015-01-23 19:52:25 +0000 | [diff] [blame] | 1945 | ASSERT(m_scopeRegister.isLocal()); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1946 | |
weinig@apple.com | 0e9a7ee | 2008-12-06 22:31:14 +0000 | [diff] [blame] | 1947 | ASSERT(m_source); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1948 | setNumParameters(unlinkedCodeBlock->numParameters()); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1949 | } |
oliver@apple.com | c909f5f | 2012-10-18 23:37:40 +0000 | [diff] [blame] | 1950 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1951 | void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, |
| 1952 | JSScope* scope) |
| 1953 | { |
| 1954 | Base::finishCreation(vm); |
| 1955 | |
| 1956 | if (vm.typeProfiler() || vm.controlFlowProfiler()) |
| 1957 | vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset()); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 1958 | |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 1959 | setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation()); |
oliver@apple.com | 75f804e | 2013-03-07 00:25:20 +0000 | [diff] [blame] | 1960 | if (unlinkedCodeBlock->usesGlobalObject()) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1961 | m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get()); |
rniwa@webkit.org | 49d0cc1 | 2015-04-25 22:03:30 +0000 | [diff] [blame] | 1962 | |
| 1963 | for (unsigned i = 0; i < LinkTimeConstantCount; i++) { |
| 1964 | LinkTimeConstant type = static_cast<LinkTimeConstant>(i); |
| 1965 | if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type)) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1966 | m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type)); |
rniwa@webkit.org | 49d0cc1 | 2015-04-25 22:03:30 +0000 | [diff] [blame] | 1967 | } |
saambarati1@gmail.com | 3321f09 | 2015-07-20 21:16:41 +0000 | [diff] [blame] | 1968 | |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 1969 | // We already have the cloned symbol table for the module environment since we need to instantiate |
| 1970 | // the module environments before linking the code block. We replace the stored symbol table with the already cloned one. |
| 1971 | if (UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock = jsDynamicCast<UnlinkedModuleProgramCodeBlock*>(unlinkedCodeBlock)) { |
| 1972 | SymbolTable* clonedSymbolTable = jsCast<ModuleProgramExecutable*>(ownerExecutable)->moduleEnvironmentSymbolTable(); |
| 1973 | if (m_vm->typeProfiler()) { |
| 1974 | ConcurrentJITLocker locker(clonedSymbolTable->m_lock); |
| 1975 | clonedSymbolTable->prepareForTypeProfiling(locker); |
| 1976 | } |
| 1977 | replaceConstant(unlinkedModuleProgramCodeBlock->moduleEnvironmentSymbolTableConstantRegisterOffset(), clonedSymbolTable); |
| 1978 | } |
| 1979 | |
sbarati@apple.com | 2877c4a | 2016-03-31 00:47:15 +0000 | [diff] [blame] | 1980 | bool shouldUpdateFunctionHasExecutedCache = vm.typeProfiler() || vm.controlFlowProfiler(); |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1981 | m_functionDecls = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionDecls()); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1982 | for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) { |
| 1983 | UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i); |
sbarati@apple.com | 2877c4a | 2016-03-31 00:47:15 +0000 | [diff] [blame] | 1984 | if (shouldUpdateFunctionHasExecutedCache) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1985 | vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset()); |
| 1986 | m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source())); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1987 | } |
| 1988 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 1989 | m_functionExprs = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionExprs()); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1990 | for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) { |
| 1991 | UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i); |
sbarati@apple.com | 2877c4a | 2016-03-31 00:47:15 +0000 | [diff] [blame] | 1992 | if (shouldUpdateFunctionHasExecutedCache) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 1993 | vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset()); |
| 1994 | m_functionExprs[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source())); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 1995 | } |
| 1996 | |
| 1997 | if (unlinkedCodeBlock->hasRareData()) { |
| 1998 | createRareDataIfNecessary(); |
| 1999 | if (size_t count = unlinkedCodeBlock->constantBufferCount()) { |
| 2000 | m_rareData->m_constantBuffers.grow(count); |
| 2001 | for (size_t i = 0; i < count; i++) { |
| 2002 | const UnlinkedCodeBlock::ConstantBuffer& buffer = unlinkedCodeBlock->constantBuffer(i); |
| 2003 | m_rareData->m_constantBuffers[i] = buffer; |
| 2004 | } |
| 2005 | } |
| 2006 | if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) { |
akling@apple.com | b2ad169 | 2014-01-18 23:09:48 +0000 | [diff] [blame] | 2007 | m_rareData->m_exceptionHandlers.resizeToFit(count); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2008 | for (size_t i = 0; i < count; i++) { |
mark.lam@apple.com | 4585ce9 | 2015-05-30 00:19:01 +0000 | [diff] [blame] | 2009 | const UnlinkedHandlerInfo& unlinkedHandler = unlinkedCodeBlock->exceptionHandler(i); |
| 2010 | HandlerInfo& handler = m_rareData->m_exceptionHandlers[i]; |
mark.lam@apple.com | 3280e07 | 2015-06-01 17:57:18 +0000 | [diff] [blame] | 2011 | #if ENABLE(JIT) |
saambarati1@gmail.com | e85426c | 2015-08-07 17:41:22 +0000 | [diff] [blame] | 2012 | handler.initialize(unlinkedHandler, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(op_catch)))); |
mark.lam@apple.com | 3280e07 | 2015-06-01 17:57:18 +0000 | [diff] [blame] | 2013 | #else |
saambarati1@gmail.com | e85426c | 2015-08-07 17:41:22 +0000 | [diff] [blame] | 2014 | handler.initialize(unlinkedHandler); |
mark.lam@apple.com | 3280e07 | 2015-06-01 17:57:18 +0000 | [diff] [blame] | 2015 | #endif |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2016 | } |
| 2017 | } |
| 2018 | |
| 2019 | if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) { |
| 2020 | m_rareData->m_stringSwitchJumpTables.grow(count); |
| 2021 | for (size_t i = 0; i < count; i++) { |
| 2022 | UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin(); |
| 2023 | UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end(); |
| 2024 | for (; ptr != end; ++ptr) { |
| 2025 | OffsetLocation offset; |
| 2026 | offset.branchOffset = ptr->value; |
| 2027 | m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset); |
| 2028 | } |
| 2029 | } |
| 2030 | } |
| 2031 | |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 2032 | if (size_t count = unlinkedCodeBlock->numberOfSwitchJumpTables()) { |
| 2033 | m_rareData->m_switchJumpTables.grow(count); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2034 | for (size_t i = 0; i < count; i++) { |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 2035 | UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->switchJumpTable(i); |
| 2036 | SimpleJumpTable& destTable = m_rareData->m_switchJumpTables[i]; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2037 | destTable.branchOffsets = sourceTable.branchOffsets; |
| 2038 | destTable.min = sourceTable.min; |
| 2039 | } |
| 2040 | } |
| 2041 | } |
| 2042 | |
| 2043 | // Allocate metadata buffers for the bytecode |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2044 | if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos()) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2045 | m_llintCallLinkInfos = RefCountedArray<LLIntCallLinkInfo>(size); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2046 | if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles()) |
| 2047 | m_arrayProfiles.grow(size); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 2048 | if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles()) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2049 | m_arrayAllocationProfiles = RefCountedArray<ArrayAllocationProfile>(size); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2050 | if (size_t size = unlinkedCodeBlock->numberOfValueProfiles()) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2051 | m_valueProfiles = RefCountedArray<ValueProfile>(size); |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 2052 | if (size_t size = unlinkedCodeBlock->numberOfObjectAllocationProfiles()) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2053 | m_objectAllocationProfiles = RefCountedArray<ObjectAllocationProfile>(size); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2054 | |
msaboff@apple.com | 0208546 | 2015-09-10 17:47:16 +0000 | [diff] [blame] | 2055 | #if ENABLE(JIT) |
| 2056 | setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters()); |
| 2057 | #endif |
| 2058 | |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 2059 | AbstractResolveKey lastResolveKey; |
| 2060 | ResolveOp lastCachedOp; |
| 2061 | auto cachedAbstractResolve = [&] (size_t localScopeDepth, const Identifier& ident, GetOrPut getOrPut, ResolveType resolveType, InitializationMode initializationMode) -> const ResolveOp& { |
| 2062 | AbstractResolveKey key(localScopeDepth, ident, getOrPut, resolveType, initializationMode); |
| 2063 | if (key == lastResolveKey) { |
| 2064 | ASSERT(!lastResolveKey.isNull()); |
| 2065 | return lastCachedOp; |
| 2066 | } |
| 2067 | lastCachedOp = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, getOrPut, resolveType, initializationMode); |
| 2068 | lastResolveKey = key; |
| 2069 | return lastCachedOp; |
| 2070 | }; |
| 2071 | |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2072 | // Copy and translate the UnlinkedInstructions |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2073 | unsigned instructionCount = unlinkedCodeBlock->instructions().count(); |
| 2074 | UnlinkedInstructionStream::Reader instructionReader(unlinkedCodeBlock->instructions()); |
| 2075 | |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2076 | // Bookkeep the strongly referenced module environments. |
| 2077 | HashSet<JSModuleEnvironment*> stronglyReferencedModuleEnvironments; |
| 2078 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 2079 | // Bookkeep the merge point bytecode offsets. |
| 2080 | Vector<size_t> mergePointBytecodeOffsets; |
| 2081 | |
akling@apple.com | f10f7a1 | 2015-10-10 21:14:56 +0000 | [diff] [blame] | 2082 | RefCountedArray<Instruction> instructions(instructionCount); |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2083 | |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2084 | for (unsigned i = 0; !instructionReader.atEnd(); ) { |
| 2085 | const UnlinkedInstruction* pc = instructionReader.next(); |
| 2086 | |
| 2087 | unsigned opLength = opcodeLength(pc[0].u.opcode); |
| 2088 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2089 | instructions[i] = vm.interpreter->getOpcode(pc[0].u.opcode); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2090 | for (size_t j = 1; j < opLength; ++j) { |
| 2091 | if (sizeof(int32_t) != sizeof(intptr_t)) |
| 2092 | instructions[i + j].u.pointer = 0; |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2093 | instructions[i + j].u.operand = pc[j].u.operand; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2094 | } |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2095 | switch (pc[0].u.opcode) { |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2096 | case op_has_indexed_property: { |
| 2097 | int arrayProfileIndex = pc[opLength - 1].u.operand; |
| 2098 | m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); |
| 2099 | |
| 2100 | instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; |
| 2101 | break; |
| 2102 | } |
msaboff@apple.com | 74aef1f | 2014-02-01 15:30:41 +0000 | [diff] [blame] | 2103 | case op_call_varargs: |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 2104 | case op_tail_call_varargs: |
oliver@apple.com | 177c2b9 | 2014-03-28 01:10:25 +0000 | [diff] [blame] | 2105 | case op_construct_varargs: |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2106 | case op_get_by_val: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2107 | int arrayProfileIndex = pc[opLength - 2].u.operand; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2108 | m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); |
| 2109 | |
| 2110 | instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex]; |
joepeck@webkit.org | 899544a | 2014-01-28 04:04:45 +0000 | [diff] [blame] | 2111 | FALLTHROUGH; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2112 | } |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2113 | case op_get_direct_pname: |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2114 | case op_get_by_id: |
| 2115 | case op_get_from_arguments: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2116 | ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand]; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2117 | ASSERT(profile->m_bytecodeOffset == -1); |
| 2118 | profile->m_bytecodeOffset = i; |
| 2119 | instructions[i + opLength - 1] = profile; |
| 2120 | break; |
| 2121 | } |
| 2122 | case op_put_by_val: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2123 | int arrayProfileIndex = pc[opLength - 1].u.operand; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2124 | m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); |
| 2125 | instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; |
| 2126 | break; |
| 2127 | } |
oliver@apple.com | e050d64 | 2013-10-19 00:09:28 +0000 | [diff] [blame] | 2128 | case op_put_by_val_direct: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2129 | int arrayProfileIndex = pc[opLength - 1].u.operand; |
oliver@apple.com | e050d64 | 2013-10-19 00:09:28 +0000 | [diff] [blame] | 2130 | m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); |
| 2131 | instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; |
| 2132 | break; |
| 2133 | } |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2134 | |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 2135 | case op_new_array: |
| 2136 | case op_new_array_buffer: |
| 2137 | case op_new_array_with_size: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2138 | int arrayAllocationProfileIndex = pc[opLength - 1].u.operand; |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 2139 | instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex]; |
| 2140 | break; |
| 2141 | } |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 2142 | case op_new_object: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2143 | int objectAllocationProfileIndex = pc[opLength - 1].u.operand; |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 2144 | ObjectAllocationProfile* objectAllocationProfile = &m_objectAllocationProfiles[objectAllocationProfileIndex]; |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2145 | int inferredInlineCapacity = pc[opLength - 2].u.operand; |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 2146 | |
| 2147 | instructions[i + opLength - 1] = objectAllocationProfile; |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2148 | objectAllocationProfile->initialize(vm, |
| 2149 | this, m_globalObject->objectPrototype(), inferredInlineCapacity); |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 2150 | break; |
| 2151 | } |
| 2152 | |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2153 | case op_call: |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 2154 | case op_tail_call: |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2155 | case op_call_eval: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2156 | ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand]; |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 2157 | ASSERT(profile->m_bytecodeOffset == -1); |
| 2158 | profile->m_bytecodeOffset = i; |
| 2159 | instructions[i + opLength - 1] = profile; |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2160 | int arrayProfileIndex = pc[opLength - 2].u.operand; |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2161 | m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 2162 | instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex]; |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2163 | instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand]; |
fpizlo@apple.com | 0ed51fc | 2012-11-09 01:27:25 +0000 | [diff] [blame] | 2164 | break; |
| 2165 | } |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 2166 | case op_construct: { |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2167 | instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand]; |
akling@apple.com | 8427aaf | 2014-01-27 05:45:30 +0000 | [diff] [blame] | 2168 | ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand]; |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 2169 | ASSERT(profile->m_bytecodeOffset == -1); |
| 2170 | profile->m_bytecodeOffset = i; |
| 2171 | instructions[i + opLength - 1] = profile; |
fpizlo@apple.com | 0ed51fc | 2012-11-09 01:27:25 +0000 | [diff] [blame] | 2172 | break; |
oliver@apple.com | cf0e6c4 | 2013-07-25 04:01:45 +0000 | [diff] [blame] | 2173 | } |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2174 | case op_get_array_length: |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2175 | CRASH(); |
| 2176 | |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2177 | case op_resolve_scope: { |
msaboff@apple.com | 44641f0 | 2014-11-03 17:56:29 +0000 | [diff] [blame] | 2178 | const Identifier& ident = identifier(pc[3].u.operand); |
| 2179 | ResolveType type = static_cast<ResolveType>(pc[4].u.operand); |
fpizlo@apple.com | a97ccfd | 2015-03-02 02:08:26 +0000 | [diff] [blame] | 2180 | RELEASE_ASSERT(type != LocalClosureVar); |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2181 | int localScopeDepth = pc[5].u.operand; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2182 | |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 2183 | const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, type, InitializationMode::NotInitialization); |
msaboff@apple.com | 44641f0 | 2014-11-03 17:56:29 +0000 | [diff] [blame] | 2184 | instructions[i + 4].u.operand = op.type; |
| 2185 | instructions[i + 5].u.operand = op.depth; |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2186 | if (op.lexicalEnvironment) { |
| 2187 | if (op.type == ModuleVar) { |
| 2188 | // Keep the linked module environment strongly referenced. |
| 2189 | if (stronglyReferencedModuleEnvironments.add(jsCast<JSModuleEnvironment*>(op.lexicalEnvironment)).isNewEntry) |
| 2190 | addConstant(op.lexicalEnvironment); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2191 | instructions[i + 6].u.jsCell.set(vm, this, op.lexicalEnvironment); |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2192 | } else |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2193 | instructions[i + 6].u.symbolTable.set(vm, this, op.lexicalEnvironment->symbolTable()); |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2194 | } else if (JSScope* constantScope = JSScope::constantScopeForCodeBlock(op.type, this)) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2195 | instructions[i + 6].u.jsCell.set(vm, this, constantScope); |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2196 | else |
| 2197 | instructions[i + 6].u.pointer = nullptr; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2198 | break; |
| 2199 | } |
| 2200 | |
| 2201 | case op_get_from_scope: { |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2202 | ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand]; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2203 | ASSERT(profile->m_bytecodeOffset == -1); |
| 2204 | profile->m_bytecodeOffset = i; |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2205 | instructions[i + opLength - 1] = profile; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2206 | |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2207 | // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2208 | |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2209 | int localScopeDepth = pc[5].u.operand; |
| 2210 | instructions[i + 5].u.pointer = nullptr; |
| 2211 | |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2212 | GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand); |
sbarati@apple.com | e67fd78 | 2016-04-19 01:38:30 +0000 | [diff] [blame] | 2213 | ASSERT(!isInitialization(getPutInfo.initializationMode())); |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2214 | if (getPutInfo.resolveType() == LocalClosureVar) { |
| 2215 | instructions[i + 4] = GetPutInfo(getPutInfo.resolveMode(), ClosureVar, getPutInfo.initializationMode()).operand(); |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2216 | break; |
| 2217 | } |
| 2218 | |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2219 | const Identifier& ident = identifier(pc[3].u.operand); |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 2220 | const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, getPutInfo.resolveType(), InitializationMode::NotInitialization); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2221 | |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2222 | instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand(); |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2223 | if (op.type == ModuleVar) |
| 2224 | instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), ClosureVar, getPutInfo.initializationMode()).operand(); |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2225 | if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks) |
fpizlo@apple.com | 1a72409 | 2013-11-28 07:10:10 +0000 | [diff] [blame] | 2226 | instructions[i + 5].u.watchpointSet = op.watchpointSet; |
| 2227 | else if (op.structure) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2228 | instructions[i + 5].u.structure.set(vm, this, op.structure); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2229 | instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand); |
| 2230 | break; |
| 2231 | } |
| 2232 | |
| 2233 | case op_put_to_scope: { |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2234 | // put_to_scope scope, id, value, GetPutInfo, Structure, Operand |
| 2235 | GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand); |
| 2236 | if (getPutInfo.resolveType() == LocalClosureVar) { |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2237 | // Only do watching if the property we're putting to is not anonymous. |
| 2238 | if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) { |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2239 | int symbolTableIndex = pc[5].u.operand; |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2240 | SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex)); |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2241 | const Identifier& ident = identifier(pc[2].u.operand); |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2242 | ConcurrentJITLocker locker(symbolTable->m_lock); |
| 2243 | auto iter = symbolTable->find(locker, ident.impl()); |
sbarati@apple.com | 2877c4a | 2016-03-31 00:47:15 +0000 | [diff] [blame] | 2244 | ASSERT(iter != symbolTable->end(locker)); |
fpizlo@apple.com | 3a2fa4c | 2015-04-13 22:13:12 +0000 | [diff] [blame] | 2245 | iter->value.prepareToWatch(); |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2246 | instructions[i + 5].u.watchpointSet = iter->value.watchpointSet(); |
| 2247 | } else |
| 2248 | instructions[i + 5].u.watchpointSet = nullptr; |
| 2249 | break; |
| 2250 | } |
| 2251 | |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 2252 | const Identifier& ident = identifier(pc[2].u.operand); |
saambarati1@gmail.com | 144f17c | 2015-07-15 21:41:08 +0000 | [diff] [blame] | 2253 | int localScopeDepth = pc[5].u.operand; |
| 2254 | instructions[i + 5].u.pointer = nullptr; |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 2255 | const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Put, getPutInfo.resolveType(), getPutInfo.initializationMode()); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2256 | |
saambarati1@gmail.com | 060e751 | 2015-09-03 19:45:44 +0000 | [diff] [blame] | 2257 | instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand(); |
| 2258 | if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks) |
fpizlo@apple.com | 40f7cbf | 2013-11-18 23:19:53 +0000 | [diff] [blame] | 2259 | instructions[i + 5].u.watchpointSet = op.watchpointSet; |
fpizlo@apple.com | 88fedde | 2013-12-04 19:29:19 +0000 | [diff] [blame] | 2260 | else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) { |
| 2261 | if (op.watchpointSet) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2262 | op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident)); |
fpizlo@apple.com | 88fedde | 2013-12-04 19:29:19 +0000 | [diff] [blame] | 2263 | } else if (op.structure) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2264 | instructions[i + 5].u.structure.set(vm, this, op.structure); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 2265 | instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand); |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 2266 | |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2267 | break; |
| 2268 | } |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 2269 | |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2270 | case op_profile_type: { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2271 | RELEASE_ASSERT(vm.typeProfiler()); |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2272 | // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType? |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2273 | size_t instructionOffset = i + opLength - 1; |
| 2274 | unsigned divotStart, divotEnd; |
mark.lam@apple.com | ca860af | 2014-10-06 22:17:09 +0000 | [diff] [blame] | 2275 | GlobalVariableID globalVariableID = 0; |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2276 | RefPtr<TypeSet> globalTypeSet; |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2277 | bool shouldAnalyze = m_unlinkedCode->typeProfilerExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2278 | VirtualRegister profileRegister(pc[1].u.operand); |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2279 | ProfileTypeBytecodeFlag flag = static_cast<ProfileTypeBytecodeFlag>(pc[3].u.operand); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2280 | SymbolTable* symbolTable = nullptr; |
| 2281 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2282 | switch (flag) { |
saambarati1@gmail.com | f07b1bc | 2015-07-28 22:39:12 +0000 | [diff] [blame] | 2283 | case ProfileTypeBytecodeClosureVar: { |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2284 | const Identifier& ident = identifier(pc[4].u.operand); |
saambarati1@gmail.com | f07b1bc | 2015-07-28 22:39:12 +0000 | [diff] [blame] | 2285 | int localScopeDepth = pc[2].u.operand; |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2286 | ResolveType type = static_cast<ResolveType>(pc[5].u.operand); |
saambarati1@gmail.com | f07b1bc | 2015-07-28 22:39:12 +0000 | [diff] [blame] | 2287 | // Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because |
| 2288 | // we're abstractly "read"ing from a JSScope. |
sbarati@apple.com | 3a9165f | 2016-05-24 22:28:20 +0000 | [diff] [blame] | 2289 | const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, type, InitializationMode::NotInitialization); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2290 | |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2291 | if (op.type == ClosureVar || op.type == ModuleVar) |
oliver@apple.com | a7dfb4d | 2014-09-11 18:18:14 +0000 | [diff] [blame] | 2292 | symbolTable = op.lexicalEnvironment->symbolTable(); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2293 | else if (op.type == GlobalVar) |
| 2294 | symbolTable = m_globalObject.get()->symbolTable(); |
utatane.tea@gmail.com | 6c38958 | 2015-09-04 04:29:04 +0000 | [diff] [blame] | 2295 | |
| 2296 | UniquedStringImpl* impl = (op.type == ModuleVar) ? op.importedName.get() : ident.impl(); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2297 | if (symbolTable) { |
| 2298 | ConcurrentJITLocker locker(symbolTable->m_lock); |
| 2299 | // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet. |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2300 | symbolTable->prepareForTypeProfiling(locker); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2301 | globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, vm); |
| 2302 | globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, vm); |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2303 | } else |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2304 | globalVariableID = TypeProfilerNoGlobalIDExists; |
commit-queue@webkit.org | eafc9b3 | 2014-08-14 23:59:44 +0000 | [diff] [blame] | 2305 | |
| 2306 | break; |
| 2307 | } |
saambarati1@gmail.com | f07b1bc | 2015-07-28 22:39:12 +0000 | [diff] [blame] | 2308 | case ProfileTypeBytecodeLocallyResolved: { |
| 2309 | int symbolTableIndex = pc[2].u.operand; |
saambarati1@gmail.com | f07b1bc | 2015-07-28 22:39:12 +0000 | [diff] [blame] | 2310 | SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex)); |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2311 | const Identifier& ident = identifier(pc[4].u.operand); |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2312 | ConcurrentJITLocker locker(symbolTable->m_lock); |
| 2313 | // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet. |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2314 | globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), vm); |
| 2315 | globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), vm); |
oliver@apple.com | f129dfb | 2014-10-02 20:35:58 +0000 | [diff] [blame] | 2316 | |
| 2317 | break; |
| 2318 | } |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2319 | case ProfileTypeBytecodeDoesNotHaveGlobalID: |
| 2320 | case ProfileTypeBytecodeFunctionArgument: { |
| 2321 | globalVariableID = TypeProfilerNoGlobalIDExists; |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2322 | break; |
| 2323 | } |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2324 | case ProfileTypeBytecodeFunctionReturnStatement: { |
commit-queue@webkit.org | f6bd2fb | 2014-08-26 02:17:58 +0000 | [diff] [blame] | 2325 | RELEASE_ASSERT(ownerExecutable->isFunctionExecutable()); |
| 2326 | globalTypeSet = jsCast<FunctionExecutable*>(ownerExecutable)->returnStatementTypeSet(); |
commit-queue@webkit.org | 2ed31ec | 2014-08-21 01:03:20 +0000 | [diff] [blame] | 2327 | globalVariableID = TypeProfilerReturnStatement; |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2328 | if (!shouldAnalyze) { |
commit-queue@webkit.org | 9653c66 | 2014-08-26 04:36:42 +0000 | [diff] [blame] | 2329 | // Because a return statement can be added implicitly to return undefined at the end of a function, |
| 2330 | // and these nodes don't emit expression ranges because they aren't in the actual source text of |
| 2331 | // the user's program, give the type profiler some range to identify these return statements. |
commit-queue@webkit.org | f1d9ed8 | 2015-08-17 22:57:23 +0000 | [diff] [blame] | 2332 | // Currently, the text offset that is used as identification is "f" in the function keyword |
commit-queue@webkit.org | 9653c66 | 2014-08-26 04:36:42 +0000 | [diff] [blame] | 2333 | // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable. |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2334 | divotStart = divotEnd = ownerExecutable->typeProfilingStartOffset(); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2335 | shouldAnalyze = true; |
| 2336 | } |
| 2337 | break; |
| 2338 | } |
| 2339 | } |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 2340 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2341 | std::pair<TypeLocation*, bool> locationPair = vm.typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID, |
| 2342 | ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, &vm); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2343 | TypeLocation* location = locationPair.first; |
| 2344 | bool isNewLocation = locationPair.second; |
| 2345 | |
commit-queue@webkit.org | 9653c66 | 2014-08-26 04:36:42 +0000 | [diff] [blame] | 2346 | if (flag == ProfileTypeBytecodeFunctionReturnStatement) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2347 | location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset(); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2348 | |
| 2349 | if (shouldAnalyze && isNewLocation) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2350 | vm.typeProfiler()->insertNewLocation(location); |
fpizlo@apple.com | a398a56 | 2014-08-06 21:32:55 +0000 | [diff] [blame] | 2351 | |
fpizlo@apple.com | 3378c48 | 2014-07-27 23:14:40 +0000 | [diff] [blame] | 2352 | instructions[i + 2].u.location = location; |
| 2353 | break; |
| 2354 | } |
| 2355 | |
mark.lam@apple.com | 3dec4c6 | 2014-03-03 22:12:10 +0000 | [diff] [blame] | 2356 | case op_debug: { |
| 2357 | if (pc[1].u.index == DidReachBreakpoint) |
| 2358 | m_hasDebuggerStatement = true; |
| 2359 | break; |
| 2360 | } |
| 2361 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 2362 | case op_save: { |
| 2363 | unsigned liveCalleeLocalsIndex = pc[2].u.index; |
| 2364 | int offset = pc[3].u.operand; |
| 2365 | if (liveCalleeLocalsIndex >= mergePointBytecodeOffsets.size()) |
| 2366 | mergePointBytecodeOffsets.resize(liveCalleeLocalsIndex + 1); |
| 2367 | mergePointBytecodeOffsets[liveCalleeLocalsIndex] = i + offset; |
| 2368 | break; |
| 2369 | } |
| 2370 | |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2371 | default: |
| 2372 | break; |
| 2373 | } |
| 2374 | i += opLength; |
| 2375 | } |
saambarati1@gmail.com | b4f28a5 | 2014-12-05 05:58:07 +0000 | [diff] [blame] | 2376 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2377 | if (vm.controlFlowProfiler()) |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 2378 | insertBasicBlockBoundariesForControlFlowProfiler(instructions); |
saambarati1@gmail.com | b4f28a5 | 2014-12-05 05:58:07 +0000 | [diff] [blame] | 2379 | |
aestes@apple.com | 13aae08 | 2016-01-02 08:03:08 +0000 | [diff] [blame] | 2380 | m_instructions = WTFMove(instructions); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 2381 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 2382 | // Perform bytecode liveness analysis to determine which locals are live and should be resumed when executing op_resume. |
| 2383 | if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode) { |
| 2384 | if (size_t count = mergePointBytecodeOffsets.size()) { |
| 2385 | createRareDataIfNecessary(); |
| 2386 | BytecodeLivenessAnalysis liveness(this); |
| 2387 | m_rareData->m_liveCalleeLocalsAtYield.grow(count); |
| 2388 | size_t liveCalleeLocalsIndex = 0; |
| 2389 | for (size_t bytecodeOffset : mergePointBytecodeOffsets) { |
| 2390 | m_rareData->m_liveCalleeLocalsAtYield[liveCalleeLocalsIndex] = liveness.getLivenessInfoAtBytecodeOffset(bytecodeOffset); |
| 2391 | ++liveCalleeLocalsIndex; |
| 2392 | } |
| 2393 | } |
| 2394 | } |
| 2395 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 2396 | // Set optimization thresholds only after m_instructions is initialized, since these |
| 2397 | // rely on the instruction count (and are in theory permitted to also inspect the |
| 2398 | // instruction stream to more accurate assess the cost of tier-up). |
| 2399 | optimizeAfterWarmUp(); |
| 2400 | jitAfterWarmUp(); |
| 2401 | |
oliver@apple.com | 9e1c809 | 2013-07-25 04:03:16 +0000 | [diff] [blame] | 2402 | // If the concurrent thread will want the code block's hash, then compute it here |
| 2403 | // synchronously. |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 2404 | if (Options::alwaysComputeHash()) |
oliver@apple.com | 9e1c809 | 2013-07-25 04:03:16 +0000 | [diff] [blame] | 2405 | hash(); |
| 2406 | |
msaboff@apple.com | 77adfde | 2012-11-29 03:16:11 +0000 | [diff] [blame] | 2407 | if (Options::dumpGeneratedBytecodes()) |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 2408 | dumpBytecode(); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 2409 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2410 | heap()->m_codeBlocks.add(this); |
| 2411 | heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction)); |
weinig@apple.com | 0e9a7ee | 2008-12-06 22:31:14 +0000 | [diff] [blame] | 2412 | } |
| 2413 | |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2414 | #if ENABLE(WEBASSEMBLY) |
ossy@webkit.org | da31b4c | 2015-10-19 16:20:08 +0000 | [diff] [blame] | 2415 | CodeBlock::CodeBlock(VM* vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject) |
| 2416 | : JSCell(*vm, structure) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2417 | , m_globalObject(globalObject->vm(), this, globalObject) |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 2418 | , m_numCalleeLocals(0) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2419 | , m_numVars(0) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2420 | , m_shouldAlwaysBeInlined(false) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2421 | #if ENABLE(JIT) |
| 2422 | , m_capabilityLevelState(DFG::CannotCompile) |
| 2423 | #endif |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2424 | , m_didFailFTLCompilation(false) |
| 2425 | , m_hasBeenCompiledWithFTL(false) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2426 | , m_isConstructor(false) |
| 2427 | , m_isStrictMode(false) |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2428 | , m_codeType(FunctionCode) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2429 | , m_hasDebuggerStatement(false) |
| 2430 | , m_steppingMode(SteppingModeDisabled) |
| 2431 | , m_numBreakpoints(0) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2432 | , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable) |
ossy@webkit.org | da31b4c | 2015-10-19 16:20:08 +0000 | [diff] [blame] | 2433 | , m_vm(vm) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2434 | , m_osrExitCounter(0) |
| 2435 | , m_optimizationDelayCounter(0) |
| 2436 | , m_reoptimizationRetryCounter(0) |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 2437 | , m_creationTime(std::chrono::steady_clock::now()) |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2438 | { |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2439 | ASSERT(heap()->isDeferred()); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2440 | } |
| 2441 | |
| 2442 | void CodeBlock::finishCreation(VM& vm, WebAssemblyExecutable*, JSGlobalObject*) |
| 2443 | { |
| 2444 | Base::finishCreation(vm); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2445 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2446 | heap()->m_codeBlocks.add(this); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2447 | } |
| 2448 | #endif |
| 2449 | |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 2450 | CodeBlock::~CodeBlock() |
| 2451 | { |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 2452 | if (m_vm->m_perBytecodeProfiler) |
| 2453 | m_vm->m_perBytecodeProfiler->notifyDestruction(this); |
fpizlo@apple.com | 4a81fa4 | 2012-12-05 01:26:13 +0000 | [diff] [blame] | 2454 | |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 2455 | #if ENABLE(VERBOSE_VALUE_PROFILE) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 2456 | dumpValueProfiles(); |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 2457 | #endif |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2458 | |
fpizlo@apple.com | a474964 | 2011-09-07 02:05:02 +0000 | [diff] [blame] | 2459 | // We may be destroyed before any CodeBlocks that refer to us are destroyed. |
| 2460 | // Consider that two CodeBlocks become unreachable at the same time. There |
| 2461 | // is no guarantee about the order in which the CodeBlocks are destroyed. |
| 2462 | // So, if we don't remove incoming calls, and get destroyed before the |
| 2463 | // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's |
| 2464 | // destructor will try to remove nodes from our (no longer valid) linked list. |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2465 | unlinkIncomingCalls(); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 2466 | |
| 2467 | // Note that our outgoing calls will be removed from other CodeBlocks' |
| 2468 | // m_incomingCalls linked lists through the execution of the ~CallLinkInfo |
| 2469 | // destructors. |
fpizlo@apple.com | 95a9f0d | 2011-08-20 02:17:49 +0000 | [diff] [blame] | 2470 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2471 | #if ENABLE(JIT) |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 2472 | for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) { |
| 2473 | StructureStubInfo* stub = *iter; |
| 2474 | stub->aboutToDie(); |
| 2475 | stub->deref(); |
| 2476 | } |
oliver@apple.com | 942e37d | 2010-07-07 01:35:56 +0000 | [diff] [blame] | 2477 | #endif // ENABLE(JIT) |
weinig@apple.com | 3412bb4 | 2008-09-01 21:22:54 +0000 | [diff] [blame] | 2478 | } |
| 2479 | |
sbarati@apple.com | 93c4d33 | 2016-04-12 22:42:06 +0000 | [diff] [blame] | 2480 | void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation) |
| 2481 | { |
| 2482 | ASSERT(constants.size() == constantsSourceCodeRepresentation.size()); |
| 2483 | size_t count = constants.size(); |
| 2484 | m_constantRegisters.resizeToFit(count); |
| 2485 | bool hasTypeProfiler = !!m_vm->typeProfiler(); |
| 2486 | for (size_t i = 0; i < count; i++) { |
| 2487 | JSValue constant = constants[i].get(); |
| 2488 | |
| 2489 | if (!constant.isEmpty()) { |
| 2490 | if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(constant)) { |
| 2491 | if (hasTypeProfiler) { |
| 2492 | ConcurrentJITLocker locker(symbolTable->m_lock); |
| 2493 | symbolTable->prepareForTypeProfiling(locker); |
| 2494 | } |
| 2495 | constant = symbolTable->cloneScopePart(*m_vm); |
| 2496 | } |
| 2497 | } |
| 2498 | |
| 2499 | m_constantRegisters[i].set(*m_vm, this, constant); |
| 2500 | } |
| 2501 | |
| 2502 | m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation; |
| 2503 | } |
| 2504 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2505 | void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative) |
| 2506 | { |
| 2507 | m_alternative.set(vm, this, alternative); |
| 2508 | } |
| 2509 | |
fpizlo@apple.com | c4d5496 | 2012-01-10 22:08:47 +0000 | [diff] [blame] | 2510 | void CodeBlock::setNumParameters(int newValue) |
| 2511 | { |
| 2512 | m_numParameters = newValue; |
| 2513 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 2514 | m_argumentValueProfiles = RefCountedArray<ValueProfile>(newValue); |
fpizlo@apple.com | c4d5496 | 2012-01-10 22:08:47 +0000 | [diff] [blame] | 2515 | } |
| 2516 | |
oliver@apple.com | 433d02f | 2011-04-21 23:08:15 +0000 | [diff] [blame] | 2517 | void EvalCodeCache::visitAggregate(SlotVisitor& visitor) |
oliver@apple.com | ba10bec | 2011-03-08 23:17:32 +0000 | [diff] [blame] | 2518 | { |
| 2519 | EvalCacheMap::iterator end = m_cacheMap.end(); |
| 2520 | for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr) |
benjamin@webkit.org | ee55405 | 2012-10-07 23:12:07 +0000 | [diff] [blame] | 2521 | visitor.append(&ptr->value); |
oliver@apple.com | ba10bec | 2011-03-08 23:17:32 +0000 | [diff] [blame] | 2522 | } |
| 2523 | |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 2524 | CodeBlock* CodeBlock::specialOSREntryBlockOrNull() |
| 2525 | { |
| 2526 | #if ENABLE(FTL_JIT) |
| 2527 | if (jitType() != JITCode::DFGJIT) |
| 2528 | return 0; |
| 2529 | DFG::JITCode* jitCode = m_jitCode->dfg(); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2530 | return jitCode->osrEntryBlock(); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 2531 | #else // ENABLE(FTL_JIT) |
| 2532 | return 0; |
| 2533 | #endif // ENABLE(FTL_JIT) |
| 2534 | } |
| 2535 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2536 | void CodeBlock::visitWeakly(SlotVisitor& visitor) |
ggaren@apple.com | 51be9a2 | 2015-09-09 22:00:58 +0000 | [diff] [blame] | 2537 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2538 | bool setByMe = m_visitWeaklyHasBeenCalled.compareExchangeStrong(false, true); |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 2539 | if (!setByMe) |
| 2540 | return; |
| 2541 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2542 | if (Heap::isMarked(this)) |
ggaren@apple.com | 7567c16 | 2015-10-07 23:10:20 +0000 | [diff] [blame] | 2543 | return; |
ggaren@apple.com | 893cf14 | 2015-10-09 17:54:16 +0000 | [diff] [blame] | 2544 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2545 | if (shouldVisitStrongly()) { |
| 2546 | visitor.appendUnbarrieredReadOnlyPointer(this); |
| 2547 | return; |
fpizlo@apple.com | 7c084e0 | 2013-09-04 05:48:06 +0000 | [diff] [blame] | 2548 | } |
| 2549 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2550 | // There are two things that may use unconditional finalizers: inline cache clearing |
| 2551 | // and jettisoning. The probability of us wanting to do at least one of those things |
| 2552 | // is probably quite close to 1. So we add one no matter what and when it runs, it |
| 2553 | // figures out whether it has any work to do. |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2554 | visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer); |
| 2555 | |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 2556 | if (!JITCode::isOptimizingJIT(jitType())) |
| 2557 | return; |
| 2558 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2559 | // If we jettison ourselves we'll install our alternative, so make sure that it |
| 2560 | // survives GC even if we don't. |
| 2561 | visitor.append(&m_alternative); |
| 2562 | |
mhahnenberg@apple.com | 7d223bb | 2014-04-02 23:50:25 +0000 | [diff] [blame] | 2563 | // There are two things that we use weak reference harvesters for: DFG fixpoint for |
| 2564 | // jettisoning, and trying to find structures that would be live based on some |
| 2565 | // inline cache. So it makes sense to register them regardless. |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2566 | visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester); |
mhahnenberg@apple.com | 7d223bb | 2014-04-02 23:50:25 +0000 | [diff] [blame] | 2567 | |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2568 | #if ENABLE(DFG_JIT) |
| 2569 | // We get here if we're live in the sense that our owner executable is live, |
| 2570 | // but we're not yet live for sure in another sense: we may yet decide that this |
| 2571 | // code block should be jettisoned based on its outgoing weak references being |
| 2572 | // stale. Set a flag to indicate that we're still assuming that we're dead, and |
| 2573 | // perform one round of determining if we're live. The GC may determine, based on |
| 2574 | // either us marking additional objects, or by other objects being marked for |
| 2575 | // other reasons, that this iteration should run again; it will notify us of this |
| 2576 | // decision by calling harvestWeakReferences(). |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2577 | |
| 2578 | m_allTransitionsHaveBeenMarked = false; |
ggaren@apple.com | 893cf14 | 2015-10-09 17:54:16 +0000 | [diff] [blame] | 2579 | propagateTransitions(visitor); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2580 | |
| 2581 | m_jitCode->dfgCommon()->livenessHasBeenProved = false; |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2582 | determineLiveness(visitor); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2583 | #endif // ENABLE(DFG_JIT) |
| 2584 | } |
| 2585 | |
commit-queue@webkit.org | 00eb52f | 2016-03-01 02:07:12 +0000 | [diff] [blame] | 2586 | size_t CodeBlock::estimatedSize(JSCell* cell) |
| 2587 | { |
| 2588 | CodeBlock* thisObject = jsCast<CodeBlock*>(cell); |
| 2589 | size_t extraMemoryAllocated = thisObject->m_instructions.size() * sizeof(Instruction); |
| 2590 | if (thisObject->m_jitCode) |
| 2591 | extraMemoryAllocated += thisObject->m_jitCode->size(); |
| 2592 | return Base::estimatedSize(cell) + extraMemoryAllocated; |
| 2593 | } |
| 2594 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2595 | void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) |
| 2596 | { |
| 2597 | CodeBlock* thisObject = jsCast<CodeBlock*>(cell); |
| 2598 | ASSERT_GC_OBJECT_INHERITS(thisObject, info()); |
| 2599 | JSCell::visitChildren(thisObject, visitor); |
| 2600 | thisObject->visitChildren(visitor); |
| 2601 | } |
| 2602 | |
| 2603 | void CodeBlock::visitChildren(SlotVisitor& visitor) |
| 2604 | { |
| 2605 | // There are two things that may use unconditional finalizers: inline cache clearing |
| 2606 | // and jettisoning. The probability of us wanting to do at least one of those things |
| 2607 | // is probably quite close to 1. So we add one no matter what and when it runs, it |
| 2608 | // figures out whether it has any work to do. |
| 2609 | visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer); |
| 2610 | |
| 2611 | if (CodeBlock* otherBlock = specialOSREntryBlockOrNull()) |
| 2612 | visitor.appendUnbarrieredReadOnlyPointer(otherBlock); |
| 2613 | |
| 2614 | if (m_jitCode) |
| 2615 | visitor.reportExtraMemoryVisited(m_jitCode->size()); |
| 2616 | if (m_instructions.size()) |
| 2617 | visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / m_instructions.refCount()); |
| 2618 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2619 | stronglyVisitStrongReferences(visitor); |
| 2620 | stronglyVisitWeakReferences(visitor); |
| 2621 | |
| 2622 | m_allTransitionsHaveBeenMarked = false; |
| 2623 | propagateTransitions(visitor); |
| 2624 | } |
| 2625 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2626 | bool CodeBlock::shouldVisitStrongly() |
fpizlo@apple.com | 04a048c | 2014-04-28 19:01:07 +0000 | [diff] [blame] | 2627 | { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 2628 | if (Options::forceCodeBlockLiveness()) |
| 2629 | return true; |
| 2630 | |
| 2631 | if (shouldJettisonDueToOldAge()) |
| 2632 | return false; |
| 2633 | |
fpizlo@apple.com | 04a048c | 2014-04-28 19:01:07 +0000 | [diff] [blame] | 2634 | // Interpreter and Baseline JIT CodeBlocks don't need to be jettisoned when |
| 2635 | // their weak references go stale. So if a basline JIT CodeBlock gets |
| 2636 | // scanned, we can assume that this means that it's live. |
| 2637 | if (!JITCode::isOptimizingJIT(jitType())) |
| 2638 | return true; |
| 2639 | |
fpizlo@apple.com | 04a048c | 2014-04-28 19:01:07 +0000 | [diff] [blame] | 2640 | return false; |
fpizlo@apple.com | 04a048c | 2014-04-28 19:01:07 +0000 | [diff] [blame] | 2641 | } |
| 2642 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2643 | bool CodeBlock::shouldJettisonDueToWeakReference() |
| 2644 | { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 2645 | if (!JITCode::isOptimizingJIT(jitType())) |
| 2646 | return false; |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2647 | return !Heap::isMarked(this); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2648 | } |
| 2649 | |
| 2650 | bool CodeBlock::shouldJettisonDueToOldAge() |
| 2651 | { |
commit-queue@webkit.org | 1029454 | 2016-01-26 03:12:29 +0000 | [diff] [blame] | 2652 | return false; |
fpizlo@apple.com | 04a048c | 2014-04-28 19:01:07 +0000 | [diff] [blame] | 2653 | } |
| 2654 | |
fpizlo@apple.com | 4adaa96 | 2014-08-06 05:55:39 +0000 | [diff] [blame] | 2655 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2656 | static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition) |
| 2657 | { |
| 2658 | if (transition.m_codeOrigin && !Heap::isMarked(transition.m_codeOrigin.get())) |
| 2659 | return false; |
| 2660 | |
| 2661 | if (!Heap::isMarked(transition.m_from.get())) |
| 2662 | return false; |
| 2663 | |
| 2664 | return true; |
| 2665 | } |
fpizlo@apple.com | 4adaa96 | 2014-08-06 05:55:39 +0000 | [diff] [blame] | 2666 | #endif // ENABLE(DFG_JIT) |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2667 | |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2668 | void CodeBlock::propagateTransitions(SlotVisitor& visitor) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2669 | { |
| 2670 | UNUSED_PARAM(visitor); |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2671 | |
| 2672 | if (m_allTransitionsHaveBeenMarked) |
| 2673 | return; |
| 2674 | |
| 2675 | bool allAreMarkedSoFar = true; |
| 2676 | |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2677 | Interpreter* interpreter = m_vm->interpreter; |
| 2678 | if (jitType() == JITCode::InterpreterThunk) { |
| 2679 | const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions(); |
oliver@apple.com | c0a31d7 | 2013-07-25 04:03:36 +0000 | [diff] [blame] | 2680 | for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) { |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2681 | Instruction* instruction = &instructions()[propertyAccessInstructions[i]]; |
| 2682 | switch (interpreter->getOpcodeID(instruction[0].u.opcode)) { |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2683 | case op_put_by_id: { |
| 2684 | StructureID oldStructureID = instruction[4].u.structureID; |
| 2685 | StructureID newStructureID = instruction[6].u.structureID; |
| 2686 | if (!oldStructureID || !newStructureID) |
| 2687 | break; |
| 2688 | Structure* oldStructure = |
| 2689 | m_vm->heap.structureIDTable().get(oldStructureID); |
| 2690 | Structure* newStructure = |
| 2691 | m_vm->heap.structureIDTable().get(newStructureID); |
| 2692 | if (Heap::isMarked(oldStructure)) |
| 2693 | visitor.appendUnbarrieredReadOnlyPointer(newStructure); |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2694 | else |
| 2695 | allAreMarkedSoFar = false; |
| 2696 | break; |
| 2697 | } |
| 2698 | default: |
| 2699 | break; |
| 2700 | } |
| 2701 | } |
| 2702 | } |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2703 | |
| 2704 | #if ENABLE(JIT) |
| 2705 | if (JITCode::isJIT(jitType())) { |
fpizlo@apple.com | dd39b9e | 2016-05-04 02:23:28 +0000 | [diff] [blame] | 2706 | for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) |
| 2707 | allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor); |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2708 | } |
| 2709 | #endif // ENABLE(JIT) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2710 | |
| 2711 | #if ENABLE(DFG_JIT) |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2712 | if (JITCode::isOptimizingJIT(jitType())) { |
| 2713 | DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); |
fpizlo@apple.com | dd39b9e | 2016-05-04 02:23:28 +0000 | [diff] [blame] | 2714 | for (auto& weakReference : dfgCommon->weakStructureReferences) |
| 2715 | allAreMarkedSoFar &= weakReference->markIfCheap(visitor); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2716 | |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 2717 | for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) { |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2718 | if (shouldMarkTransition(dfgCommon->transitions[i])) { |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2719 | // If the following three things are live, then the target of the |
| 2720 | // transition is also live: |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2721 | // |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2722 | // - This code block. We know it's live already because otherwise |
| 2723 | // we wouldn't be scanning ourselves. |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2724 | // |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2725 | // - The code origin of the transition. Transitions may arise from |
| 2726 | // code that was inlined. They are not relevant if the user's |
| 2727 | // object that is required for the inlinee to run is no longer |
| 2728 | // live. |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2729 | // |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2730 | // - The source of the transition. The transition checks if some |
| 2731 | // heap location holds the source, and if so, stores the target. |
| 2732 | // Hence the source must be live for the transition to be live. |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2733 | // |
| 2734 | // We also short-circuit the liveness if the structure is harmless |
| 2735 | // to mark (i.e. its global object and prototype are both already |
| 2736 | // live). |
| 2737 | |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 2738 | visitor.append(&dfgCommon->transitions[i].m_to); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2739 | } else |
| 2740 | allAreMarkedSoFar = false; |
| 2741 | } |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2742 | } |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2743 | #endif // ENABLE(DFG_JIT) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2744 | |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2745 | if (allAreMarkedSoFar) |
| 2746 | m_allTransitionsHaveBeenMarked = true; |
| 2747 | } |
| 2748 | |
| 2749 | void CodeBlock::determineLiveness(SlotVisitor& visitor) |
| 2750 | { |
| 2751 | UNUSED_PARAM(visitor); |
| 2752 | |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2753 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2754 | // Check if we have any remaining work to do. |
oliver@apple.com | a152471 | 2013-07-25 04:01:56 +0000 | [diff] [blame] | 2755 | DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 2756 | if (dfgCommon->livenessHasBeenProved) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2757 | return; |
| 2758 | |
| 2759 | // Now check all of our weak references. If all of them are live, then we |
| 2760 | // have proved liveness and so we scan our strong references. If at end of |
| 2761 | // GC we still have not proved liveness, then this code block is toast. |
| 2762 | bool allAreLiveSoFar = true; |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 2763 | for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) { |
| 2764 | if (!Heap::isMarked(dfgCommon->weakReferences[i].get())) { |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2765 | allAreLiveSoFar = false; |
| 2766 | break; |
| 2767 | } |
| 2768 | } |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 2769 | if (allAreLiveSoFar) { |
| 2770 | for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) { |
| 2771 | if (!Heap::isMarked(dfgCommon->weakStructureReferences[i].get())) { |
| 2772 | allAreLiveSoFar = false; |
| 2773 | break; |
| 2774 | } |
| 2775 | } |
| 2776 | } |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2777 | |
| 2778 | // If some weak references are dead, then this fixpoint iteration was |
| 2779 | // unsuccessful. |
| 2780 | if (!allAreLiveSoFar) |
| 2781 | return; |
| 2782 | |
| 2783 | // All weak references are live. Record this information so we don't |
| 2784 | // come back here again, and scan the strong references. |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 2785 | dfgCommon->livenessHasBeenProved = true; |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2786 | visitor.appendUnbarrieredReadOnlyPointer(this); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2787 | #endif // ENABLE(DFG_JIT) |
| 2788 | } |
| 2789 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2790 | void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor) |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2791 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2792 | CodeBlock* codeBlock = |
| 2793 | bitwise_cast<CodeBlock*>( |
| 2794 | bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester)); |
| 2795 | |
| 2796 | codeBlock->propagateTransitions(visitor); |
| 2797 | codeBlock->determineLiveness(visitor); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2798 | } |
| 2799 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2800 | void CodeBlock::finalizeLLIntInlineCaches() |
fpizlo@apple.com | cf71612 | 2012-07-13 06:41:18 +0000 | [diff] [blame] | 2801 | { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2802 | #if ENABLE(WEBASSEMBLY) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2803 | if (m_ownerExecutable->isWebAssemblyExecutable()) |
| 2804 | return; |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 2805 | #endif |
oliver@apple.com | c909f5f | 2012-10-18 23:37:40 +0000 | [diff] [blame] | 2806 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2807 | Interpreter* interpreter = m_vm->interpreter; |
| 2808 | const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions(); |
| 2809 | for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) { |
| 2810 | Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]]; |
| 2811 | switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) { |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 2812 | case op_get_by_id: |
keith_miller@apple.com | 785c651 | 2016-05-27 18:36:30 +0000 | [diff] [blame^] | 2813 | case op_get_by_id_proto_load: |
| 2814 | case op_get_by_id_unset: { |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2815 | StructureID oldStructureID = curInstruction[4].u.structureID; |
| 2816 | if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2817 | break; |
| 2818 | if (Options::verboseOSR()) |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2819 | dataLogF("Clearing LLInt property access.\n"); |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 2820 | clearLLIntGetByIdCache(curInstruction); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2821 | break; |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2822 | } |
| 2823 | case op_put_by_id: { |
| 2824 | StructureID oldStructureID = curInstruction[4].u.structureID; |
| 2825 | StructureID newStructureID = curInstruction[6].u.structureID; |
| 2826 | StructureChain* chain = curInstruction[7].u.structureChain.get(); |
| 2827 | if ((!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) && |
| 2828 | (!newStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(newStructureID))) && |
| 2829 | (!chain || Heap::isMarked(chain))) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2830 | break; |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2831 | if (Options::verboseOSR()) |
| 2832 | dataLogF("Clearing LLInt put transition.\n"); |
| 2833 | curInstruction[4].u.structureID = 0; |
| 2834 | curInstruction[5].u.operand = 0; |
| 2835 | curInstruction[6].u.structureID = 0; |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2836 | curInstruction[7].u.structureChain.clear(); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2837 | break; |
fpizlo@apple.com | e7ec7fb | 2015-09-15 00:55:17 +0000 | [diff] [blame] | 2838 | } |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2839 | case op_get_array_length: |
| 2840 | break; |
| 2841 | case op_to_this: |
| 2842 | if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get())) |
| 2843 | break; |
| 2844 | if (Options::verboseOSR()) |
| 2845 | dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get()); |
| 2846 | curInstruction[2].u.structure.clear(); |
| 2847 | curInstruction[3].u.toThisStatus = merge( |
| 2848 | curInstruction[3].u.toThisStatus, ToThisClearedByGC); |
| 2849 | break; |
| 2850 | case op_create_this: { |
| 2851 | auto& cacheWriteBarrier = curInstruction[4].u.jsCell; |
| 2852 | if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects()) |
| 2853 | break; |
| 2854 | JSCell* cachedFunction = cacheWriteBarrier.get(); |
| 2855 | if (Heap::isMarked(cachedFunction)) |
| 2856 | break; |
| 2857 | if (Options::verboseOSR()) |
| 2858 | dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction); |
| 2859 | cacheWriteBarrier.clear(); |
| 2860 | break; |
| 2861 | } |
| 2862 | case op_resolve_scope: { |
| 2863 | // Right now this isn't strictly necessary. Any symbol tables that this will refer to |
| 2864 | // are for outer functions, and we refer to those functions strongly, and they refer |
| 2865 | // to the symbol table strongly. But it's nice to be on the safe side. |
| 2866 | WriteBarrierBase<SymbolTable>& symbolTable = curInstruction[6].u.symbolTable; |
| 2867 | if (!symbolTable || Heap::isMarked(symbolTable.get())) |
| 2868 | break; |
| 2869 | if (Options::verboseOSR()) |
| 2870 | dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get()); |
| 2871 | symbolTable.clear(); |
| 2872 | break; |
| 2873 | } |
| 2874 | case op_get_from_scope: |
| 2875 | case op_put_to_scope: { |
| 2876 | GetPutInfo getPutInfo = GetPutInfo(curInstruction[4].u.operand); |
| 2877 | if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks |
| 2878 | || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks) |
| 2879 | continue; |
| 2880 | WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure; |
| 2881 | if (!structure || Heap::isMarked(structure.get())) |
| 2882 | break; |
| 2883 | if (Options::verboseOSR()) |
| 2884 | dataLogF("Clearing scope access with structure %p.\n", structure.get()); |
| 2885 | structure.clear(); |
| 2886 | break; |
| 2887 | } |
| 2888 | default: |
| 2889 | OpcodeID opcodeID = interpreter->getOpcodeID(curInstruction[0].u.opcode); |
| 2890 | ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]); |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 2891 | } |
fpizlo@apple.com | cd8eb2c | 2013-09-20 18:42:41 +0000 | [diff] [blame] | 2892 | } |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 2893 | |
keith_miller@apple.com | 8350adf | 2016-05-24 23:49:57 +0000 | [diff] [blame] | 2894 | // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set |
| 2895 | // then cleared the cache without GCing in between. |
| 2896 | m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool { |
| 2897 | return !Heap::isMarked(pair.key); |
| 2898 | }); |
| 2899 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2900 | for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) { |
| 2901 | if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) { |
| 2902 | if (Options::verboseOSR()) |
| 2903 | dataLog("Clearing LLInt call from ", *this, "\n"); |
| 2904 | m_llintCallLinkInfos[i].unlink(); |
fpizlo@apple.com | 1e89af3 | 2012-11-19 02:55:14 +0000 | [diff] [blame] | 2905 | } |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2906 | if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get())) |
| 2907 | m_llintCallLinkInfos[i].lastSeenCallee.clear(); |
| 2908 | } |
| 2909 | } |
| 2910 | |
| 2911 | void CodeBlock::finalizeBaselineJITInlineCaches() |
| 2912 | { |
ggaren@apple.com | 95bf67e | 2015-09-11 17:35:59 +0000 | [diff] [blame] | 2913 | #if ENABLE(JIT) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2914 | for (auto iter = callLinkInfosBegin(); !!iter; ++iter) |
| 2915 | (*iter)->visitWeak(*vm()); |
| 2916 | |
| 2917 | for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) { |
| 2918 | StructureStubInfo& stubInfo = **iter; |
| 2919 | stubInfo.visitWeakReferences(this); |
| 2920 | } |
ggaren@apple.com | 95bf67e | 2015-09-11 17:35:59 +0000 | [diff] [blame] | 2921 | #endif |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2922 | } |
| 2923 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2924 | void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally() |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2925 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2926 | CodeBlock* codeBlock = bitwise_cast<CodeBlock*>( |
| 2927 | bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer)); |
| 2928 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2929 | #if ENABLE(DFG_JIT) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2930 | if (codeBlock->shouldJettisonDueToWeakReference()) { |
| 2931 | codeBlock->jettison(Profiler::JettisonDueToWeakReference); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2932 | return; |
| 2933 | } |
| 2934 | #endif // ENABLE(DFG_JIT) |
oliver@apple.com | c909f5f | 2012-10-18 23:37:40 +0000 | [diff] [blame] | 2935 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2936 | if (codeBlock->shouldJettisonDueToOldAge()) { |
| 2937 | codeBlock->jettison(Profiler::JettisonDueToOldAge); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2938 | return; |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2939 | } |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2940 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2941 | if (JITCode::couldBeInterpreted(codeBlock->jitType())) |
| 2942 | codeBlock->finalizeLLIntInlineCaches(); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 2943 | |
| 2944 | #if ENABLE(JIT) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 2945 | if (!!codeBlock->jitCode()) |
| 2946 | codeBlock->finalizeBaselineJITInlineCaches(); |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2947 | #endif |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 2948 | } |
| 2949 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 2950 | void CodeBlock::getStubInfoMap(const ConcurrentJITLocker&, StubInfoMap& result) |
| 2951 | { |
| 2952 | #if ENABLE(JIT) |
| 2953 | toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result); |
| 2954 | #else |
| 2955 | UNUSED_PARAM(result); |
| 2956 | #endif |
| 2957 | } |
| 2958 | |
| 2959 | void CodeBlock::getStubInfoMap(StubInfoMap& result) |
| 2960 | { |
| 2961 | ConcurrentJITLocker locker(m_lock); |
| 2962 | getStubInfoMap(locker, result); |
| 2963 | } |
| 2964 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 2965 | void CodeBlock::getCallLinkInfoMap(const ConcurrentJITLocker&, CallLinkInfoMap& result) |
| 2966 | { |
| 2967 | #if ENABLE(JIT) |
| 2968 | toHashMap(m_callLinkInfos, getCallLinkInfoCodeOrigin, result); |
| 2969 | #else |
| 2970 | UNUSED_PARAM(result); |
| 2971 | #endif |
| 2972 | } |
| 2973 | |
| 2974 | void CodeBlock::getCallLinkInfoMap(CallLinkInfoMap& result) |
| 2975 | { |
| 2976 | ConcurrentJITLocker locker(m_lock); |
| 2977 | getCallLinkInfoMap(locker, result); |
| 2978 | } |
| 2979 | |
utatane.tea@gmail.com | fccd136 | 2015-08-11 22:02:09 +0000 | [diff] [blame] | 2980 | void CodeBlock::getByValInfoMap(const ConcurrentJITLocker&, ByValInfoMap& result) |
| 2981 | { |
| 2982 | #if ENABLE(JIT) |
| 2983 | for (auto* byValInfo : m_byValInfos) |
| 2984 | result.add(CodeOrigin(byValInfo->bytecodeIndex), byValInfo); |
| 2985 | #else |
| 2986 | UNUSED_PARAM(result); |
| 2987 | #endif |
| 2988 | } |
| 2989 | |
| 2990 | void CodeBlock::getByValInfoMap(ByValInfoMap& result) |
| 2991 | { |
| 2992 | ConcurrentJITLocker locker(m_lock); |
| 2993 | getByValInfoMap(locker, result); |
| 2994 | } |
| 2995 | |
fpizlo@apple.com | cf71612 | 2012-07-13 06:41:18 +0000 | [diff] [blame] | 2996 | #if ENABLE(JIT) |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 2997 | StructureStubInfo* CodeBlock::addStubInfo(AccessType accessType) |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 2998 | { |
| 2999 | ConcurrentJITLocker locker(m_lock); |
fpizlo@apple.com | b26b524 | 2015-09-10 19:49:36 +0000 | [diff] [blame] | 3000 | return m_stubInfos.add(accessType); |
fpizlo@apple.com | d49bfe8 | 2013-10-19 02:20:14 +0000 | [diff] [blame] | 3001 | } |
| 3002 | |
fpizlo@apple.com | 4c6b8ad | 2014-07-22 21:08:50 +0000 | [diff] [blame] | 3003 | StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin) |
| 3004 | { |
| 3005 | for (StructureStubInfo* stubInfo : m_stubInfos) { |
| 3006 | if (stubInfo->codeOrigin == codeOrigin) |
| 3007 | return stubInfo; |
| 3008 | } |
| 3009 | return nullptr; |
| 3010 | } |
| 3011 | |
utatane.tea@gmail.com | fccd136 | 2015-08-11 22:02:09 +0000 | [diff] [blame] | 3012 | ByValInfo* CodeBlock::addByValInfo() |
| 3013 | { |
| 3014 | ConcurrentJITLocker locker(m_lock); |
| 3015 | return m_byValInfos.add(); |
| 3016 | } |
| 3017 | |
fpizlo@apple.com | ba262b2 | 2014-03-23 04:34:38 +0000 | [diff] [blame] | 3018 | CallLinkInfo* CodeBlock::addCallLinkInfo() |
| 3019 | { |
| 3020 | ConcurrentJITLocker locker(m_lock); |
| 3021 | return m_callLinkInfos.add(); |
| 3022 | } |
| 3023 | |
fpizlo@apple.com | f7100b6 | 2014-03-24 17:29:51 +0000 | [diff] [blame] | 3024 | CallLinkInfo* CodeBlock::getCallLinkInfoForBytecodeIndex(unsigned index) |
| 3025 | { |
| 3026 | for (auto iter = m_callLinkInfos.begin(); !!iter; ++iter) { |
msaboff@apple.com | 203a56e | 2015-06-24 22:37:30 +0000 | [diff] [blame] | 3027 | if ((*iter)->codeOrigin() == CodeOrigin(index)) |
fpizlo@apple.com | f7100b6 | 2014-03-24 17:29:51 +0000 | [diff] [blame] | 3028 | return *iter; |
| 3029 | } |
| 3030 | return nullptr; |
| 3031 | } |
fpizlo@apple.com | cf71612 | 2012-07-13 06:41:18 +0000 | [diff] [blame] | 3032 | #endif |
| 3033 | |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3034 | void CodeBlock::visitOSRExitTargets(SlotVisitor& visitor) |
| 3035 | { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3036 | // We strongly visit OSR exits targets because we don't want to deal with |
| 3037 | // the complexity of generating an exit target CodeBlock on demand and |
| 3038 | // guaranteeing that it matches the details of the CodeBlock we compiled |
| 3039 | // the OSR exit against. |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3040 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3041 | visitor.append(&m_alternative); |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3042 | |
ggaren@apple.com | 6520f0c | 2015-09-09 22:26:16 +0000 | [diff] [blame] | 3043 | #if ENABLE(DFG_JIT) |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3044 | DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); |
| 3045 | if (dfgCommon->inlineCallFrames) { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3046 | for (auto* inlineCallFrame : *dfgCommon->inlineCallFrames) { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3047 | ASSERT(inlineCallFrame->baselineCodeBlock); |
| 3048 | visitor.append(&inlineCallFrame->baselineCodeBlock); |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3049 | } |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3050 | } |
ggaren@apple.com | 6520f0c | 2015-09-09 22:26:16 +0000 | [diff] [blame] | 3051 | #endif |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3052 | } |
| 3053 | |
fpizlo@apple.com | a147a4d | 2011-11-21 04:45:17 +0000 | [diff] [blame] | 3054 | void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) |
| 3055 | { |
oliver@apple.com | 433d02f | 2011-04-21 23:08:15 +0000 | [diff] [blame] | 3056 | visitor.append(&m_globalObject); |
| 3057 | visitor.append(&m_ownerExecutable); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 3058 | visitor.append(&m_unlinkedCode); |
| 3059 | if (m_rareData) |
oliver@apple.com | 433d02f | 2011-04-21 23:08:15 +0000 | [diff] [blame] | 3060 | m_rareData->m_evalCodeCache.visitAggregate(visitor); |
| 3061 | visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size()); |
barraclough@apple.com | 306bb12 | 2009-08-18 05:34:52 +0000 | [diff] [blame] | 3062 | for (size_t i = 0; i < m_functionExprs.size(); ++i) |
oliver@apple.com | 433d02f | 2011-04-21 23:08:15 +0000 | [diff] [blame] | 3063 | visitor.append(&m_functionExprs[i]); |
barraclough@apple.com | 306bb12 | 2009-08-18 05:34:52 +0000 | [diff] [blame] | 3064 | for (size_t i = 0; i < m_functionDecls.size(); ++i) |
oliver@apple.com | 433d02f | 2011-04-21 23:08:15 +0000 | [diff] [blame] | 3065 | visitor.append(&m_functionDecls[i]); |
ggaren@apple.com | c862eac | 2013-01-29 05:48:01 +0000 | [diff] [blame] | 3066 | for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i) |
| 3067 | m_objectAllocationProfiles[i].visitAggregate(visitor); |
fpizlo@apple.com | d13163d | 2011-09-03 05:14:04 +0000 | [diff] [blame] | 3068 | |
ggaren@apple.com | 156eb59 | 2015-09-09 22:06:49 +0000 | [diff] [blame] | 3069 | #if ENABLE(DFG_JIT) |
| 3070 | if (JITCode::isOptimizingJIT(jitType())) |
| 3071 | visitOSRExitTargets(visitor); |
| 3072 | #endif |
| 3073 | |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3074 | updateAllPredictions(); |
fpizlo@apple.com | 5e37f9a | 2011-11-17 00:49:50 +0000 | [diff] [blame] | 3075 | } |
| 3076 | |
| 3077 | void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor) |
| 3078 | { |
ggaren@apple.com | 7ac9ed8 | 2011-11-17 01:43:48 +0000 | [diff] [blame] | 3079 | UNUSED_PARAM(visitor); |
| 3080 | |
| 3081 | #if ENABLE(DFG_JIT) |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 3082 | if (!JITCode::isOptimizingJIT(jitType())) |
fpizlo@apple.com | 5e37f9a | 2011-11-17 00:49:50 +0000 | [diff] [blame] | 3083 | return; |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 3084 | |
| 3085 | DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); |
ggaren@apple.com | 7ac9ed8 | 2011-11-17 01:43:48 +0000 | [diff] [blame] | 3086 | |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 3087 | for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) { |
| 3088 | if (!!dfgCommon->transitions[i].m_codeOrigin) |
| 3089 | visitor.append(&dfgCommon->transitions[i].m_codeOrigin); // Almost certainly not necessary, since the code origin should also be a weak reference. Better to be safe, though. |
| 3090 | visitor.append(&dfgCommon->transitions[i].m_from); |
| 3091 | visitor.append(&dfgCommon->transitions[i].m_to); |
fpizlo@apple.com | 5e37f9a | 2011-11-17 00:49:50 +0000 | [diff] [blame] | 3092 | } |
| 3093 | |
oliver@apple.com | 02b179b | 2013-07-25 03:58:20 +0000 | [diff] [blame] | 3094 | for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) |
| 3095 | visitor.append(&dfgCommon->weakReferences[i]); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 3096 | |
| 3097 | for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) |
| 3098 | visitor.append(&dfgCommon->weakStructureReferences[i]); |
ggaren@apple.com | 51be9a2 | 2015-09-09 22:00:58 +0000 | [diff] [blame] | 3099 | |
| 3100 | dfgCommon->livenessHasBeenProved = true; |
ggaren@apple.com | 7ac9ed8 | 2011-11-17 01:43:48 +0000 | [diff] [blame] | 3101 | #endif |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 3102 | } |
| 3103 | |
fpizlo@apple.com | 501e606 | 2013-11-01 22:10:52 +0000 | [diff] [blame] | 3104 | CodeBlock* CodeBlock::baselineAlternative() |
| 3105 | { |
| 3106 | #if ENABLE(JIT) |
| 3107 | CodeBlock* result = this; |
| 3108 | while (result->alternative()) |
| 3109 | result = result->alternative(); |
| 3110 | RELEASE_ASSERT(result); |
| 3111 | RELEASE_ASSERT(JITCode::isBaselineCode(result->jitType()) || result->jitType() == JITCode::None); |
| 3112 | return result; |
| 3113 | #else |
| 3114 | return this; |
| 3115 | #endif |
| 3116 | } |
| 3117 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3118 | CodeBlock* CodeBlock::baselineVersion() |
| 3119 | { |
fpizlo@apple.com | 501e606 | 2013-11-01 22:10:52 +0000 | [diff] [blame] | 3120 | #if ENABLE(JIT) |
fpizlo@apple.com | 669223d | 2013-09-01 02:02:47 +0000 | [diff] [blame] | 3121 | if (JITCode::isBaselineCode(jitType())) |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3122 | return this; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3123 | CodeBlock* result = replacement(); |
fpizlo@apple.com | cd8eb2c | 2013-09-20 18:42:41 +0000 | [diff] [blame] | 3124 | if (!result) { |
| 3125 | // This can happen if we're creating the original CodeBlock for an executable. |
| 3126 | // Assume that we're the baseline CodeBlock. |
fpizlo@apple.com | 501e606 | 2013-11-01 22:10:52 +0000 | [diff] [blame] | 3127 | RELEASE_ASSERT(jitType() == JITCode::None); |
fpizlo@apple.com | cd8eb2c | 2013-09-20 18:42:41 +0000 | [diff] [blame] | 3128 | return this; |
| 3129 | } |
fpizlo@apple.com | 501e606 | 2013-11-01 22:10:52 +0000 | [diff] [blame] | 3130 | result = result->baselineAlternative(); |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3131 | return result; |
| 3132 | #else |
fpizlo@apple.com | cd8eb2c | 2013-09-20 18:42:41 +0000 | [diff] [blame] | 3133 | return this; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3134 | #endif |
| 3135 | } |
| 3136 | |
| 3137 | #if ENABLE(JIT) |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3138 | bool CodeBlock::hasOptimizedReplacement(JITCode::JITType typeToReplace) |
| 3139 | { |
| 3140 | return JITCode::isHigherTier(replacement()->jitType(), typeToReplace); |
| 3141 | } |
| 3142 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3143 | bool CodeBlock::hasOptimizedReplacement() |
| 3144 | { |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3145 | return hasOptimizedReplacement(jitType()); |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3146 | } |
| 3147 | #endif |
| 3148 | |
mark.lam@apple.com | 6ed0827 | 2015-06-05 18:52:12 +0000 | [diff] [blame] | 3149 | HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler) |
mrowe@apple.com | f88a463 | 2008-09-07 05:44:58 +0000 | [diff] [blame] | 3150 | { |
oliver@apple.com | 49a2c14 | 2013-04-04 21:25:26 +0000 | [diff] [blame] | 3151 | RELEASE_ASSERT(bytecodeOffset < instructions().size()); |
sbarati@apple.com | 36c1340 | 2015-09-18 23:37:42 +0000 | [diff] [blame] | 3152 | return handlerForIndex(bytecodeOffset, requiredHandler); |
| 3153 | } |
weinig@apple.com | 06885cf | 2008-12-17 21:25:40 +0000 | [diff] [blame] | 3154 | |
sbarati@apple.com | 36c1340 | 2015-09-18 23:37:42 +0000 | [diff] [blame] | 3155 | HandlerInfo* CodeBlock::handlerForIndex(unsigned index, RequiredHandler requiredHandler) |
| 3156 | { |
weinig@apple.com | 4557e84 | 2008-12-09 01:06:14 +0000 | [diff] [blame] | 3157 | if (!m_rareData) |
| 3158 | return 0; |
mrowe@apple.com | f88a463 | 2008-09-07 05:44:58 +0000 | [diff] [blame] | 3159 | |
weinig@apple.com | 18064e7 | 2008-12-10 00:26:13 +0000 | [diff] [blame] | 3160 | Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers; |
| 3161 | for (size_t i = 0; i < exceptionHandlers.size(); ++i) { |
mark.lam@apple.com | 4585ce9 | 2015-05-30 00:19:01 +0000 | [diff] [blame] | 3162 | HandlerInfo& handler = exceptionHandlers[i]; |
mark.lam@apple.com | 6ed0827 | 2015-06-05 18:52:12 +0000 | [diff] [blame] | 3163 | if ((requiredHandler == RequiredHandler::CatchHandler) && !handler.isCatchHandler()) |
| 3164 | continue; |
| 3165 | |
weinig@apple.com | 18064e7 | 2008-12-10 00:26:13 +0000 | [diff] [blame] | 3166 | // Handlers are ordered innermost first, so the first handler we encounter |
| 3167 | // that contains the source address is the correct handler to use. |
sbarati@apple.com | 36c1340 | 2015-09-18 23:37:42 +0000 | [diff] [blame] | 3168 | // This index used is either the BytecodeOffset or a CallSiteIndex. |
| 3169 | if (handler.start <= index && handler.end > index) |
mark.lam@apple.com | 4585ce9 | 2015-05-30 00:19:01 +0000 | [diff] [blame] | 3170 | return &handler; |
mrowe@apple.com | f88a463 | 2008-09-07 05:44:58 +0000 | [diff] [blame] | 3171 | } |
| 3172 | |
| 3173 | return 0; |
| 3174 | } |
| 3175 | |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 3176 | CallSiteIndex CodeBlock::newExceptionHandlingCallSiteIndex(CallSiteIndex originalCallSite) |
| 3177 | { |
| 3178 | #if ENABLE(DFG_JIT) |
sbarati@apple.com | 5bebda7 | 2015-11-10 07:48:54 +0000 | [diff] [blame] | 3179 | RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType())); |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 3180 | RELEASE_ASSERT(canGetCodeOrigin(originalCallSite)); |
| 3181 | ASSERT(!!handlerForIndex(originalCallSite.bits())); |
| 3182 | CodeOrigin originalOrigin = codeOrigin(originalCallSite); |
sbarati@apple.com | 2697fe7 | 2015-10-12 20:37:05 +0000 | [diff] [blame] | 3183 | return m_jitCode->dfgCommon()->addUniqueCallSiteIndex(originalOrigin); |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 3184 | #else |
| 3185 | // We never create new on-the-fly exception handling |
| 3186 | // call sites outside the DFG/FTL inline caches. |
sbarati@apple.com | 9bf79cf | 2015-10-08 20:24:25 +0000 | [diff] [blame] | 3187 | UNUSED_PARAM(originalCallSite); |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 3188 | RELEASE_ASSERT_NOT_REACHED(); |
mark.lam@apple.com | ceb2fc2 | 2015-10-14 16:23:16 +0000 | [diff] [blame] | 3189 | return CallSiteIndex(0u); |
sbarati@apple.com | 9aacac4 | 2015-10-08 19:37:28 +0000 | [diff] [blame] | 3190 | #endif |
| 3191 | } |
| 3192 | |
| 3193 | void CodeBlock::removeExceptionHandlerForCallSite(CallSiteIndex callSiteIndex) |
| 3194 | { |
| 3195 | RELEASE_ASSERT(m_rareData); |
| 3196 | Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers; |
| 3197 | unsigned index = callSiteIndex.bits(); |
| 3198 | for (size_t i = 0; i < exceptionHandlers.size(); ++i) { |
| 3199 | HandlerInfo& handler = exceptionHandlers[i]; |
| 3200 | if (handler.start <= index && handler.end > index) { |
| 3201 | exceptionHandlers.remove(i); |
| 3202 | return; |
| 3203 | } |
| 3204 | } |
| 3205 | |
| 3206 | RELEASE_ASSERT_NOT_REACHED(); |
| 3207 | } |
| 3208 | |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 3209 | unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset) |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 3210 | { |
oliver@apple.com | 903b0c0 | 2013-01-24 01:40:37 +0000 | [diff] [blame] | 3211 | RELEASE_ASSERT(bytecodeOffset < instructions().size()); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3212 | return ownerScriptExecutable()->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset); |
mrowe@apple.com | 2f6dfdf | 2008-05-22 01:20:45 +0000 | [diff] [blame] | 3213 | } |
| 3214 | |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 3215 | unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset) |
oliver@apple.com | 90b88ae | 2008-07-19 01:44:24 +0000 | [diff] [blame] | 3216 | { |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 3217 | int divot; |
| 3218 | int startOffset; |
| 3219 | int endOffset; |
| 3220 | unsigned line; |
| 3221 | unsigned column; |
| 3222 | expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column); |
| 3223 | return column; |
| 3224 | } |
| 3225 | |
| 3226 | void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) |
| 3227 | { |
| 3228 | m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column); |
oliver@apple.com | f0c01b8 | 2012-11-07 00:13:54 +0000 | [diff] [blame] | 3229 | divot += m_sourceOffset; |
mark.lam@apple.com | 5b45f90 | 2013-07-09 16:15:12 +0000 | [diff] [blame] | 3230 | column += line ? 1 : firstLineColumnOffset(); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3231 | line += ownerScriptExecutable()->firstLine(); |
oliver@apple.com | 90b88ae | 2008-07-19 01:44:24 +0000 | [diff] [blame] | 3232 | } |
| 3233 | |
mark.lam@apple.com | 945b139 | 2014-01-23 07:39:58 +0000 | [diff] [blame] | 3234 | bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column) |
| 3235 | { |
| 3236 | Interpreter* interpreter = vm()->interpreter; |
| 3237 | const Instruction* begin = instructions().begin(); |
| 3238 | const Instruction* end = instructions().end(); |
| 3239 | for (const Instruction* it = begin; it != end;) { |
| 3240 | OpcodeID opcodeID = interpreter->getOpcodeID(it->u.opcode); |
| 3241 | if (opcodeID == op_debug) { |
| 3242 | unsigned bytecodeOffset = it - begin; |
| 3243 | int unused; |
| 3244 | unsigned opDebugLine; |
| 3245 | unsigned opDebugColumn; |
| 3246 | expressionRangeForBytecodeOffset(bytecodeOffset, unused, unused, unused, opDebugLine, opDebugColumn); |
| 3247 | if (line == opDebugLine && (column == Breakpoint::unspecifiedColumn || column == opDebugColumn)) |
| 3248 | return true; |
| 3249 | } |
| 3250 | it += opcodeLengths[opcodeID]; |
| 3251 | } |
| 3252 | return false; |
| 3253 | } |
| 3254 | |
fpizlo@apple.com | db79da2 | 2012-05-16 00:56:54 +0000 | [diff] [blame] | 3255 | void CodeBlock::shrinkToFit(ShrinkMode shrinkMode) |
weinig@apple.com | 9d9d25d | 2008-12-05 20:27:58 +0000 | [diff] [blame] | 3256 | { |
fpizlo@apple.com | db79da2 | 2012-05-16 00:56:54 +0000 | [diff] [blame] | 3257 | m_rareCaseProfiles.shrinkToFit(); |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 3258 | m_resultProfiles.shrinkToFit(); |
fpizlo@apple.com | db79da2 | 2012-05-16 00:56:54 +0000 | [diff] [blame] | 3259 | |
| 3260 | if (shrinkMode == EarlyShrink) { |
fpizlo@apple.com | db79da2 | 2012-05-16 00:56:54 +0000 | [diff] [blame] | 3261 | m_constantRegisters.shrinkToFit(); |
benjamin@webkit.org | 54d94f5 | 2015-02-28 03:21:37 +0000 | [diff] [blame] | 3262 | m_constantsSourceCodeRepresentation.shrinkToFit(); |
oliver@apple.com | 9b7647b | 2013-07-25 04:03:00 +0000 | [diff] [blame] | 3263 | |
| 3264 | if (m_rareData) { |
oliver@apple.com | a14cea5 | 2013-07-25 04:03:23 +0000 | [diff] [blame] | 3265 | m_rareData->m_switchJumpTables.shrinkToFit(); |
oliver@apple.com | 9b7647b | 2013-07-25 04:03:00 +0000 | [diff] [blame] | 3266 | m_rareData->m_stringSwitchJumpTables.shrinkToFit(); |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 3267 | m_rareData->m_liveCalleeLocalsAtYield.shrinkToFit(); |
oliver@apple.com | 9b7647b | 2013-07-25 04:03:00 +0000 | [diff] [blame] | 3268 | } |
fpizlo@apple.com | db79da2 | 2012-05-16 00:56:54 +0000 | [diff] [blame] | 3269 | } // else don't shrink these, because we would have already pointed pointers into these tables. |
weinig@apple.com | 9d9d25d | 2008-12-05 20:27:58 +0000 | [diff] [blame] | 3270 | } |
| 3271 | |
oliver@apple.com | 1db480d | 2011-06-28 01:32:01 +0000 | [diff] [blame] | 3272 | #if ENABLE(JIT) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3273 | void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming) |
| 3274 | { |
| 3275 | noticeIncomingCall(callerFrame); |
| 3276 | m_incomingCalls.push(incoming); |
| 3277 | } |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3278 | |
| 3279 | void CodeBlock::linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode* incoming) |
| 3280 | { |
| 3281 | noticeIncomingCall(callerFrame); |
| 3282 | m_incomingPolymorphicCalls.push(incoming); |
| 3283 | } |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 3284 | #endif // ENABLE(JIT) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3285 | |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3286 | void CodeBlock::unlinkIncomingCalls() |
| 3287 | { |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 3288 | while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) |
| 3289 | m_incomingLLIntCalls.begin()->unlink(); |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 3290 | #if ENABLE(JIT) |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3291 | while (m_incomingCalls.begin() != m_incomingCalls.end()) |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 3292 | m_incomingCalls.begin()->unlink(*vm()); |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3293 | while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end()) |
fpizlo@apple.com | 7a79726 | 2015-09-03 21:11:59 +0000 | [diff] [blame] | 3294 | m_incomingPolymorphicCalls.begin()->unlink(*vm()); |
commit-queue@webkit.org | ea1f902 | 2013-08-29 16:41:07 +0000 | [diff] [blame] | 3295 | #endif // ENABLE(JIT) |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 3296 | } |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 3297 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3298 | void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming) |
| 3299 | { |
| 3300 | noticeIncomingCall(callerFrame); |
| 3301 | m_incomingLLIntCalls.push(incoming); |
| 3302 | } |
commit-queue@webkit.org | f76b9d5 | 2012-08-20 23:48:00 +0000 | [diff] [blame] | 3303 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3304 | CodeBlock* CodeBlock::newReplacement() |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 3305 | { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3306 | return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind()); |
fpizlo@apple.com | 62b6af8 | 2013-08-29 18:25:36 +0000 | [diff] [blame] | 3307 | } |
| 3308 | |
fpizlo@apple.com | af478bb | 2011-09-06 23:36:51 +0000 | [diff] [blame] | 3309 | #if ENABLE(JIT) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3310 | CodeBlock* CodeBlock::replacement() |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3311 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3312 | const ClassInfo* classInfo = this->classInfo(); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3313 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3314 | if (classInfo == FunctionCodeBlock::info()) |
| 3315 | return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall); |
utatane.tea@gmail.com | a8309d9 | 2015-09-01 02:05:30 +0000 | [diff] [blame] | 3316 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3317 | if (classInfo == EvalCodeBlock::info()) |
| 3318 | return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock(); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3319 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3320 | if (classInfo == ProgramCodeBlock::info()) |
| 3321 | return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock(); |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3322 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3323 | if (classInfo == ModuleProgramCodeBlock::info()) |
| 3324 | return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock(); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3325 | |
| 3326 | #if ENABLE(WEBASSEMBLY) |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3327 | if (classInfo == WebAssemblyCodeBlock::info()) |
| 3328 | return nullptr; |
| 3329 | #endif |
| 3330 | |
| 3331 | RELEASE_ASSERT_NOT_REACHED(); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3332 | return nullptr; |
| 3333 | } |
| 3334 | |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3335 | DFG::CapabilityLevel CodeBlock::computeCapabilityLevel() |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3336 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3337 | const ClassInfo* classInfo = this->classInfo(); |
| 3338 | |
| 3339 | if (classInfo == FunctionCodeBlock::info()) { |
| 3340 | if (m_isConstructor) |
| 3341 | return DFG::functionForConstructCapabilityLevel(this); |
| 3342 | return DFG::functionForCallCapabilityLevel(this); |
| 3343 | } |
| 3344 | |
| 3345 | if (classInfo == EvalCodeBlock::info()) |
| 3346 | return DFG::evalCapabilityLevel(this); |
| 3347 | |
| 3348 | if (classInfo == ProgramCodeBlock::info()) |
| 3349 | return DFG::programCapabilityLevel(this); |
| 3350 | |
| 3351 | if (classInfo == ModuleProgramCodeBlock::info()) |
| 3352 | return DFG::programCapabilityLevel(this); |
| 3353 | |
| 3354 | #if ENABLE(WEBASSEMBLY) |
| 3355 | if (classInfo == WebAssemblyCodeBlock::info()) |
| 3356 | return DFG::CannotCompile; |
| 3357 | #endif |
| 3358 | |
| 3359 | RELEASE_ASSERT_NOT_REACHED(); |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 3360 | return DFG::CannotCompile; |
| 3361 | } |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3362 | |
| 3363 | #endif // ENABLE(JIT) |
fpizlo@apple.com | 706f5f3 | 2011-09-21 23:36:35 +0000 | [diff] [blame] | 3364 | |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 3365 | void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail) |
fpizlo@apple.com | 706f5f3 | 2011-09-21 23:36:35 +0000 | [diff] [blame] | 3366 | { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3367 | #if !ENABLE(DFG_JIT) |
| 3368 | UNUSED_PARAM(mode); |
| 3369 | UNUSED_PARAM(detail); |
| 3370 | #endif |
fpizlo@apple.com | 4a528d0 | 2016-05-11 00:08:50 +0000 | [diff] [blame] | 3371 | |
| 3372 | CODEBLOCK_LOG_EVENT(this, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail))); |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3373 | |
fpizlo@apple.com | 0dda6d7 | 2014-02-02 02:25:13 +0000 | [diff] [blame] | 3374 | RELEASE_ASSERT(reason != Profiler::NotJettisoned); |
| 3375 | |
fpizlo@apple.com | 580c6f0 | 2013-10-30 20:22:40 +0000 | [diff] [blame] | 3376 | #if ENABLE(DFG_JIT) |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 3377 | if (DFG::shouldDumpDisassembly()) { |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3378 | dataLog("Jettisoning ", *this); |
| 3379 | if (mode == CountReoptimization) |
| 3380 | dataLog(" and counting reoptimization"); |
fpizlo@apple.com | 2c4a7e9 | 2014-08-06 05:27:46 +0000 | [diff] [blame] | 3381 | dataLog(" due to ", reason); |
| 3382 | if (detail) |
| 3383 | dataLog(", ", *detail); |
| 3384 | dataLog(".\n"); |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3385 | } |
| 3386 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3387 | if (reason == Profiler::JettisonDueToWeakReference) { |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 3388 | if (DFG::shouldDumpDisassembly()) { |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3389 | dataLog(*this, " will be jettisoned because of the following dead references:\n"); |
| 3390 | DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); |
| 3391 | for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) { |
| 3392 | DFG::WeakReferenceTransition& transition = dfgCommon->transitions[i]; |
| 3393 | JSCell* origin = transition.m_codeOrigin.get(); |
| 3394 | JSCell* from = transition.m_from.get(); |
| 3395 | JSCell* to = transition.m_to.get(); |
| 3396 | if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from)) |
| 3397 | continue; |
| 3398 | dataLog(" Transition under ", RawPointer(origin), ", ", RawPointer(from), " -> ", RawPointer(to), ".\n"); |
| 3399 | } |
| 3400 | for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) { |
| 3401 | JSCell* weak = dfgCommon->weakReferences[i].get(); |
| 3402 | if (Heap::isMarked(weak)) |
| 3403 | continue; |
| 3404 | dataLog(" Weak reference ", RawPointer(weak), ".\n"); |
| 3405 | } |
| 3406 | } |
| 3407 | } |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3408 | #endif // ENABLE(DFG_JIT) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3409 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 3410 | DeferGCForAWhile deferGC(*heap()); |
fpizlo@apple.com | 0dda6d7 | 2014-02-02 02:25:13 +0000 | [diff] [blame] | 3411 | |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3412 | // We want to accomplish two things here: |
| 3413 | // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it |
| 3414 | // we should OSR exit at the top of the next bytecode instruction after the return. |
| 3415 | // 2) Make sure that if we call the owner executable, then we shouldn't call this CodeBlock. |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3416 | |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3417 | #if ENABLE(DFG_JIT) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3418 | if (reason != Profiler::JettisonDueToOldAge) { |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3419 | if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get()) |
| 3420 | compilation->setJettisonReason(reason, detail); |
| 3421 | |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3422 | // This accomplishes (1), and does its own book-keeping about whether it has already happened. |
| 3423 | if (!jitCode()->dfgCommon()->invalidate()) { |
| 3424 | // We've already been invalidated. |
| 3425 | RELEASE_ASSERT(this != replacement()); |
| 3426 | return; |
| 3427 | } |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3428 | } |
| 3429 | |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 3430 | if (DFG::shouldDumpDisassembly()) |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3431 | dataLog(" Did invalidate ", *this, "\n"); |
| 3432 | |
| 3433 | // Count the reoptimization if that's what the user wanted. |
| 3434 | if (mode == CountReoptimization) { |
fpizlo@apple.com | 78e1b2b | 2013-11-03 00:32:23 +0000 | [diff] [blame] | 3435 | // FIXME: Maybe this should call alternative(). |
| 3436 | // https://bugs.webkit.org/show_bug.cgi?id=123677 |
| 3437 | baselineAlternative()->countReoptimization(); |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 3438 | if (DFG::shouldDumpDisassembly()) |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3439 | dataLog(" Did count reoptimization for ", *this, "\n"); |
| 3440 | } |
| 3441 | |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3442 | if (this != replacement()) { |
| 3443 | // This means that we were never the entrypoint. This can happen for OSR entry code |
| 3444 | // blocks. |
| 3445 | return; |
| 3446 | } |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3447 | |
| 3448 | if (alternative()) |
| 3449 | alternative()->optimizeAfterWarmUp(); |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3450 | |
| 3451 | if (reason != Profiler::JettisonDueToOldAge) |
| 3452 | tallyFrequentExitSites(); |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3453 | #endif // ENABLE(DFG_JIT) |
ggaren@apple.com | 111b3fa | 2015-09-11 16:08:39 +0000 | [diff] [blame] | 3454 | |
ggaren@apple.com | 0548385 | 2015-09-17 00:28:34 +0000 | [diff] [blame] | 3455 | // This accomplishes (2). |
| 3456 | ownerScriptExecutable()->installCode( |
| 3457 | m_globalObject->vm(), alternative(), codeType(), specializationKind()); |
| 3458 | |
| 3459 | #if ENABLE(DFG_JIT) |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 3460 | if (DFG::shouldDumpDisassembly()) |
fpizlo@apple.com | d84425d | 2013-10-30 19:58:08 +0000 | [diff] [blame] | 3461 | dataLog(" Did install baseline version of ", *this, "\n"); |
fpizlo@apple.com | 580c6f0 | 2013-10-30 20:22:40 +0000 | [diff] [blame] | 3462 | #endif // ENABLE(DFG_JIT) |
fpizlo@apple.com | 706f5f3 | 2011-09-21 23:36:35 +0000 | [diff] [blame] | 3463 | } |
fpizlo@apple.com | 594887a | 2011-09-06 09:23:55 +0000 | [diff] [blame] | 3464 | |
fpizlo@apple.com | 5e2296a | 2013-01-07 02:24:58 +0000 | [diff] [blame] | 3465 | JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin) |
| 3466 | { |
| 3467 | if (!codeOrigin.inlineCallFrame) |
| 3468 | return globalObject(); |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 3469 | return codeOrigin.inlineCallFrame->baselineCodeBlock->globalObject(); |
fpizlo@apple.com | 5e2296a | 2013-01-07 02:24:58 +0000 | [diff] [blame] | 3470 | } |
| 3471 | |
msaboff@apple.com | 4d563e4 | 2014-08-16 01:45:40 +0000 | [diff] [blame] | 3472 | class RecursionCheckFunctor { |
| 3473 | public: |
| 3474 | RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck) |
| 3475 | : m_startCallFrame(startCallFrame) |
| 3476 | , m_codeBlock(codeBlock) |
| 3477 | , m_depthToCheck(depthToCheck) |
| 3478 | , m_foundStartCallFrame(false) |
| 3479 | , m_didRecurse(false) |
| 3480 | { } |
| 3481 | |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 3482 | StackVisitor::Status operator()(StackVisitor& visitor) const |
msaboff@apple.com | 4d563e4 | 2014-08-16 01:45:40 +0000 | [diff] [blame] | 3483 | { |
| 3484 | CallFrame* currentCallFrame = visitor->callFrame(); |
| 3485 | |
| 3486 | if (currentCallFrame == m_startCallFrame) |
| 3487 | m_foundStartCallFrame = true; |
| 3488 | |
| 3489 | if (m_foundStartCallFrame) { |
| 3490 | if (visitor->callFrame()->codeBlock() == m_codeBlock) { |
| 3491 | m_didRecurse = true; |
| 3492 | return StackVisitor::Done; |
| 3493 | } |
| 3494 | |
| 3495 | if (!m_depthToCheck--) |
| 3496 | return StackVisitor::Done; |
| 3497 | } |
| 3498 | |
| 3499 | return StackVisitor::Continue; |
| 3500 | } |
| 3501 | |
| 3502 | bool didRecurse() const { return m_didRecurse; } |
| 3503 | |
| 3504 | private: |
| 3505 | CallFrame* m_startCallFrame; |
| 3506 | CodeBlock* m_codeBlock; |
fpizlo@apple.com | 39303e0 | 2016-04-05 22:17:35 +0000 | [diff] [blame] | 3507 | mutable unsigned m_depthToCheck; |
| 3508 | mutable bool m_foundStartCallFrame; |
| 3509 | mutable bool m_didRecurse; |
msaboff@apple.com | 4d563e4 | 2014-08-16 01:45:40 +0000 | [diff] [blame] | 3510 | }; |
| 3511 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3512 | void CodeBlock::noticeIncomingCall(ExecState* callerFrame) |
| 3513 | { |
| 3514 | CodeBlock* callerCodeBlock = callerFrame->codeBlock(); |
| 3515 | |
oliver@apple.com | afa7e3a | 2013-07-25 04:02:04 +0000 | [diff] [blame] | 3516 | if (Options::verboseCallLink()) |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3517 | dataLog("Noticing call link from ", pointerDump(callerCodeBlock), " to ", *this, "\n"); |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3518 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3519 | #if ENABLE(DFG_JIT) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3520 | if (!m_shouldAlwaysBeInlined) |
| 3521 | return; |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3522 | |
| 3523 | if (!callerCodeBlock) { |
| 3524 | m_shouldAlwaysBeInlined = false; |
| 3525 | if (Options::verboseCallLink()) |
| 3526 | dataLog(" Clearing SABI because caller is native.\n"); |
| 3527 | return; |
| 3528 | } |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3529 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3530 | if (!hasBaselineJITProfiling()) |
| 3531 | return; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3532 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3533 | if (!DFG::mightInlineFunction(this)) |
| 3534 | return; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3535 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 3536 | if (!canInline(capabilityLevelState())) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3537 | return; |
fpizlo@apple.com | afeb1a9 | 2014-02-23 18:48:43 +0000 | [diff] [blame] | 3538 | |
| 3539 | if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) { |
| 3540 | m_shouldAlwaysBeInlined = false; |
| 3541 | if (Options::verboseCallLink()) |
| 3542 | dataLog(" Clearing SABI because caller is too large.\n"); |
| 3543 | return; |
| 3544 | } |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3545 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3546 | if (callerCodeBlock->jitType() == JITCode::InterpreterThunk) { |
| 3547 | // If the caller is still in the interpreter, then we can't expect inlining to |
| 3548 | // happen anytime soon. Assume it's profitable to optimize it separately. This |
| 3549 | // ensures that a function is SABI only if it is called no more frequently than |
| 3550 | // any of its callers. |
| 3551 | m_shouldAlwaysBeInlined = false; |
oliver@apple.com | afa7e3a | 2013-07-25 04:02:04 +0000 | [diff] [blame] | 3552 | if (Options::verboseCallLink()) |
fpizlo@apple.com | afeb1a9 | 2014-02-23 18:48:43 +0000 | [diff] [blame] | 3553 | dataLog(" Clearing SABI because caller is in LLInt.\n"); |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3554 | return; |
| 3555 | } |
| 3556 | |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3557 | if (JITCode::isOptimizingJIT(callerCodeBlock->jitType())) { |
| 3558 | m_shouldAlwaysBeInlined = false; |
| 3559 | if (Options::verboseCallLink()) |
| 3560 | dataLog(" Clearing SABI bcause caller was already optimized.\n"); |
| 3561 | return; |
| 3562 | } |
| 3563 | |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3564 | if (callerCodeBlock->codeType() != FunctionCode) { |
| 3565 | // If the caller is either eval or global code, assume that that won't be |
| 3566 | // optimized anytime soon. For eval code this is particularly true since we |
| 3567 | // delay eval optimization by a *lot*. |
| 3568 | m_shouldAlwaysBeInlined = false; |
oliver@apple.com | afa7e3a | 2013-07-25 04:02:04 +0000 | [diff] [blame] | 3569 | if (Options::verboseCallLink()) |
fpizlo@apple.com | afeb1a9 | 2014-02-23 18:48:43 +0000 | [diff] [blame] | 3570 | dataLog(" Clearing SABI because caller is not a function.\n"); |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3571 | return; |
| 3572 | } |
msaboff@apple.com | 4d563e4 | 2014-08-16 01:45:40 +0000 | [diff] [blame] | 3573 | |
| 3574 | // Recursive calls won't be inlined. |
| 3575 | RecursionCheckFunctor functor(callerFrame, this, Options::maximumInliningDepth()); |
| 3576 | vm()->topCallFrame->iterate(functor); |
| 3577 | |
| 3578 | if (functor.didRecurse()) { |
| 3579 | if (Options::verboseCallLink()) |
| 3580 | dataLog(" Clearing SABI because recursion was detected.\n"); |
| 3581 | m_shouldAlwaysBeInlined = false; |
| 3582 | return; |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3583 | } |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3584 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 3585 | if (callerCodeBlock->capabilityLevelState() == DFG::CapabilityLevelNotSet) { |
fpizlo@apple.com | 8a5fd18 | 2015-02-02 18:38:08 +0000 | [diff] [blame] | 3586 | dataLog("In call from ", *callerCodeBlock, " ", callerFrame->codeOrigin(), " to ", *this, ": caller's DFG capability level is not set.\n"); |
| 3587 | CRASH(); |
| 3588 | } |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3589 | |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 3590 | if (canCompile(callerCodeBlock->capabilityLevelState())) |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3591 | return; |
| 3592 | |
oliver@apple.com | afa7e3a | 2013-07-25 04:02:04 +0000 | [diff] [blame] | 3593 | if (Options::verboseCallLink()) |
fpizlo@apple.com | afeb1a9 | 2014-02-23 18:48:43 +0000 | [diff] [blame] | 3594 | dataLog(" Clearing SABI because the caller is not a DFG candidate.\n"); |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3595 | |
| 3596 | m_shouldAlwaysBeInlined = false; |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3597 | #endif |
oliver@apple.com | d2cdd31 | 2013-07-25 04:01:00 +0000 | [diff] [blame] | 3598 | } |
| 3599 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3600 | unsigned CodeBlock::reoptimizationRetryCounter() const |
| 3601 | { |
mhahnenberg@apple.com | d79127e | 2014-02-05 01:35:31 +0000 | [diff] [blame] | 3602 | #if ENABLE(JIT) |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3603 | ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax()); |
| 3604 | return m_reoptimizationRetryCounter; |
mhahnenberg@apple.com | d79127e | 2014-02-05 01:35:31 +0000 | [diff] [blame] | 3605 | #else |
| 3606 | return 0; |
| 3607 | #endif // ENABLE(JIT) |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3608 | } |
| 3609 | |
mhahnenberg@apple.com | d79127e | 2014-02-05 01:35:31 +0000 | [diff] [blame] | 3610 | #if ENABLE(JIT) |
msaboff@apple.com | 0208546 | 2015-09-10 17:47:16 +0000 | [diff] [blame] | 3611 | void CodeBlock::setCalleeSaveRegisters(RegisterSet calleeSaveRegisters) |
| 3612 | { |
| 3613 | m_calleeSaveRegisters = std::make_unique<RegisterAtOffsetList>(calleeSaveRegisters); |
| 3614 | } |
| 3615 | |
| 3616 | void CodeBlock::setCalleeSaveRegisters(std::unique_ptr<RegisterAtOffsetList> registerAtOffsetList) |
| 3617 | { |
aestes@apple.com | 13aae08 | 2016-01-02 08:03:08 +0000 | [diff] [blame] | 3618 | m_calleeSaveRegisters = WTFMove(registerAtOffsetList); |
msaboff@apple.com | 0208546 | 2015-09-10 17:47:16 +0000 | [diff] [blame] | 3619 | } |
| 3620 | |
| 3621 | static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters) |
| 3622 | { |
| 3623 | static const unsigned cpuRegisterSize = sizeof(void*); |
| 3624 | return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * cpuRegisterSize) / sizeof(Register)); |
| 3625 | |
| 3626 | } |
| 3627 | |
| 3628 | size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() |
| 3629 | { |
| 3630 | return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters()); |
| 3631 | } |
| 3632 | |
| 3633 | size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters() |
| 3634 | { |
| 3635 | return roundCalleeSaveSpaceAsVirtualRegisters(m_calleeSaveRegisters->size()); |
| 3636 | } |
| 3637 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3638 | void CodeBlock::countReoptimization() |
| 3639 | { |
| 3640 | m_reoptimizationRetryCounter++; |
| 3641 | if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax()) |
| 3642 | m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax(); |
| 3643 | } |
| 3644 | |
oliver@apple.com | 37172f8 | 2013-07-25 04:01:17 +0000 | [diff] [blame] | 3645 | unsigned CodeBlock::numberOfDFGCompiles() |
| 3646 | { |
| 3647 | ASSERT(JITCode::isBaselineCode(jitType())); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 3648 | if (Options::testTheFTL()) { |
| 3649 | if (m_didFailFTLCompilation) |
| 3650 | return 1000000; |
| 3651 | return (m_hasBeenCompiledWithFTL ? 1 : 0) + m_reoptimizationRetryCounter; |
| 3652 | } |
oliver@apple.com | 37172f8 | 2013-07-25 04:01:17 +0000 | [diff] [blame] | 3653 | return (JITCode::isOptimizingJIT(replacement()->jitType()) ? 1 : 0) + m_reoptimizationRetryCounter; |
| 3654 | } |
| 3655 | |
fpizlo@apple.com | d29f963 | 2012-12-18 22:49:40 +0000 | [diff] [blame] | 3656 | int32_t CodeBlock::codeTypeThresholdMultiplier() const |
| 3657 | { |
| 3658 | if (codeType() == EvalCode) |
| 3659 | return Options::evalThresholdMultiplier(); |
| 3660 | |
| 3661 | return 1; |
| 3662 | } |
| 3663 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3664 | double CodeBlock::optimizationThresholdScalingFactor() |
| 3665 | { |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3666 | // This expression arises from doing a least-squares fit of |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3667 | // |
| 3668 | // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d |
| 3669 | // |
| 3670 | // against the data points: |
| 3671 | // |
| 3672 | // x F[x_] |
| 3673 | // 10 0.9 (smallest reasonable code block) |
| 3674 | // 200 1.0 (typical small-ish code block) |
| 3675 | // 320 1.2 (something I saw in 3d-cube that I wanted to optimize) |
| 3676 | // 1268 5.0 (something I saw in 3d-cube that I didn't want to optimize) |
| 3677 | // 4000 5.5 (random large size, used to cause the function to converge to a shallow curve of some sort) |
| 3678 | // 10000 6.0 (similar to above) |
| 3679 | // |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3680 | // I achieve the minimization using the following Mathematica code: |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3681 | // |
| 3682 | // MyFunctionTemplate[x_, a_, b_, c_, d_] := a*Sqrt[x + b] + Abs[c*x] + d |
| 3683 | // |
| 3684 | // samples = {{10, 0.9}, {200, 1}, {320, 1.2}, {1268, 5}, {4000, 5.5}, {10000, 6}} |
| 3685 | // |
| 3686 | // solution = |
| 3687 | // Minimize[Plus @@ ((MyFunctionTemplate[#[[1]], a, b, c, d] - #[[2]])^2 & /@ samples), |
| 3688 | // {a, b, c, d}][[2]] |
| 3689 | // |
| 3690 | // And the code below (to initialize a, b, c, d) is generated by: |
| 3691 | // |
| 3692 | // Print["const double " <> ToString[#[[1]]] <> " = " <> |
| 3693 | // If[#[[2]] < 0.00001, "0.0", ToString[#[[2]]]] <> ";"] & /@ solution |
| 3694 | // |
| 3695 | // We've long known the following to be true: |
| 3696 | // - Small code blocks are cheap to optimize and so we should do it sooner rather |
| 3697 | // than later. |
| 3698 | // - Large code blocks are expensive to optimize and so we should postpone doing so, |
| 3699 | // and sometimes have a large enough threshold that we never optimize them. |
| 3700 | // - The difference in cost is not totally linear because (a) just invoking the |
| 3701 | // DFG incurs some base cost and (b) for large code blocks there is enough slop |
| 3702 | // in the correlation between instruction count and the actual compilation cost |
| 3703 | // that for those large blocks, the instruction count should not have a strong |
| 3704 | // influence on our threshold. |
| 3705 | // |
| 3706 | // I knew the goals but I didn't know how to achieve them; so I picked an interesting |
| 3707 | // example where the heuristics were right (code block in 3d-cube with instruction |
| 3708 | // count 320, which got compiled early as it should have been) and one where they were |
| 3709 | // totally wrong (code block in 3d-cube with instruction count 1268, which was expensive |
| 3710 | // to compile and didn't run often enough to warrant compilation in my opinion), and |
| 3711 | // then threw in additional data points that represented my own guess of what our |
| 3712 | // heuristics should do for some round-numbered examples. |
| 3713 | // |
| 3714 | // The expression to which I decided to fit the data arose because I started with an |
| 3715 | // affine function, and then did two things: put the linear part in an Abs to ensure |
| 3716 | // that the fit didn't end up choosing a negative value of c (which would result in |
| 3717 | // the function turning over and going negative for large x) and I threw in a Sqrt |
| 3718 | // term because Sqrt represents my intution that the function should be more sensitive |
| 3719 | // to small changes in small values of x, but less sensitive when x gets large. |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3720 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3721 | // Note that the current fit essentially eliminates the linear portion of the |
| 3722 | // expression (c == 0.0). |
| 3723 | const double a = 0.061504; |
| 3724 | const double b = 1.02406; |
| 3725 | const double c = 0.0; |
| 3726 | const double d = 0.825914; |
| 3727 | |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3728 | double instructionCount = this->instructionCount(); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3729 | |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3730 | ASSERT(instructionCount); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense. |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3731 | |
ggaren@apple.com | f019398 | 2013-04-03 01:41:16 +0000 | [diff] [blame] | 3732 | double result = d + a * sqrt(instructionCount + b) + c * instructionCount; |
fpizlo@apple.com | 3ce9323 | 2014-03-03 05:42:29 +0000 | [diff] [blame] | 3733 | |
| 3734 | result *= codeTypeThresholdMultiplier(); |
| 3735 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3736 | if (Options::verboseOSR()) { |
| 3737 | dataLog( |
| 3738 | *this, ": instruction count is ", instructionCount, |
| 3739 | ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(), |
| 3740 | "\n"); |
| 3741 | } |
fpizlo@apple.com | 3ce9323 | 2014-03-03 05:42:29 +0000 | [diff] [blame] | 3742 | return result; |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3743 | } |
| 3744 | |
| 3745 | static int32_t clipThreshold(double threshold) |
| 3746 | { |
| 3747 | if (threshold < 1.0) |
| 3748 | return 1; |
| 3749 | |
| 3750 | if (threshold > static_cast<double>(std::numeric_limits<int32_t>::max())) |
| 3751 | return std::numeric_limits<int32_t>::max(); |
| 3752 | |
| 3753 | return static_cast<int32_t>(threshold); |
| 3754 | } |
| 3755 | |
fpizlo@apple.com | e5b6864 | 2013-08-29 20:27:15 +0000 | [diff] [blame] | 3756 | int32_t CodeBlock::adjustedCounterValue(int32_t desiredThreshold) |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3757 | { |
| 3758 | return clipThreshold( |
fpizlo@apple.com | e5b6864 | 2013-08-29 20:27:15 +0000 | [diff] [blame] | 3759 | static_cast<double>(desiredThreshold) * |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3760 | optimizationThresholdScalingFactor() * |
| 3761 | (1 << reoptimizationRetryCounter())); |
| 3762 | } |
| 3763 | |
| 3764 | bool CodeBlock::checkIfOptimizationThresholdReached() |
| 3765 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3766 | #if ENABLE(DFG_JIT) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 3767 | if (DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull()) { |
fpizlo@apple.com | 6931c47 | 2013-08-29 23:45:26 +0000 | [diff] [blame] | 3768 | if (worklist->compilationState(DFG::CompilationKey(this, DFG::DFGMode)) |
| 3769 | == DFG::Worklist::Compiled) { |
| 3770 | optimizeNextInvocation(); |
| 3771 | return true; |
| 3772 | } |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3773 | } |
| 3774 | #endif |
| 3775 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3776 | return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this); |
| 3777 | } |
| 3778 | |
| 3779 | void CodeBlock::optimizeNextInvocation() |
| 3780 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3781 | if (Options::verboseOSR()) |
| 3782 | dataLog(*this, ": Optimizing next invocation.\n"); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3783 | m_jitExecuteCounter.setNewThreshold(0, this); |
| 3784 | } |
| 3785 | |
| 3786 | void CodeBlock::dontOptimizeAnytimeSoon() |
| 3787 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3788 | if (Options::verboseOSR()) |
| 3789 | dataLog(*this, ": Not optimizing anytime soon.\n"); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3790 | m_jitExecuteCounter.deferIndefinitely(); |
| 3791 | } |
| 3792 | |
| 3793 | void CodeBlock::optimizeAfterWarmUp() |
| 3794 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3795 | if (Options::verboseOSR()) |
| 3796 | dataLog(*this, ": Optimizing after warm-up.\n"); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3797 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | e5b6864 | 2013-08-29 20:27:15 +0000 | [diff] [blame] | 3798 | m_jitExecuteCounter.setNewThreshold( |
| 3799 | adjustedCounterValue(Options::thresholdForOptimizeAfterWarmUp()), this); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3800 | #endif |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3801 | } |
| 3802 | |
| 3803 | void CodeBlock::optimizeAfterLongWarmUp() |
| 3804 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3805 | if (Options::verboseOSR()) |
| 3806 | dataLog(*this, ": Optimizing after long warm-up.\n"); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3807 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | e5b6864 | 2013-08-29 20:27:15 +0000 | [diff] [blame] | 3808 | m_jitExecuteCounter.setNewThreshold( |
| 3809 | adjustedCounterValue(Options::thresholdForOptimizeAfterLongWarmUp()), this); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3810 | #endif |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3811 | } |
| 3812 | |
| 3813 | void CodeBlock::optimizeSoon() |
| 3814 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3815 | if (Options::verboseOSR()) |
| 3816 | dataLog(*this, ": Optimizing soon.\n"); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3817 | #if ENABLE(DFG_JIT) |
fpizlo@apple.com | e5b6864 | 2013-08-29 20:27:15 +0000 | [diff] [blame] | 3818 | m_jitExecuteCounter.setNewThreshold( |
| 3819 | adjustedCounterValue(Options::thresholdForOptimizeSoon()), this); |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3820 | #endif |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3821 | } |
| 3822 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3823 | void CodeBlock::forceOptimizationSlowPathConcurrently() |
| 3824 | { |
| 3825 | if (Options::verboseOSR()) |
| 3826 | dataLog(*this, ": Forcing slow path concurrently.\n"); |
| 3827 | m_jitExecuteCounter.forceSlowPathConcurrently(); |
| 3828 | } |
| 3829 | |
oliver@apple.com | 58c8675 | 2013-07-25 04:02:40 +0000 | [diff] [blame] | 3830 | #if ENABLE(DFG_JIT) |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3831 | void CodeBlock::setOptimizationThresholdBasedOnCompilationResult(CompilationResult result) |
| 3832 | { |
fpizlo@apple.com | e7a417d | 2014-05-08 21:51:03 +0000 | [diff] [blame] | 3833 | JITCode::JITType type = jitType(); |
| 3834 | if (type != JITCode::BaselineJIT) { |
| 3835 | dataLog(*this, ": expected to have baseline code but have ", type, "\n"); |
| 3836 | RELEASE_ASSERT_NOT_REACHED(); |
| 3837 | } |
| 3838 | |
| 3839 | CodeBlock* theReplacement = replacement(); |
| 3840 | if ((result == CompilationSuccessful) != (theReplacement != this)) { |
| 3841 | dataLog(*this, ": we have result = ", result, " but "); |
| 3842 | if (theReplacement == this) |
| 3843 | dataLog("we are our own replacement.\n"); |
| 3844 | else |
| 3845 | dataLog("our replacement is ", pointerDump(theReplacement), "\n"); |
| 3846 | RELEASE_ASSERT_NOT_REACHED(); |
| 3847 | } |
| 3848 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3849 | switch (result) { |
| 3850 | case CompilationSuccessful: |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 3851 | RELEASE_ASSERT(JITCode::isOptimizingJIT(replacement()->jitType())); |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3852 | optimizeNextInvocation(); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3853 | return; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3854 | case CompilationFailed: |
| 3855 | dontOptimizeAnytimeSoon(); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3856 | return; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3857 | case CompilationDeferred: |
| 3858 | // We'd like to do dontOptimizeAnytimeSoon() but we cannot because |
| 3859 | // forceOptimizationSlowPathConcurrently() is inherently racy. It won't |
| 3860 | // necessarily guarantee anything. So, we make sure that even if that |
| 3861 | // function ends up being a no-op, we still eventually retry and realize |
| 3862 | // that we have optimized code ready. |
| 3863 | optimizeAfterWarmUp(); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3864 | return; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3865 | case CompilationInvalidated: |
| 3866 | // Retry with exponential backoff. |
| 3867 | countReoptimization(); |
| 3868 | optimizeAfterWarmUp(); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3869 | return; |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3870 | } |
fpizlo@apple.com | e7a417d | 2014-05-08 21:51:03 +0000 | [diff] [blame] | 3871 | |
| 3872 | dataLog("Unrecognized result: ", static_cast<int>(result), "\n"); |
fpizlo@apple.com | 532f1e5 | 2013-09-04 06:26:04 +0000 | [diff] [blame] | 3873 | RELEASE_ASSERT_NOT_REACHED(); |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 3874 | } |
| 3875 | |
oliver@apple.com | 807e7e1 | 2013-07-25 20:22:45 +0000 | [diff] [blame] | 3876 | #endif |
| 3877 | |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3878 | uint32_t CodeBlock::adjustedExitCountThreshold(uint32_t desiredThreshold) |
| 3879 | { |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 3880 | ASSERT(JITCode::isOptimizingJIT(jitType())); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3881 | // Compute this the lame way so we don't saturate. This is called infrequently |
| 3882 | // enough that this loop won't hurt us. |
| 3883 | unsigned result = desiredThreshold; |
| 3884 | for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) { |
| 3885 | unsigned newResult = result << 1; |
| 3886 | if (newResult < result) |
| 3887 | return std::numeric_limits<uint32_t>::max(); |
| 3888 | result = newResult; |
| 3889 | } |
| 3890 | return result; |
| 3891 | } |
| 3892 | |
| 3893 | uint32_t CodeBlock::exitCountThresholdForReoptimization() |
| 3894 | { |
fpizlo@apple.com | d29f963 | 2012-12-18 22:49:40 +0000 | [diff] [blame] | 3895 | return adjustedExitCountThreshold(Options::osrExitCountForReoptimization() * codeTypeThresholdMultiplier()); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3896 | } |
| 3897 | |
| 3898 | uint32_t CodeBlock::exitCountThresholdForReoptimizationFromLoop() |
| 3899 | { |
fpizlo@apple.com | d29f963 | 2012-12-18 22:49:40 +0000 | [diff] [blame] | 3900 | return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop() * codeTypeThresholdMultiplier()); |
fpizlo@apple.com | 7f7ba49 | 2012-12-09 20:41:09 +0000 | [diff] [blame] | 3901 | } |
| 3902 | |
| 3903 | bool CodeBlock::shouldReoptimizeNow() |
| 3904 | { |
| 3905 | return osrExitCounter() >= exitCountThresholdForReoptimization(); |
| 3906 | } |
| 3907 | |
| 3908 | bool CodeBlock::shouldReoptimizeFromLoopNow() |
| 3909 | { |
| 3910 | return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop(); |
| 3911 | } |
| 3912 | #endif |
| 3913 | |
fpizlo@apple.com | f24804c | 2012-08-15 02:48:35 +0000 | [diff] [blame] | 3914 | ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset) |
| 3915 | { |
| 3916 | for (unsigned i = 0; i < m_arrayProfiles.size(); ++i) { |
| 3917 | if (m_arrayProfiles[i].bytecodeOffset() == bytecodeOffset) |
| 3918 | return &m_arrayProfiles[i]; |
| 3919 | } |
| 3920 | return 0; |
| 3921 | } |
| 3922 | |
| 3923 | ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset) |
| 3924 | { |
| 3925 | ArrayProfile* result = getArrayProfile(bytecodeOffset); |
| 3926 | if (result) |
| 3927 | return result; |
| 3928 | return addArrayProfile(bytecodeOffset); |
| 3929 | } |
| 3930 | |
fpizlo@apple.com | 8e470a2 | 2015-09-21 20:10:04 +0000 | [diff] [blame] | 3931 | #if ENABLE(DFG_JIT) |
| 3932 | Vector<CodeOrigin, 0, UnsafeVectorOverflow>& CodeBlock::codeOrigins() |
| 3933 | { |
| 3934 | return m_jitCode->dfgCommon()->codeOrigins; |
| 3935 | } |
| 3936 | |
| 3937 | size_t CodeBlock::numberOfDFGIdentifiers() const |
| 3938 | { |
| 3939 | if (!JITCode::isOptimizingJIT(jitType())) |
| 3940 | return 0; |
| 3941 | |
| 3942 | return m_jitCode->dfgCommon()->dfgIdentifiers.size(); |
| 3943 | } |
| 3944 | |
| 3945 | const Identifier& CodeBlock::identifier(int index) const |
| 3946 | { |
| 3947 | size_t unlinkedIdentifiers = m_unlinkedCode->numberOfIdentifiers(); |
| 3948 | if (static_cast<unsigned>(index) < unlinkedIdentifiers) |
| 3949 | return m_unlinkedCode->identifier(index); |
| 3950 | ASSERT(JITCode::isOptimizingJIT(jitType())); |
| 3951 | return m_jitCode->dfgCommon()->dfgIdentifiers[index - unlinkedIdentifiers]; |
| 3952 | } |
| 3953 | #endif // ENABLE(DFG_JIT) |
| 3954 | |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3955 | void CodeBlock::updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles) |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3956 | { |
oliver@apple.com | d205666 | 2013-07-25 04:00:37 +0000 | [diff] [blame] | 3957 | ConcurrentJITLocker locker(m_lock); |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 3958 | |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3959 | numberOfLiveNonArgumentValueProfiles = 0; |
| 3960 | numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. |
| 3961 | for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { |
| 3962 | ValueProfile* profile = getFromAllValueProfiles(i); |
| 3963 | unsigned numSamples = profile->totalNumberOfSamples(); |
| 3964 | if (numSamples > ValueProfile::numberOfBuckets) |
| 3965 | numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight. |
| 3966 | numberOfSamplesInProfiles += numSamples; |
| 3967 | if (profile->m_bytecodeOffset < 0) { |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3968 | profile->computeUpdatedPrediction(locker); |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3969 | continue; |
| 3970 | } |
| 3971 | if (profile->numberOfSamples() || profile->m_prediction != SpecNone) |
| 3972 | numberOfLiveNonArgumentValueProfiles++; |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3973 | profile->computeUpdatedPrediction(locker); |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3974 | } |
| 3975 | |
| 3976 | #if ENABLE(DFG_JIT) |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3977 | m_lazyOperandValueProfiles.computeUpdatedPredictions(locker); |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3978 | #endif |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 3979 | } |
| 3980 | |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3981 | void CodeBlock::updateAllValueProfilePredictions() |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 3982 | { |
| 3983 | unsigned ignoredValue1, ignoredValue2; |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3984 | updateAllPredictionsAndCountLiveness(ignoredValue1, ignoredValue2); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 3985 | } |
| 3986 | |
oliver@apple.com | 58cdc33 | 2013-07-25 04:04:59 +0000 | [diff] [blame] | 3987 | void CodeBlock::updateAllArrayPredictions() |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 3988 | { |
oliver@apple.com | d205666 | 2013-07-25 04:00:37 +0000 | [diff] [blame] | 3989 | ConcurrentJITLocker locker(m_lock); |
oliver@apple.com | c14eb7d | 2013-07-25 03:58:47 +0000 | [diff] [blame] | 3990 | |
fpizlo@apple.com | f24804c | 2012-08-15 02:48:35 +0000 | [diff] [blame] | 3991 | for (unsigned i = m_arrayProfiles.size(); i--;) |
oliver@apple.com | 58cdc33 | 2013-07-25 04:04:59 +0000 | [diff] [blame] | 3992 | m_arrayProfiles[i].computeUpdatedPrediction(locker, this); |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 3993 | |
| 3994 | // Don't count these either, for similar reasons. |
| 3995 | for (unsigned i = m_arrayAllocationProfiles.size(); i--;) |
| 3996 | m_arrayAllocationProfiles[i].updateIndexingType(); |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 3997 | } |
| 3998 | |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 3999 | void CodeBlock::updateAllPredictions() |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 4000 | { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 4001 | #if ENABLE(WEBASSEMBLY) |
| 4002 | if (m_ownerExecutable->isWebAssemblyExecutable()) |
| 4003 | return; |
| 4004 | #endif |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 4005 | updateAllValueProfilePredictions(); |
oliver@apple.com | 58cdc33 | 2013-07-25 04:04:59 +0000 | [diff] [blame] | 4006 | updateAllArrayPredictions(); |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 4007 | } |
| 4008 | |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4009 | bool CodeBlock::shouldOptimizeNow() |
| 4010 | { |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 4011 | if (Options::verboseOSR()) |
| 4012 | dataLog("Considering optimizing ", *this, "...\n"); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4013 | |
commit-queue@webkit.org | fbda60c | 2012-07-03 19:19:22 +0000 | [diff] [blame] | 4014 | if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay()) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4015 | return true; |
| 4016 | |
fpizlo@apple.com | 75c91a7 | 2012-11-08 22:28:25 +0000 | [diff] [blame] | 4017 | updateAllArrayPredictions(); |
| 4018 | |
fpizlo@apple.com | 3745dbc | 2012-06-26 02:14:07 +0000 | [diff] [blame] | 4019 | unsigned numberOfLiveNonArgumentValueProfiles; |
| 4020 | unsigned numberOfSamplesInProfiles; |
mhahnenberg@apple.com | c568471 | 2013-09-26 17:16:47 +0000 | [diff] [blame] | 4021 | updateAllPredictionsAndCountLiveness(numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4022 | |
oliver@apple.com | 284cc3d | 2013-07-25 04:00:33 +0000 | [diff] [blame] | 4023 | if (Options::verboseOSR()) { |
| 4024 | dataLogF( |
| 4025 | "Profile hotness: %lf (%u / %u), %lf (%u / %u)\n", |
| 4026 | (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), |
| 4027 | numberOfLiveNonArgumentValueProfiles, numberOfValueProfiles(), |
| 4028 | (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles(), |
| 4029 | numberOfSamplesInProfiles, ValueProfile::numberOfBuckets * numberOfValueProfiles()); |
| 4030 | } |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4031 | |
commit-queue@webkit.org | fbda60c | 2012-07-03 19:19:22 +0000 | [diff] [blame] | 4032 | if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate()) |
| 4033 | && (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate()) |
| 4034 | && static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay()) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4035 | return true; |
| 4036 | |
fpizlo@apple.com | 4043e81 | 2011-11-06 11:54:59 +0000 | [diff] [blame] | 4037 | ASSERT(m_optimizationDelayCounter < std::numeric_limits<uint8_t>::max()); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4038 | m_optimizationDelayCounter++; |
| 4039 | optimizeAfterWarmUp(); |
| 4040 | return false; |
| 4041 | } |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4042 | |
fpizlo@apple.com | 4ef9c87 | 2011-12-13 19:49:49 +0000 | [diff] [blame] | 4043 | #if ENABLE(DFG_JIT) |
| 4044 | void CodeBlock::tallyFrequentExitSites() |
| 4045 | { |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 4046 | ASSERT(JITCode::isOptimizingJIT(jitType())); |
| 4047 | ASSERT(alternative()->jitType() == JITCode::BaselineJIT); |
fpizlo@apple.com | 4ef9c87 | 2011-12-13 19:49:49 +0000 | [diff] [blame] | 4048 | |
| 4049 | CodeBlock* profiledBlock = alternative(); |
| 4050 | |
oliver@apple.com | 5a24fdd | 2013-07-25 04:00:54 +0000 | [diff] [blame] | 4051 | switch (jitType()) { |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4052 | case JITCode::DFGJIT: { |
| 4053 | DFG::JITCode* jitCode = m_jitCode->dfg(); |
| 4054 | for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) { |
| 4055 | DFG::OSRExit& exit = jitCode->osrExit[i]; |
benjamin@webkit.org | 6f63a8b | 2015-02-18 07:04:10 +0000 | [diff] [blame] | 4056 | exit.considerAddingAsFrequentExitSite(profiledBlock); |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4057 | } |
| 4058 | break; |
| 4059 | } |
oliver@apple.com | 0c1b13e | 2013-07-25 03:58:43 +0000 | [diff] [blame] | 4060 | |
| 4061 | #if ENABLE(FTL_JIT) |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4062 | case JITCode::FTLJIT: { |
| 4063 | // There is no easy way to avoid duplicating this code since the FTL::JITCode::osrExit |
| 4064 | // vector contains a totally different type, that just so happens to behave like |
| 4065 | // DFG::JITCode::osrExit. |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4066 | FTL::JITCode* jitCode = m_jitCode->ftl(); |
| 4067 | for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) { |
| 4068 | FTL::OSRExit& exit = jitCode->osrExit[i]; |
benjamin@webkit.org | 6f63a8b | 2015-02-18 07:04:10 +0000 | [diff] [blame] | 4069 | exit.considerAddingAsFrequentExitSite(profiledBlock); |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4070 | } |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4071 | break; |
oliver@apple.com | 0c1b13e | 2013-07-25 03:58:43 +0000 | [diff] [blame] | 4072 | } |
| 4073 | #endif |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 4074 | |
| 4075 | default: |
| 4076 | RELEASE_ASSERT_NOT_REACHED(); |
| 4077 | break; |
fpizlo@apple.com | 4ef9c87 | 2011-12-13 19:49:49 +0000 | [diff] [blame] | 4078 | } |
| 4079 | } |
| 4080 | #endif // ENABLE(DFG_JIT) |
| 4081 | |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4082 | #if ENABLE(VERBOSE_VALUE_PROFILE) |
| 4083 | void CodeBlock::dumpValueProfiles() |
| 4084 | { |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 4085 | dataLog("ValueProfile for ", *this, ":\n"); |
fpizlo@apple.com | 086d2af | 2011-12-21 02:29:15 +0000 | [diff] [blame] | 4086 | for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { |
| 4087 | ValueProfile* profile = getFromAllValueProfiles(i); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4088 | if (profile->m_bytecodeOffset < 0) { |
| 4089 | ASSERT(profile->m_bytecodeOffset == -1); |
fpizlo@apple.com | 01902c8 | 2012-11-22 04:23:36 +0000 | [diff] [blame] | 4090 | dataLogF(" arg = %u: ", i); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4091 | } else |
fpizlo@apple.com | 01902c8 | 2012-11-22 04:23:36 +0000 | [diff] [blame] | 4092 | dataLogF(" bc = %d: ", profile->m_bytecodeOffset); |
fpizlo@apple.com | 6233616 | 2012-06-07 01:35:59 +0000 | [diff] [blame] | 4093 | if (!profile->numberOfSamples() && profile->m_prediction == SpecNone) { |
fpizlo@apple.com | 01902c8 | 2012-11-22 04:23:36 +0000 | [diff] [blame] | 4094 | dataLogF("<empty>\n"); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4095 | continue; |
| 4096 | } |
fpizlo@apple.com | d095b24 | 2012-02-12 03:21:32 +0000 | [diff] [blame] | 4097 | profile->dump(WTF::dataFile()); |
fpizlo@apple.com | 01902c8 | 2012-11-22 04:23:36 +0000 | [diff] [blame] | 4098 | dataLogF("\n"); |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4099 | } |
fpizlo@apple.com | 0bfcc38 | 2012-11-30 03:42:29 +0000 | [diff] [blame] | 4100 | dataLog("RareCaseProfile for ", *this, ":\n"); |
barraclough@apple.com | e32d4ec | 2011-09-21 22:43:11 +0000 | [diff] [blame] | 4101 | for (unsigned i = 0; i < numberOfRareCaseProfiles(); ++i) { |
| 4102 | RareCaseProfile* profile = rareCaseProfile(i); |
fpizlo@apple.com | 01902c8 | 2012-11-22 04:23:36 +0000 | [diff] [blame] | 4103 | dataLogF(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); |
fpizlo@apple.com | 9b0b31e | 2011-09-19 22:27:38 +0000 | [diff] [blame] | 4104 | } |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 4105 | dataLog("ResultProfile for ", *this, ":\n"); |
| 4106 | for (unsigned i = 0; i < numberOfResultProfiles(); ++i) { |
| 4107 | const ResultProfile& profile = *resultProfile(i); |
| 4108 | dataLog(" bc = ", profile.bytecodeOffset(), ": ", profile, "\n"); |
fpizlo@apple.com | 706f5f3 | 2011-09-21 23:36:35 +0000 | [diff] [blame] | 4109 | } |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4110 | } |
fpizlo@apple.com | 8618e4b | 2012-07-03 01:27:16 +0000 | [diff] [blame] | 4111 | #endif // ENABLE(VERBOSE_VALUE_PROFILE) |
fpizlo@apple.com | 7f2d234 | 2011-09-14 23:00:26 +0000 | [diff] [blame] | 4112 | |
fpizlo@apple.com | 81bb8bb | 2013-11-23 00:36:55 +0000 | [diff] [blame] | 4113 | unsigned CodeBlock::frameRegisterCount() |
| 4114 | { |
| 4115 | switch (jitType()) { |
fpizlo@apple.com | 81bb8bb | 2013-11-23 00:36:55 +0000 | [diff] [blame] | 4116 | case JITCode::InterpreterThunk: |
| 4117 | return LLInt::frameRegisterCountFor(this); |
fpizlo@apple.com | 81bb8bb | 2013-11-23 00:36:55 +0000 | [diff] [blame] | 4118 | |
| 4119 | #if ENABLE(JIT) |
| 4120 | case JITCode::BaselineJIT: |
| 4121 | return JIT::frameRegisterCountFor(this); |
| 4122 | #endif // ENABLE(JIT) |
| 4123 | |
| 4124 | #if ENABLE(DFG_JIT) |
| 4125 | case JITCode::DFGJIT: |
| 4126 | case JITCode::FTLJIT: |
| 4127 | return jitCode()->dfgCommon()->frameRegisterCount; |
| 4128 | #endif // ENABLE(DFG_JIT) |
| 4129 | |
| 4130 | default: |
| 4131 | RELEASE_ASSERT_NOT_REACHED(); |
| 4132 | return 0; |
| 4133 | } |
| 4134 | } |
| 4135 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 4136 | int CodeBlock::stackPointerOffset() |
| 4137 | { |
| 4138 | return virtualRegisterForLocal(frameRegisterCount() - 1).offset(); |
| 4139 | } |
| 4140 | |
fpizlo@apple.com | 254d43b | 2012-03-05 06:52:44 +0000 | [diff] [blame] | 4141 | size_t CodeBlock::predictedMachineCodeSize() |
| 4142 | { |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 4143 | // This will be called from CodeBlock::CodeBlock before either m_vm or the |
fpizlo@apple.com | 254d43b | 2012-03-05 06:52:44 +0000 | [diff] [blame] | 4144 | // instructions have been initialized. It's OK to return 0 because what will really |
| 4145 | // matter is the recomputation of this value when the slow path is triggered. |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 4146 | if (!m_vm) |
fpizlo@apple.com | 254d43b | 2012-03-05 06:52:44 +0000 | [diff] [blame] | 4147 | return 0; |
| 4148 | |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 4149 | if (!m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT) |
fpizlo@apple.com | 254d43b | 2012-03-05 06:52:44 +0000 | [diff] [blame] | 4150 | return 0; // It's as good of a prediction as we'll get. |
| 4151 | |
| 4152 | // Be conservative: return a size that will be an overestimation 84% of the time. |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 4153 | double multiplier = m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.mean() + |
| 4154 | m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.standardDeviation(); |
fpizlo@apple.com | 254d43b | 2012-03-05 06:52:44 +0000 | [diff] [blame] | 4155 | |
| 4156 | // Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing |
| 4157 | // here is OK, since this whole method is just a heuristic. |
| 4158 | if (multiplier < 0 || multiplier > 1000) |
| 4159 | return 0; |
| 4160 | |
| 4161 | double doubleResult = multiplier * m_instructions.size(); |
| 4162 | |
| 4163 | // Be even more paranoid: silently reject values that won't fit into a size_t. If |
| 4164 | // the function is so huge that we can't even fit it into virtual memory then we |
| 4165 | // should probably have some other guards in place to prevent us from even getting |
| 4166 | // to this point. |
| 4167 | if (doubleResult > std::numeric_limits<size_t>::max()) |
| 4168 | return 0; |
| 4169 | |
| 4170 | return static_cast<size_t>(doubleResult); |
| 4171 | } |
| 4172 | |
fpizlo@apple.com | c828f14 | 2011-10-25 21:56:31 +0000 | [diff] [blame] | 4173 | bool CodeBlock::usesOpcode(OpcodeID opcodeID) |
| 4174 | { |
ggaren@apple.com | 9a9a4b5 | 2013-04-18 19:32:17 +0000 | [diff] [blame] | 4175 | Interpreter* interpreter = vm()->interpreter; |
fpizlo@apple.com | c828f14 | 2011-10-25 21:56:31 +0000 | [diff] [blame] | 4176 | Instruction* instructionsBegin = instructions().begin(); |
| 4177 | unsigned instructionCount = instructions().size(); |
| 4178 | |
| 4179 | for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) { |
| 4180 | switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) { |
| 4181 | #define DEFINE_OP(curOpcode, length) \ |
| 4182 | case curOpcode: \ |
| 4183 | if (curOpcode == opcodeID) \ |
| 4184 | return true; \ |
| 4185 | bytecodeOffset += length; \ |
| 4186 | break; |
| 4187 | FOR_EACH_OPCODE_ID(DEFINE_OP) |
| 4188 | #undef DEFINE_OP |
| 4189 | default: |
oliver@apple.com | 5598c18 | 2013-01-23 22:25:07 +0000 | [diff] [blame] | 4190 | RELEASE_ASSERT_NOT_REACHED(); |
fpizlo@apple.com | c828f14 | 2011-10-25 21:56:31 +0000 | [diff] [blame] | 4191 | break; |
| 4192 | } |
| 4193 | } |
| 4194 | |
| 4195 | return false; |
| 4196 | } |
fpizlo@apple.com | c828f14 | 2011-10-25 21:56:31 +0000 | [diff] [blame] | 4197 | |
msaboff@apple.com | 62aa8b7 | 2013-09-26 22:53:54 +0000 | [diff] [blame] | 4198 | String CodeBlock::nameForRegister(VirtualRegister virtualRegister) |
oliver@apple.com | a08210b | 2012-07-18 23:26:06 +0000 | [diff] [blame] | 4199 | { |
saambarati1@gmail.com | 3321f09 | 2015-07-20 21:16:41 +0000 | [diff] [blame] | 4200 | for (unsigned i = 0; i < m_constantRegisters.size(); i++) { |
| 4201 | if (m_constantRegisters[i].get().isEmpty()) |
| 4202 | continue; |
| 4203 | if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(m_constantRegisters[i].get())) { |
| 4204 | ConcurrentJITLocker locker(symbolTable->m_lock); |
| 4205 | auto end = symbolTable->end(locker); |
| 4206 | for (auto ptr = symbolTable->begin(locker); ptr != end; ++ptr) { |
| 4207 | if (ptr->value.varOffset() == VarOffset(virtualRegister)) { |
| 4208 | // FIXME: This won't work from the compilation thread. |
| 4209 | // https://bugs.webkit.org/show_bug.cgi?id=115300 |
| 4210 | return ptr->key.get(); |
| 4211 | } |
| 4212 | } |
oliver@apple.com | f72e22e | 2013-07-25 03:59:04 +0000 | [diff] [blame] | 4213 | } |
oliver@apple.com | a08210b | 2012-07-18 23:26:06 +0000 | [diff] [blame] | 4214 | } |
msaboff@apple.com | 62aa8b7 | 2013-09-26 22:53:54 +0000 | [diff] [blame] | 4215 | if (virtualRegister == thisRegister()) |
benjamin@webkit.org | 762e2c6 | 2012-09-04 21:19:25 +0000 | [diff] [blame] | 4216 | return ASCIILiteral("this"); |
msaboff@apple.com | 62aa8b7 | 2013-09-26 22:53:54 +0000 | [diff] [blame] | 4217 | if (virtualRegister.isArgument()) |
commit-queue@webkit.org | 29e710c | 2014-08-29 21:33:30 +0000 | [diff] [blame] | 4218 | return String::format("arguments[%3d]", virtualRegister.toArgument()); |
msaboff@apple.com | 62aa8b7 | 2013-09-26 22:53:54 +0000 | [diff] [blame] | 4219 | |
oliver@apple.com | a08210b | 2012-07-18 23:26:06 +0000 | [diff] [blame] | 4220 | return ""; |
| 4221 | } |
| 4222 | |
fpizlo@apple.com | 3a2fa4c | 2015-04-13 22:13:12 +0000 | [diff] [blame] | 4223 | ValueProfile* CodeBlock::valueProfileForBytecodeOffset(int bytecodeOffset) |
| 4224 | { |
| 4225 | ValueProfile* result = binarySearch<ValueProfile, int>( |
| 4226 | m_valueProfiles, m_valueProfiles.size(), bytecodeOffset, |
| 4227 | getValueProfileBytecodeOffset<ValueProfile>); |
| 4228 | ASSERT(result->m_bytecodeOffset != -1); |
| 4229 | ASSERT(instructions()[bytecodeOffset + opcodeLength( |
| 4230 | m_vm->interpreter->getOpcodeID( |
| 4231 | instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result); |
| 4232 | return result; |
| 4233 | } |
| 4234 | |
fpizlo@apple.com | 2eb67ec | 2013-11-27 23:15:48 +0000 | [diff] [blame] | 4235 | void CodeBlock::validate() |
| 4236 | { |
| 4237 | BytecodeLivenessAnalysis liveness(this); // Compute directly from scratch so it doesn't effect CodeBlock footprint. |
| 4238 | |
| 4239 | FastBitVector liveAtHead = liveness.getLivenessInfoAtBytecodeOffset(0); |
| 4240 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 4241 | if (liveAtHead.numBits() != static_cast<size_t>(m_numCalleeLocals)) { |
fpizlo@apple.com | 2eb67ec | 2013-11-27 23:15:48 +0000 | [diff] [blame] | 4242 | beginValidationDidFail(); |
| 4243 | dataLog(" Wrong number of bits in result!\n"); |
| 4244 | dataLog(" Result: ", liveAtHead, "\n"); |
| 4245 | dataLog(" Bit count: ", liveAtHead.numBits(), "\n"); |
| 4246 | endValidationDidFail(); |
| 4247 | } |
| 4248 | |
utatane.tea@gmail.com | fdd9bf4 | 2015-12-02 03:16:28 +0000 | [diff] [blame] | 4249 | for (unsigned i = m_numCalleeLocals; i--;) { |
fpizlo@apple.com | 2eb67ec | 2013-11-27 23:15:48 +0000 | [diff] [blame] | 4250 | VirtualRegister reg = virtualRegisterForLocal(i); |
| 4251 | |
fpizlo@apple.com | da834ae | 2015-03-26 04:28:43 +0000 | [diff] [blame] | 4252 | if (liveAtHead.get(i)) { |
| 4253 | beginValidationDidFail(); |
| 4254 | dataLog(" Variable ", reg, " is expected to be dead.\n"); |
| 4255 | dataLog(" Result: ", liveAtHead, "\n"); |
| 4256 | endValidationDidFail(); |
fpizlo@apple.com | 2eb67ec | 2013-11-27 23:15:48 +0000 | [diff] [blame] | 4257 | } |
| 4258 | } |
| 4259 | } |
| 4260 | |
| 4261 | void CodeBlock::beginValidationDidFail() |
| 4262 | { |
| 4263 | dataLog("Validation failure in ", *this, ":\n"); |
| 4264 | dataLog("\n"); |
| 4265 | } |
| 4266 | |
| 4267 | void CodeBlock::endValidationDidFail() |
| 4268 | { |
| 4269 | dataLog("\n"); |
| 4270 | dumpBytecode(); |
| 4271 | dataLog("\n"); |
| 4272 | dataLog("Validation failure.\n"); |
| 4273 | RELEASE_ASSERT_NOT_REACHED(); |
| 4274 | } |
| 4275 | |
mark.lam@apple.com | 6c4085b | 2014-01-28 17:43:07 +0000 | [diff] [blame] | 4276 | void CodeBlock::addBreakpoint(unsigned numBreakpoints) |
| 4277 | { |
| 4278 | m_numBreakpoints += numBreakpoints; |
| 4279 | ASSERT(m_numBreakpoints); |
mark.lam@apple.com | 51ccaab | 2014-02-01 20:29:23 +0000 | [diff] [blame] | 4280 | if (JITCode::isOptimizingJIT(jitType())) |
fpizlo@apple.com | 0dda6d7 | 2014-02-02 02:25:13 +0000 | [diff] [blame] | 4281 | jettison(Profiler::JettisonDueToDebuggerBreakpoint); |
mark.lam@apple.com | 6c4085b | 2014-01-28 17:43:07 +0000 | [diff] [blame] | 4282 | } |
| 4283 | |
| 4284 | void CodeBlock::setSteppingMode(CodeBlock::SteppingMode mode) |
| 4285 | { |
| 4286 | m_steppingMode = mode; |
mark.lam@apple.com | 51ccaab | 2014-02-01 20:29:23 +0000 | [diff] [blame] | 4287 | if (mode == SteppingModeEnabled && JITCode::isOptimizingJIT(jitType())) |
fpizlo@apple.com | 0dda6d7 | 2014-02-02 02:25:13 +0000 | [diff] [blame] | 4288 | jettison(Profiler::JettisonDueToDebuggerStepping); |
mark.lam@apple.com | 6c4085b | 2014-01-28 17:43:07 +0000 | [diff] [blame] | 4289 | } |
| 4290 | |
mhahnenberg@apple.com | 1f26507 | 2014-05-02 18:52:10 +0000 | [diff] [blame] | 4291 | RareCaseProfile* CodeBlock::rareCaseProfileForBytecodeOffset(int bytecodeOffset) |
| 4292 | { |
| 4293 | return tryBinarySearch<RareCaseProfile, int>( |
| 4294 | m_rareCaseProfiles, m_rareCaseProfiles.size(), bytecodeOffset, |
| 4295 | getRareCaseProfileBytecodeOffset); |
| 4296 | } |
| 4297 | |
mark.lam@apple.com | ff2c14a | 2015-09-24 18:38:35 +0000 | [diff] [blame] | 4298 | unsigned CodeBlock::rareCaseProfileCountForBytecodeOffset(int bytecodeOffset) |
| 4299 | { |
| 4300 | RareCaseProfile* profile = rareCaseProfileForBytecodeOffset(bytecodeOffset); |
| 4301 | if (profile) |
| 4302 | return profile->m_counter; |
| 4303 | return 0; |
| 4304 | } |
| 4305 | |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 4306 | ResultProfile* CodeBlock::resultProfileForBytecodeOffset(int bytecodeOffset) |
| 4307 | { |
sbarati@apple.com | 900f891 | 2016-04-12 18:38:16 +0000 | [diff] [blame] | 4308 | ConcurrentJITLocker locker(m_lock); |
| 4309 | return resultProfileForBytecodeOffset(locker, bytecodeOffset); |
| 4310 | } |
| 4311 | |
| 4312 | ResultProfile* CodeBlock::resultProfileForBytecodeOffset(const ConcurrentJITLocker&, int bytecodeOffset) |
| 4313 | { |
akling@apple.com | ce2ec58 | 2016-01-29 20:37:52 +0000 | [diff] [blame] | 4314 | if (!m_bytecodeOffsetToResultProfileIndexMap) |
| 4315 | return nullptr; |
| 4316 | auto iterator = m_bytecodeOffsetToResultProfileIndexMap->find(bytecodeOffset); |
| 4317 | if (iterator == m_bytecodeOffsetToResultProfileIndexMap->end()) |
mark.lam@apple.com | c1a7241 | 2016-01-05 23:08:58 +0000 | [diff] [blame] | 4318 | return nullptr; |
| 4319 | return &m_resultProfiles[iterator->value]; |
mark.lam@apple.com | bad59ea | 2015-12-18 22:03:30 +0000 | [diff] [blame] | 4320 | } |
| 4321 | |
sbarati@apple.com | 900f891 | 2016-04-12 18:38:16 +0000 | [diff] [blame] | 4322 | |
| 4323 | ResultProfile* CodeBlock::ensureResultProfile(int bytecodeOffset) |
| 4324 | { |
| 4325 | ConcurrentJITLocker locker(m_lock); |
| 4326 | return ensureResultProfile(locker, bytecodeOffset); |
| 4327 | } |
| 4328 | |
| 4329 | ResultProfile* CodeBlock::ensureResultProfile(const ConcurrentJITLocker& locker, int bytecodeOffset) |
| 4330 | { |
sbarati@apple.com | 900f891 | 2016-04-12 18:38:16 +0000 | [diff] [blame] | 4331 | ResultProfile* profile = resultProfileForBytecodeOffset(locker, bytecodeOffset); |
| 4332 | if (!profile) { |
| 4333 | m_resultProfiles.append(ResultProfile(bytecodeOffset)); |
| 4334 | profile = &m_resultProfiles.last(); |
| 4335 | ASSERT(&m_resultProfiles.last() == &m_resultProfiles[m_resultProfiles.size() - 1]); |
| 4336 | if (!m_bytecodeOffsetToResultProfileIndexMap) |
| 4337 | m_bytecodeOffsetToResultProfileIndexMap = std::make_unique<BytecodeOffsetToResultProfileIndexMap>(); |
| 4338 | m_bytecodeOffsetToResultProfileIndexMap->add(bytecodeOffset, m_resultProfiles.size() - 1); |
| 4339 | } |
| 4340 | return profile; |
| 4341 | } |
| 4342 | |
mhahnenberg@apple.com | 0ef30c4 | 2014-05-02 21:21:04 +0000 | [diff] [blame] | 4343 | #if ENABLE(JIT) |
mhahnenberg@apple.com | 1f26507 | 2014-05-02 18:52:10 +0000 | [diff] [blame] | 4344 | DFG::CapabilityLevel CodeBlock::capabilityLevel() |
| 4345 | { |
ggaren@apple.com | 81def5f | 2015-10-09 23:10:16 +0000 | [diff] [blame] | 4346 | DFG::CapabilityLevel result = computeCapabilityLevel(); |
mhahnenberg@apple.com | 1f26507 | 2014-05-02 18:52:10 +0000 | [diff] [blame] | 4347 | m_capabilityLevelState = result; |
| 4348 | return result; |
| 4349 | } |
mhahnenberg@apple.com | 0ef30c4 | 2014-05-02 21:21:04 +0000 | [diff] [blame] | 4350 | #endif |
mhahnenberg@apple.com | 1f26507 | 2014-05-02 18:52:10 +0000 | [diff] [blame] | 4351 | |
akling@apple.com | f10f7a1 | 2015-10-10 21:14:56 +0000 | [diff] [blame] | 4352 | void CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler(RefCountedArray<Instruction>& instructions) |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 4353 | { |
akling@apple.com | 7dc7b8b | 2016-03-07 18:24:26 +0000 | [diff] [blame] | 4354 | if (!unlinkedCodeBlock()->hasOpProfileControlFlowBytecodeOffsets()) |
| 4355 | return; |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 4356 | const Vector<size_t>& bytecodeOffsets = unlinkedCodeBlock()->opProfileControlFlowBytecodeOffsets(); |
| 4357 | for (size_t i = 0, offsetsLength = bytecodeOffsets.size(); i < offsetsLength; i++) { |
| 4358 | // Because op_profile_control_flow is emitted at the beginning of every basic block, finding |
| 4359 | // the next op_profile_control_flow will give us the text range of a single basic block. |
| 4360 | size_t startIdx = bytecodeOffsets[i]; |
| 4361 | RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[startIdx].u.opcode) == op_profile_control_flow); |
| 4362 | int basicBlockStartOffset = instructions[startIdx + 1].u.operand; |
| 4363 | int basicBlockEndOffset; |
| 4364 | if (i + 1 < offsetsLength) { |
| 4365 | size_t endIdx = bytecodeOffsets[i + 1]; |
| 4366 | RELEASE_ASSERT(vm()->interpreter->getOpcodeID(instructions[endIdx].u.opcode) == op_profile_control_flow); |
saambarati1@gmail.com | 1595250 | 2015-02-23 22:10:51 +0000 | [diff] [blame] | 4367 | basicBlockEndOffset = instructions[endIdx + 1].u.operand - 1; |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 4368 | } else { |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 4369 | basicBlockEndOffset = m_sourceOffset + ownerScriptExecutable()->source().length() - 1; // Offset before the closing brace. |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 4370 | basicBlockStartOffset = std::min(basicBlockStartOffset, basicBlockEndOffset); // Some start offsets may be at the closing brace, ensure it is the offset before. |
| 4371 | } |
| 4372 | |
| 4373 | // The following check allows for the same textual JavaScript basic block to have its bytecode emitted more |
| 4374 | // than once and still play nice with the control flow profiler. When basicBlockStartOffset is larger than |
| 4375 | // basicBlockEndOffset, it indicates that the bytecode generator has emitted code for the same AST node |
| 4376 | // more than once (for example: ForInNode, Finally blocks in TryNode, etc). Though these are different |
| 4377 | // basic blocks at the bytecode level, they are generated from the same textual basic block in the JavaScript |
| 4378 | // program. The condition: |
| 4379 | // (basicBlockEndOffset < basicBlockStartOffset) |
| 4380 | // is encountered when op_profile_control_flow lies across the boundary of these duplicated bytecode basic |
| 4381 | // blocks and the textual offset goes from the end of the duplicated block back to the beginning. These |
| 4382 | // ranges are dummy ranges and are ignored. The duplicated bytecode basic blocks point to the same |
| 4383 | // internal data structure, so if any of them execute, it will record the same textual basic block in the |
| 4384 | // JavaScript program as executing. |
| 4385 | // At the bytecode level, this situation looks like: |
| 4386 | // j: op_profile_control_flow (from j->k, we have basicBlockEndOffset < basicBlockStartOffset) |
| 4387 | // ... |
| 4388 | // k: op_profile_control_flow (we want to skip over the j->k block and start fresh at offset k as the start of a new basic block k->m). |
| 4389 | // ... |
| 4390 | // m: op_profile_control_flow |
| 4391 | if (basicBlockEndOffset < basicBlockStartOffset) { |
| 4392 | RELEASE_ASSERT(i + 1 < offsetsLength); // We should never encounter dummy blocks at the end of a CodeBlock. |
| 4393 | instructions[startIdx + 1].u.basicBlockLocation = vm()->controlFlowProfiler()->dummyBasicBlock(); |
| 4394 | continue; |
| 4395 | } |
| 4396 | |
commit-queue@webkit.org | fa19663 | 2015-08-28 21:07:22 +0000 | [diff] [blame] | 4397 | BasicBlockLocation* basicBlockLocation = vm()->controlFlowProfiler()->getBasicBlockLocation(ownerScriptExecutable()->sourceID(), basicBlockStartOffset, basicBlockEndOffset); |
saambarati1@gmail.com | d60d941 | 2015-01-20 04:47:55 +0000 | [diff] [blame] | 4398 | |
| 4399 | // Find all functions that are enclosed within the range: [basicBlockStartOffset, basicBlockEndOffset] |
| 4400 | // and insert these functions' start/end offsets as gaps in the current BasicBlockLocation. |
| 4401 | // This is necessary because in the original source text of a JavaScript program, |
| 4402 | // function literals form new basic blocks boundaries, but they aren't represented |
| 4403 | // inside the CodeBlock's instruction stream. |
| 4404 | auto insertFunctionGaps = [basicBlockLocation, basicBlockStartOffset, basicBlockEndOffset] (const WriteBarrier<FunctionExecutable>& functionExecutable) { |
| 4405 | const UnlinkedFunctionExecutable* executable = functionExecutable->unlinkedExecutable(); |
| 4406 | int functionStart = executable->typeProfilingStartOffset(); |
| 4407 | int functionEnd = executable->typeProfilingEndOffset(); |
| 4408 | if (functionStart >= basicBlockStartOffset && functionEnd <= basicBlockEndOffset) |
| 4409 | basicBlockLocation->insertGap(functionStart, functionEnd); |
| 4410 | }; |
| 4411 | |
| 4412 | for (const WriteBarrier<FunctionExecutable>& executable : m_functionDecls) |
| 4413 | insertFunctionGaps(executable); |
| 4414 | for (const WriteBarrier<FunctionExecutable>& executable : m_functionExprs) |
| 4415 | insertFunctionGaps(executable); |
| 4416 | |
| 4417 | instructions[startIdx + 1].u.basicBlockLocation = basicBlockLocation; |
| 4418 | } |
| 4419 | } |
| 4420 | |
sbarati@apple.com | d3d0c00 | 2016-01-30 01:11:05 +0000 | [diff] [blame] | 4421 | #if ENABLE(JIT) |
| 4422 | void CodeBlock::setPCToCodeOriginMap(std::unique_ptr<PCToCodeOriginMap>&& map) |
| 4423 | { |
| 4424 | m_pcToCodeOriginMap = WTFMove(map); |
| 4425 | } |
| 4426 | |
| 4427 | Optional<CodeOrigin> CodeBlock::findPC(void* pc) |
| 4428 | { |
| 4429 | if (m_pcToCodeOriginMap) { |
| 4430 | if (Optional<CodeOrigin> codeOrigin = m_pcToCodeOriginMap->findPC(pc)) |
| 4431 | return codeOrigin; |
| 4432 | } |
| 4433 | |
| 4434 | for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) { |
| 4435 | StructureStubInfo* stub = *iter; |
| 4436 | if (stub->containsPC(pc)) |
| 4437 | return Optional<CodeOrigin>(stub->codeOrigin); |
| 4438 | } |
| 4439 | |
| 4440 | if (Optional<CodeOrigin> codeOrigin = m_jitCode->findPC(this, pc)) |
| 4441 | return codeOrigin; |
| 4442 | |
| 4443 | return Nullopt; |
| 4444 | } |
| 4445 | #endif // ENABLE(JIT) |
| 4446 | |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 4447 | Optional<unsigned> CodeBlock::bytecodeOffsetFromCallSiteIndex(CallSiteIndex callSiteIndex) |
| 4448 | { |
| 4449 | Optional<unsigned> bytecodeOffset; |
| 4450 | JITCode::JITType jitType = this->jitType(); |
| 4451 | if (jitType == JITCode::InterpreterThunk || jitType == JITCode::BaselineJIT) { |
| 4452 | #if USE(JSVALUE64) |
| 4453 | bytecodeOffset = callSiteIndex.bits(); |
| 4454 | #else |
| 4455 | Instruction* instruction = bitwise_cast<Instruction*>(callSiteIndex.bits()); |
| 4456 | bytecodeOffset = instruction - instructions().begin(); |
| 4457 | #endif |
| 4458 | } else if (jitType == JITCode::DFGJIT || jitType == JITCode::FTLJIT) { |
sbarati@apple.com | 977e0ca | 2016-05-17 00:29:40 +0000 | [diff] [blame] | 4459 | #if ENABLE(DFG_JIT) |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 4460 | RELEASE_ASSERT(canGetCodeOrigin(callSiteIndex)); |
| 4461 | CodeOrigin origin = codeOrigin(callSiteIndex); |
| 4462 | bytecodeOffset = origin.bytecodeIndex; |
sbarati@apple.com | 977e0ca | 2016-05-17 00:29:40 +0000 | [diff] [blame] | 4463 | #else |
| 4464 | RELEASE_ASSERT_NOT_REACHED(); |
| 4465 | #endif |
sbarati@apple.com | ce5b05e | 2016-05-16 23:31:39 +0000 | [diff] [blame] | 4466 | } |
| 4467 | |
| 4468 | return bytecodeOffset; |
| 4469 | } |
| 4470 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 4471 | } // namespace JSC |