Source/JavaScriptCore/ChangeLog

 12012-01-24 Filip Pizlo <fpizlo@apple.com>
 2
 3 JSC should be a triple-tier VM
 4 https://bugs.webkit.org/show_bug.cgi?id=75812
 5 <rdar://problem/10079694>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Implemented an interpreter that uses the JIT's calling convention. This
 10 interpreter is called LLInt, or the Low Level Interpreter. JSC will now
 11 will start by executing code in LLInt and will only tier up to the old
 12 JIT after the code is proven hot.
 13
 14 LLInt is written in a modified form of our macro assembly. This new macro
 15 assembly is compiled by an offline assembler (see offlineasm), which
 16 implements many modern conveniences such as a Turing-complete CPS-based
 17 macro language and direct access to relevant C++ type information
 18 (basically offsets of fields and sizes of structs/classes).
 19
 20 Code executing in LLInt appears to the rest of the JSC world "as if" it
 21 were executing in the old JIT. Hence, things like exception handling and
 22 cross-execution-engine calls just work and require pretty much no
 23 additional overhead.
 24
 25 This interpreter is 2-2.5x faster than our old interpreter on SunSpider,
 26 V8, and Kraken. With triple-tiering turned on, we're neutral on SunSpider,
 27 V8, and Kraken, but appear to get a double-digit improvement on real-world
 28 websites due to a huge reduction in the amount of JIT'ing.
 29
 30 As an additional change, this patch makes bytecode dumping and JSValue
 31 dumping work in release builds, since debugging some of the nastier
 32 aspects of this patch would have been impossible without that. And I
 33 don't believe that we care about the miniscule code bloat that this
 34 introduces.
 35
 36 * CMakeLists.txt:
 37 * GNUmakefile.am:
 38 * GNUmakefile.list.am:
 39 * JavaScriptCore.pri:
 40 * JavaScriptCore.xcodeproj/project.pbxproj:
 41 * assembler/LinkBuffer.h:
 42 * bytecode/BytecodeConventions.h: Added.
 43 * bytecode/CallLinkStatus.cpp:
 44 (JSC::CallLinkStatus::computeFromLLInt):
 45 (JSC::CallLinkStatus::computeFor):
 46 * bytecode/CallLinkStatus.h:
 47 (JSC::CallLinkStatus::isSet):
 48 (JSC::CallLinkStatus::operator!):
 49 * bytecode/CodeBlock.cpp:
 50 (JSC::CodeBlock::dump):
 51 (JSC::CodeBlock::CodeBlock):
 52 (JSC::CodeBlock::~CodeBlock):
 53 (JSC::CodeBlock::finalizeUnconditionally):
 54 (JSC::CodeBlock::stronglyVisitStrongReferences):
 55 (JSC::CodeBlock::unlinkCalls):
 56 (JSC::CodeBlock::unlinkIncomingCalls):
 57 (JSC::CodeBlock::bytecodeOffset):
 58 (JSC::ProgramCodeBlock::jettison):
 59 (JSC::EvalCodeBlock::jettison):
 60 (JSC::FunctionCodeBlock::jettison):
 61 (JSC::ProgramCodeBlock::jitCompileImpl):
 62 (JSC::EvalCodeBlock::jitCompileImpl):
 63 (JSC::FunctionCodeBlock::jitCompileImpl):
 64 (JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
 65 * bytecode/CodeBlock.h:
 66 (JSC::CodeBlock::baselineVersion):
 67 (JSC::CodeBlock::linkIncomingCall):
 68 (JSC::CodeBlock::bytecodeOffset):
 69 (JSC::CodeBlock::jitCompile):
 70 (JSC::CodeBlock::hasOptimizedReplacement):
 71 (JSC::CodeBlock::addPropertyAccessInstruction):
 72 (JSC::CodeBlock::addGlobalResolveInstruction):
 73 (JSC::CodeBlock::addLLIntCallLinkInfo):
 74 (JSC::CodeBlock::addGlobalResolveInfo):
 75 (JSC::CodeBlock::numberOfMethodCallLinkInfos):
 76 (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
 77 (JSC::CodeBlock::likelyToTakeSlowCase):
 78 (JSC::CodeBlock::couldTakeSlowCase):
 79 (JSC::CodeBlock::likelyToTakeSpecialFastCase):
 80 (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
 81 (JSC::CodeBlock::likelyToTakeAnySlowCase):
 82 (JSC::CodeBlock::addFrequentExitSite):
 83 (JSC::CodeBlock::dontJITAnytimeSoon):
 84 (JSC::CodeBlock::jitAfterWarmUp):
 85 (JSC::CodeBlock::jitSoon):
 86 (JSC::CodeBlock::llintExecuteCounter):
 87 * bytecode/GetByIdStatus.cpp:
 88 (JSC::GetByIdStatus::computeFromLLInt):
 89 (JSC::GetByIdStatus::computeFor):
 90 * bytecode/GetByIdStatus.h:
 91 (JSC::GetByIdStatus::GetByIdStatus):
 92 (JSC::GetByIdStatus::wasSeenInJIT):
 93 * bytecode/Instruction.h:
 94 (JSC::Instruction::Instruction):
 95 * bytecode/LLIntCallLinkInfo.h: Added.
 96 (JSC::LLIntCallLinkInfo::LLIntCallLinkInfo):
 97 (JSC::LLIntCallLinkInfo::~LLIntCallLinkInfo):
 98 (JSC::LLIntCallLinkInfo::isLinked):
 99 (JSC::LLIntCallLinkInfo::unlink):
 100 * bytecode/MethodCallLinkStatus.cpp:
 101 (JSC::MethodCallLinkStatus::computeFor):
 102 * bytecode/Opcode.h:
 103 * bytecode/PutByIdStatus.cpp:
 104 (JSC::PutByIdStatus::computeFromLLInt):
 105 (JSC::PutByIdStatus::computeFor):
 106 * bytecode/PutByIdStatus.h:
 107 * bytecompiler/BytecodeGenerator.cpp:
 108 (JSC::BytecodeGenerator::setDumpsGeneratedCode):
 109 (JSC::BytecodeGenerator::dumpsGeneratedCode):
 110 (JSC::BytecodeGenerator::generate):
 111 (JSC::BytecodeGenerator::emitResolve):
 112 (JSC::BytecodeGenerator::emitResolveWithBase):
 113 (JSC::BytecodeGenerator::emitResolveWithThis):
 114 (JSC::BytecodeGenerator::emitGetById):
 115 (JSC::BytecodeGenerator::emitPutById):
 116 (JSC::BytecodeGenerator::emitDirectPutById):
 117 (JSC::BytecodeGenerator::emitCall):
 118 (JSC::BytecodeGenerator::emitConstruct):
 119 (JSC::BytecodeGenerator::emitCatch):
 120 * dfg/DFGByteCodeParser.cpp:
 121 (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
 122 (JSC::DFG::ByteCodeParser::handleInlining):
 123 (JSC::DFG::ByteCodeParser::parseBlock):
 124 * dfg/DFGCapabilities.h:
 125 (JSC::DFG::canCompileOpcode):
 126 * dfg/DFGOSRExitCompiler.cpp:
 127 * dfg/DFGOperations.cpp:
 128 * heap/AllocationSpace.h:
 129 * heap/Heap.cpp:
 130 (JSC::Heap::collect):
 131 * heap/Heap.h:
 132 * heap/MarkStack.cpp:
 133 (JSC::visitChildren):
 134 * heap/MarkedSpace.h:
 135 * interpreter/CallFrame.h:
 136 (JSC::ExecState::currentVPC):
 137 * interpreter/Interpreter.cpp:
 138 (JSC::Interpreter::~Interpreter):
 139 (JSC::Interpreter::initialize):
 140 (JSC::Interpreter::isOpcode):
 141 (JSC::Interpreter::unwindCallFrame):
 142 (JSC::Interpreter::retrieveLastCaller):
 143 * interpreter/Interpreter.h:
 144 (JSC::Interpreter::getOpcode):
 145 (JSC::Interpreter::getOpcodeID):
 146 (JSC::Interpreter::enabled):
 147 * interpreter/RegisterFile.h:
 148 * jit/HostCallReturnValue.cpp: Added.
 149 (JSC::getHostCallReturnValueWithExecState):
 150 * jit/HostCallReturnValue.h: Added.
 151 * jit/JIT.cpp:
 152 (JSC::JIT::privateCompileMainPass):
 153 (JSC::JIT::privateCompileSlowCases):
 154 (JSC::JIT::privateCompile):
 155 * jit/JITCode.h:
 156 (JSC::JITCode::isOptimizingJIT):
 157 (JSC::JITCode::isBaselineCode):
 158 (JSC::JITCode::JITCode):
 159 * jit/JITDriver.h:
 160 (JSC::jitCompileIfAppropriate):
 161 (JSC::jitCompileFunctionIfAppropriate):
 162 * jit/JITExceptions.cpp:
 163 (JSC::jitThrow):
 164 * jit/JITStubs.cpp:
 165 (JSC::DEFINE_STUB_FUNCTION):
 166 * jit/JSInterfaceJIT.h:
 167 * llint: Added.
 168 * llint/LLIntCommon.h: Added.
 169 * llint/LLIntData.cpp: Added.
 170 (JSC::LLInt::Data::Data):
 171 (JSC::LLInt::Data::~Data):
 172 * llint/LLIntData.h: Added.
 173 (JSC::LLInt::Data::exceptionInstructions):
 174 (JSC::LLInt::Data::opcodeMap):
 175 * llint/LLIntEntrypoints.cpp: Added.
 176 (JSC::LLInt::getFunctionEntrypoint):
 177 (JSC::LLInt::getEvalEntrypoint):
 178 (JSC::LLInt::getProgramEntrypoint):
 179 * llint/LLIntEntrypoints.h: Added.
 180 (JSC::LLInt::getEntrypoint):
 181 * llint/LLIntExceptions.cpp: Added.
 182 (JSC::LLInt::interpreterThrowInCaller):
 183 (JSC::LLInt::returnToThrowForThrownException):
 184 (JSC::LLInt::returnToThrow):
 185 (JSC::LLInt::callToThrow):
 186 * llint/LLIntExceptions.h: Added.
 187 * llint/LLIntHelpers.cpp: Added.
 188 (JSC::LLInt::llint_trace_operand):
 189 (JSC::LLInt::llint_trace_value):
 190 (JSC::LLInt::LLINT_HELPER_DECL):
 191 (JSC::LLInt::traceFunctionPrologue):
 192 (JSC::LLInt::shouldJIT):
 193 (JSC::LLInt::entryOSR):
 194 (JSC::LLInt::resolveGlobal):
 195 (JSC::LLInt::getByVal):
 196 (JSC::LLInt::handleHostCall):
 197 (JSC::LLInt::setUpCall):
 198 (JSC::LLInt::genericCall):
 199 * llint/LLIntHelpers.h: Added.
 200 * llint/LLIntOfflineAsmConfig.h: Added.
 201 * llint/LLIntOffsetsExtractor.cpp: Added.
 202 (JSC::LLIntOffsetsExtractor::dummy):
 203 (main):
 204 * llint/LLIntThunks.cpp: Added.
 205 (JSC::LLInt::generateThunkWithJumpTo):
 206 (JSC::LLInt::functionForCallEntryThunkGenerator):
 207 (JSC::LLInt::functionForConstructEntryThunkGenerator):
 208 (JSC::LLInt::functionForCallArityCheckThunkGenerator):
 209 (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
 210 (JSC::LLInt::evalEntryThunkGenerator):
 211 (JSC::LLInt::programEntryThunkGenerator):
 212 * llint/LLIntThunks.h: Added.
 213 * llint/LowLevelInterpreter.asm: Added.
 214 * llint/LowLevelInterpreter.cpp: Added.
 215 * llint/LowLevelInterpreter.h: Added.
 216 * offlineasm: Added.
 217 * offlineasm/armv7.rb: Added.
 218 * offlineasm/asm.rb: Added.
 219 * offlineasm/ast.rb: Added.
 220 * offlineasm/backends.rb: Added.
 221 * offlineasm/generate_offset_extractor.rb: Added.
 222 * offlineasm/instructions.rb: Added.
 223 * offlineasm/offset_extractor_constants.rb: Added.
 224 * offlineasm/offsets.rb: Added.
 225 * offlineasm/parser.rb: Added.
 226 * offlineasm/registers.rb: Added.
 227 * offlineasm/settings.rb: Added.
 228 * offlineasm/transform.rb: Added.
 229 * offlineasm/x86.rb: Added.
 230 * runtime/CodeSpecializationKind.h: Added.
 231 * runtime/CommonSlowPaths.h:
 232 (JSC::CommonSlowPaths::arityCheckFor):
 233 * runtime/Executable.cpp:
 234 (JSC::jettisonCodeBlock):
 235 (JSC::EvalExecutable::jitCompile):
 236 (JSC::samplingDescription):
 237 (JSC::EvalExecutable::compileInternal):
 238 (JSC::ProgramExecutable::jitCompile):
 239 (JSC::ProgramExecutable::compileInternal):
 240 (JSC::FunctionExecutable::baselineCodeBlockFor):
 241 (JSC::FunctionExecutable::jitCompileForCall):
 242 (JSC::FunctionExecutable::jitCompileForConstruct):
 243 (JSC::FunctionExecutable::compileForCallInternal):
 244 (JSC::FunctionExecutable::compileForConstructInternal):
 245 * runtime/Executable.h:
 246 (JSC::FunctionExecutable::jitCompileFor):
 247 * runtime/ExecutionHarness.h: Added.
 248 (JSC::prepareForExecution):
 249 (JSC::prepareFunctionForExecution):
 250 * runtime/JSActivation.h:
 251 (JSC::JSActivation::tearOff):
 252 * runtime/JSArray.h:
 253 * runtime/JSCell.h:
 254 * runtime/JSFunction.h:
 255 * runtime/JSGlobalData.cpp:
 256 (JSC::JSGlobalData::JSGlobalData):
 257 * runtime/JSGlobalData.h:
 258 * runtime/JSGlobalObject.h:
 259 * runtime/JSObject.h:
 260 * runtime/JSPropertyNameIterator.h:
 261 * runtime/JSString.h:
 262 * runtime/JSTypeInfo.h:
 263 * runtime/JSValue.cpp:
 264 (JSC::JSValue::description):
 265 * runtime/JSValue.h:
 266 * runtime/JSVariableObject.h:
 267 * runtime/Options.cpp:
 268 (JSC::Options::initializeOptions):
 269 * runtime/Options.h:
 270 * runtime/ScopeChain.h:
 271 * runtime/Structure.h:
 272 * runtime/StructureChain.h:
 273 * wtf/Platform.h:
 274 * wtf/SentinelLinkedList.h:
 275 (WTF::SentinelLinkedList::isEmpty):
 276 * wtf/text/StringImpl.h:
 277
12782012-01-24 Gavin Barraclough <barraclough@apple.com>
2279
3280 https://bugs.webkit.org/show_bug.cgi?id=76855
105845

Source/JavaScriptCore/CMakeLists.txt

@@SET(JavaScriptCore_INCLUDE_DIRECTORIES
1111 "${JAVASCRIPTCORE_DIR}/debugger"
1212 "${JAVASCRIPTCORE_DIR}/interpreter"
1313 "${JAVASCRIPTCORE_DIR}/jit"
 14 "${JAVASCRIPTCORE_DIR}/llint"
1415 "${JAVASCRIPTCORE_DIR}/parser"
1516 "${JAVASCRIPTCORE_DIR}/profiler"
1617 "${JAVASCRIPTCORE_DIR}/runtime"

@@SET(JavaScriptCore_SOURCES
9495 interpreter/RegisterFile.cpp
9596
9697 jit/ExecutableAllocator.cpp
 98 jit/HostCallReturnValue.cpp
9799 jit/JITArithmetic32_64.cpp
98100 jit/JITArithmetic.cpp
99101 jit/JITCall32_64.cpp
105770

Source/JavaScriptCore/GNUmakefile.am

@@javascriptcore_cppflags += \
5757 -I$(srcdir)/Source/JavaScriptCore/interpreter \
5858 -I$(srcdir)/Source/JavaScriptCore/jit \
5959 -I$(srcdir)/Source/JavaScriptCore/jit \
 60 -I$(srcdir)/Source/JavaScriptCore/llint \
6061 -I$(srcdir)/Source/JavaScriptCore/parser \
6162 -I$(srcdir)/Source/JavaScriptCore/profiler \
6263 -I$(srcdir)/Source/JavaScriptCore/runtime \
105770

Source/JavaScriptCore/GNUmakefile.list.am

@@javascriptcore_sources += \
8181 Source/JavaScriptCore/assembler/RepatchBuffer.h \
8282 Source/JavaScriptCore/assembler/SH4Assembler.h \
8383 Source/JavaScriptCore/assembler/X86Assembler.h \
 84 Source/JavaScriptCore/bytecode/BytecodeConventions.h \
8485 Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
8586 Source/JavaScriptCore/bytecode/CallLinkInfo.h \
8687 Source/JavaScriptCore/bytecode/CallLinkStatus.cpp \

@@javascriptcore_sources += \
102103 Source/JavaScriptCore/bytecode/Instruction.h \
103104 Source/JavaScriptCore/bytecode/JumpTable.cpp \
104105 Source/JavaScriptCore/bytecode/JumpTable.h \
 106 Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h \
105107 Source/JavaScriptCore/bytecode/LineInfo.h \
106108 Source/JavaScriptCore/bytecode/MethodCallLinkInfo.cpp \
107109 Source/JavaScriptCore/bytecode/MethodCallLinkInfo.h \

@@javascriptcore_sources += \
277279 Source/JavaScriptCore/jit/CompactJITCodeMap.h \
278280 Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
279281 Source/JavaScriptCore/jit/ExecutableAllocator.h \
 282 Source/JavaScriptCore/jit/HostCallReturnValue.cpp \
 283 Source/JavaScriptCore/jit/HostCallReturnValue.h \
280284 Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \
281285 Source/JavaScriptCore/jit/JITArithmetic.cpp \
282286 Source/JavaScriptCore/jit/JITCall32_64.cpp \

@@javascriptcore_sources += \
300304 Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
301305 Source/JavaScriptCore/jit/ThunkGenerators.cpp \
302306 Source/JavaScriptCore/jit/ThunkGenerators.h \
 307 Source/JavaScriptCore/llint/LLIntData.h \
303308 Source/JavaScriptCore/os-win32/stdbool.h \
304309 Source/JavaScriptCore/os-win32/stdint.h \
305310 Source/JavaScriptCore/parser/ASTBuilder.h \

@@javascriptcore_sources += \
350355 Source/JavaScriptCore/runtime/CallData.cpp \
351356 Source/JavaScriptCore/runtime/CallData.h \
352357 Source/JavaScriptCore/runtime/ClassInfo.h \
 358 Source/JavaScriptCore/runtime/CodeSpecializationKind.h \
353359 Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \
354360 Source/JavaScriptCore/runtime/CommonIdentifiers.h \
355361 Source/JavaScriptCore/runtime/CommonSlowPaths.h \

@@javascriptcore_sources += \
378384 Source/JavaScriptCore/runtime/ExceptionHelpers.h \
379385 Source/JavaScriptCore/runtime/Executable.cpp \
380386 Source/JavaScriptCore/runtime/Executable.h \
 387 Source/JavaScriptCore/runtime/ExecutionHarness.h \
381388 Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
382389 Source/JavaScriptCore/runtime/FunctionConstructor.h \
383390 Source/JavaScriptCore/runtime/FunctionPrototype.cpp \
105770

Source/JavaScriptCore/JavaScriptCore.pri

@@INCLUDEPATH += \
2020 $$SOURCE_DIR/debugger \
2121 $$SOURCE_DIR/interpreter \
2222 $$SOURCE_DIR/jit \
 23 $$SOURCE_DIR/llint \
2324 $$SOURCE_DIR/parser \
2425 $$SOURCE_DIR/profiler \
2526 $$SOURCE_DIR/runtime \
105770

Source/JavaScriptCore/Target.pri

@@SOURCES += \
106106 interpreter/RegisterFile.cpp \
107107 jit/ExecutableAllocatorFixedVMPool.cpp \
108108 jit/ExecutableAllocator.cpp \
 109 jit/HostCallReturnValue.cpp \
109110 jit/JITArithmetic.cpp \
110111 jit/JITArithmetic32_64.cpp \
111112 jit/JITCall.cpp \
105770

Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

17301730 >
17311731 </File>
17321732 <File
 1733 RelativePath="..\..\jit\HostCallReturnValue.cpp"
 1734 >
 1735 </File>
 1736 <File
17331737 RelativePath="..\..\jit\JIT.cpp"
17341738 >
17351739 </File>
105770

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

77 objects = {
88
99/* Begin PBXAggregateTarget section */
 10 0F4680A914BA7FD900BFE272 /* LLInt Offsets */ = {
 11 isa = PBXAggregateTarget;
 12 buildConfigurationList = 0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */;
 13 buildPhases = (
 14 0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */,
 15 );
 16 name = "LLInt Offsets";
 17 productName = "Derived Sources";
 18 };
1019 65FB3F6609D11E9100F49DEB /* Derived Sources */ = {
1120 isa = PBXAggregateTarget;
1221 buildConfigurationList = 65FB3F7709D11EBD00F49DEB /* Build configuration list for PBXAggregateTarget "Derived Sources" */;

1423 65FB3F6509D11E9100F49DEB /* Generate Derived Sources */,
1524 5D35DEE10C7C140B008648B2 /* Generate DTrace header */,
1625 );
 26 dependencies = (
 27 0F4680B414BA821400BFE272 /* PBXTargetDependency */,
 28 );
1729 name = "Derived Sources";
1830 productName = "Derived Sources";
1931 };

4860 0BAC94A01338728400CF135B /* ThreadRestrictionVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
4961 0BCD83571485845200EA2003 /* TemporaryChange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BCD83541485841200EA2003 /* TemporaryChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
5062 0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
 63 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */; };
 64 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
 65 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */; };
 66 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B839814BCF45A00885B4F /* LLIntThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
5167 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A514BCF50400885B4F /* CodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
5268 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
5369 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };

5874 0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
5975 0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
6076 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
 77 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
6178 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
6279 0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
6380 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C26614BE5F5E00ADC64B /* JITDriver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 81 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */; settings = {ATTRIBUTES = (Private, ); }; };
 82 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
 83 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; };
6484 0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
6585 0F2C556F14738F3100121E4F /* DFGCodeBlocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */; settings = {ATTRIBUTES = (Private, ); }; };
6686 0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */; };

7191 0F431738146BAC69007E3890 /* ListableHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F431736146BAC65007E3890 /* ListableHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
7292 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46808014BA572700BFE272 /* JITExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
7393 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46807F14BA572700BFE272 /* JITExceptions.cpp */; };
 94 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 95 0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */; settings = {COMPILER_FLAGS = "-Wno-unused-parameter"; }; };
 96 0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
 97 0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
 98 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */; };
 99 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C514BBB16900BFE272 /* LLIntCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
 100 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */; settings = {ATTRIBUTES = (Private, ); }; };
 101 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */; };
 102 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 103 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */; };
 104 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 105 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; };
 106 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
74107 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
75108 0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; };
76109 0F620175143FCD370068B77C /* DFGOperands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620171143FCD2F0068B77C /* DFGOperands.h */; settings = {ATTRIBUTES = (Private, ); }; };

383416 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
384417 86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
385418 86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
386  86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
 419 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
387420 86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
388421 86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
389422 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };

752785/* End PBXBuildFile section */
753786
754787/* Begin PBXContainerItemProxy section */
 788 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */ = {
 789 isa = PBXContainerItemProxy;
 790 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 791 proxyType = 1;
 792 remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
 793 remoteInfo = "LLInt Offsets";
 794 };
 795 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */ = {
 796 isa = PBXContainerItemProxy;
 797 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 798 proxyType = 1;
 799 remoteGlobalIDString = 0F46808E14BA7E5E00BFE272;
 800 remoteInfo = JSCLLIntOffsetsExtractor;
 801 };
755802 141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
756803 isa = PBXContainerItemProxy;
757804 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;

797844/* End PBXContainerItemProxy section */
798845
799846/* Begin PBXCopyFilesBuildPhase section */
 847 0F46808D14BA7E5E00BFE272 /* CopyFiles */ = {
 848 isa = PBXCopyFilesBuildPhase;
 849 buildActionMask = 2147483647;
 850 dstPath = /usr/share/man/man1/;
 851 dstSubfolderSpec = 0;
 852 files = (
 853 );
 854 runOnlyForDeploymentPostprocessing = 1;
 855 };
800856 5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
801857 isa = PBXCopyFilesBuildPhase;
802858 buildActionMask = 12;

837893 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
838894 0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
839895 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
 896 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
 897 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
 898 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
 899 0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
840900 0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
841901 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
842902 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };

847907 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
848908 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
849909 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
 910 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
850911 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
851912 0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
852913 0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
 914 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
 915 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
 916 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
853917 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
854918 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
855919 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };

860924 0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
861925 0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
862926 0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
 927 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
 928 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntExceptions.cpp; path = llint/LLIntExceptions.cpp; sourceTree = "<group>"; };
 929 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntExceptions.h; path = llint/LLIntExceptions.h; sourceTree = "<group>"; };
 930 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntHelpers.cpp; path = llint/LLIntHelpers.cpp; sourceTree = "<group>"; };
 931 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntHelpers.h; path = llint/LLIntHelpers.h; sourceTree = "<group>"; };
 932 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntOffsetsExtractor.cpp; path = llint/LLIntOffsetsExtractor.cpp; sourceTree = "<group>"; };
 933 0F4680C514BBB16900BFE272 /* LLIntCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCommon.h; path = llint/LLIntCommon.h; sourceTree = "<group>"; };
 934 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOfflineAsmConfig.h; path = llint/LLIntOfflineAsmConfig.h; sourceTree = "<group>"; };
 935 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LowLevelInterpreter.cpp; path = llint/LowLevelInterpreter.cpp; sourceTree = "<group>"; };
 936 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LowLevelInterpreter.h; path = llint/LowLevelInterpreter.h; sourceTree = "<group>"; };
 937 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntData.cpp; path = llint/LLIntData.cpp; sourceTree = "<group>"; };
 938 0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
 939 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
 940 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
863941 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
864942 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
865943 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; };

15791657/* End PBXFileReference section */
15801658
15811659/* Begin PBXFrameworksBuildPhase section */
 1660 0F46808C14BA7E5E00BFE272 /* Frameworks */ = {
 1661 isa = PBXFrameworksBuildPhase;
 1662 buildActionMask = 2147483647;
 1663 files = (
 1664 );
 1665 runOnlyForDeploymentPostprocessing = 0;
 1666 };
15821667 1412111E0A48793C00480255 /* Frameworks */ = {
15831668 isa = PBXFrameworksBuildPhase;
15841669 buildActionMask = 2147483647;

16371722 141211200A48793C00480255 /* minidom */,
16381723 14BD59BF0A3E8F9000BAF59C /* testapi */,
16391724 6511230514046A4C002B101D /* testRegExp */,
 1725 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
16401726 );
16411727 name = Products;
16421728 sourceTree = "<group>";

16671753 F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
16681754 45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
16691755 F68EBB8C0255D4C601FF60F7 /* config.h */,
 1756 0F46809C14BA7F4D00BFE272 /* llint */,
16701757 1432EBD70A34CAD400717B9F /* API */,
16711758 9688CB120ED12B4E001D649F /* assembler */,
16721759 969A078F0ED1D3AE00F1F681 /* bytecode */,

17051792 tabWidth = 4;
17061793 usesTabs = 0;
17071794 };
 1795 0F46809C14BA7F4D00BFE272 /* llint */ = {
 1796 isa = PBXGroup;
 1797 children = (
 1798 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
 1799 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
 1800 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
 1801 0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
 1802 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
 1803 0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
 1804 0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
 1805 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
 1806 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
 1807 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
 1808 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
 1809 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
 1810 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */,
 1811 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */,
 1812 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
 1813 );
 1814 name = llint;
 1815 sourceTree = "<group>";
 1816 };
17081817 141211000A48772600480255 /* tests */ = {
17091818 isa = PBXGroup;
17101819 children = (

17371846 1429D92C0ED22D7000B89619 /* jit */ = {
17381847 isa = PBXGroup;
17391848 children = (
 1849 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
 1850 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
17401851 0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
17411852 0F46808014BA572700BFE272 /* JITExceptions.h */,
17421853 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,

21662277 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
21672278 isa = PBXGroup;
21682279 children = (
 2280 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
 2281 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
21692282 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
21702283 BCF605110E203EF800B9A64D /* ArgList.cpp */,
21712284 BCF605120E203EF800B9A64D /* ArgList.h */,

25252638 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
25262639 isa = PBXGroup;
25272640 children = (
 2641 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
 2642 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
25282643 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
25292644 0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
25302645 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,

30763191 86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
30773192 86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
30783193 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
 3194 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
 3195 0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */,
30793196 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
 3197 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
 3198 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
 3199 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
 3200 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
 3201 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
 3202 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
 3203 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
30803204 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
30813205 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
30823206 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,

30853209 0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
30863210 0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
30873211 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
 3212 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
30883213 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
 3214 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
 3215 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
 3216 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
30893217 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
30903218 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
30913219 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,

31033231/* End PBXHeadersBuildPhase section */
31043232
31053233/* Begin PBXNativeTarget section */
 3234 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {
 3235 isa = PBXNativeTarget;
 3236 buildConfigurationList = 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */;
 3237 buildPhases = (
 3238 0F46808B14BA7E5E00BFE272 /* Sources */,
 3239 0F46808C14BA7E5E00BFE272 /* Frameworks */,
 3240 0F46808D14BA7E5E00BFE272 /* CopyFiles */,
 3241 );
 3242 buildRules = (
 3243 );
 3244 dependencies = (
 3245 0F4680B214BA811500BFE272 /* PBXTargetDependency */,
 3246 );
 3247 name = JSCLLIntOffsetsExtractor;
 3248 productName = JSCLLIntOffsetsExtractor;
 3249 productReference = 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3250 productType = "com.apple.product-type.tool";
 3251 };
31063252 1412111F0A48793C00480255 /* minidom */ = {
31073253 isa = PBXNativeTarget;
31083254 buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;

32293375 14BD59BE0A3E8F9000BAF59C /* testapi */,
32303376 932F5BDA0822A1C700736975 /* jsc */,
32313377 651122F714046A4C002B101D /* testRegExp */,
 3378 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
 3379 0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
32323380 );
32333381 };
32343382/* End PBXProject section */
32353383
32363384/* Begin PBXShellScriptBuildPhase section */
 3385 0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */ = {
 3386 isa = PBXShellScriptBuildPhase;
 3387 buildActionMask = 2147483647;
 3388 files = (
 3389 );
 3390 inputPaths = (
 3391 "$(SRCROOT)/llint/LowLevelAssembler.asm",
 3392 );
 3393 name = "Generate Derived Sources";
 3394 outputPaths = (
 3395 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
 3396 );
 3397 runOnlyForDeploymentPostprocessing = 0;
 3398 shellPath = /bin/sh;
 3399 shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/\"\n\n/usr/bin/env ruby \"${SRCROOT}/offlineasm/generate_offset_extractor.rb\" \"${SRCROOT}/llint/LowLevelInterpreter.asm\" \"${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\"\n";
 3400 };
32373401 3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
32383402 isa = PBXShellScriptBuildPhase;
32393403 buildActionMask = 2147483647;

33393503 );
33403504 runOnlyForDeploymentPostprocessing = 0;
33413505 shellPath = /bin/sh;
3342  shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake --no-builtin-rules -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n";
 3506 shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake --no-builtin-rules -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n\n/usr/bin/env ruby JavaScriptCore/offlineasm/asm.rb JavaScriptCore/llint/LowLevelInterpreter.asm ${BUILT_PRODUCTS_DIR}/JSCLLIntOffsetsExtractor LLIntAssembly.h\n";
33433507 };
33443508 9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
33453509 isa = PBXShellScriptBuildPhase;

33743538/* End PBXShellScriptBuildPhase section */
33753539
33763540/* Begin PBXSourcesBuildPhase section */
 3541 0F46808B14BA7E5E00BFE272 /* Sources */ = {
 3542 isa = PBXSourcesBuildPhase;
 3543 buildActionMask = 2147483647;
 3544 files = (
 3545 0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */,
 3546 );
 3547 runOnlyForDeploymentPostprocessing = 0;
 3548 };
33773549 1412111D0A48793C00480255 /* Sources */ = {
33783550 isa = PBXSourcesBuildPhase;
33793551 buildActionMask = 2147483647;

36323804 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
36333805 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
36343806 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
 3807 0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */,
 3808 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
36353809 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
 3810 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
 3811 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
 3812 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
 3813 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
 3814 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
36363815 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
36373816 0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
36383817 F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,

36543833/* End PBXSourcesBuildPhase section */
36553834
36563835/* Begin PBXTargetDependency section */
 3836 0F4680B214BA811500BFE272 /* PBXTargetDependency */ = {
 3837 isa = PBXTargetDependency;
 3838 target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
 3839 targetProxy = 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */;
 3840 };
 3841 0F4680B414BA821400BFE272 /* PBXTargetDependency */ = {
 3842 isa = PBXTargetDependency;
 3843 target = 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3844 targetProxy = 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */;
 3845 };
36573846 141214BF0A49190E00480255 /* PBXTargetDependency */ = {
36583847 isa = PBXTargetDependency;
36593848 target = 1412111F0A48793C00480255 /* minidom */;

36873876/* End PBXTargetDependency section */
36883877
36893878/* Begin XCBuildConfiguration section */
 3879 0F46809614BA7E5E00BFE272 /* Debug */ = {
 3880 isa = XCBuildConfiguration;
 3881 buildSettings = {
 3882 ALWAYS_SEARCH_USER_PATHS = NO;
 3883 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3884 COPY_PHASE_STRIP = NO;
 3885 GCC_C_LANGUAGE_STANDARD = gnu99;
 3886 GCC_DYNAMIC_NO_PIC = NO;
 3887 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3888 GCC_OPTIMIZATION_LEVEL = 0;
 3889 GCC_PREPROCESSOR_DEFINITIONS = (
 3890 "DEBUG=1",
 3891 "$(inherited)",
 3892 );
 3893 GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 3894 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3895 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3896 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3897 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3898 GCC_WARN_UNUSED_VARIABLE = YES;
 3899 "HEADER_SEARCH_PATHS[arch=*]" = (
 3900 .,
 3901 icu,
 3902 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3903 "$(HEADER_SEARCH_PATHS)",
 3904 );
 3905 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3906 ONLY_ACTIVE_ARCH = YES;
 3907 PRODUCT_NAME = "$(TARGET_NAME)";
 3908 SDKROOT = macosx;
 3909 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3910 };
 3911 name = Debug;
 3912 };
 3913 0F46809714BA7E5E00BFE272 /* Release */ = {
 3914 isa = XCBuildConfiguration;
 3915 buildSettings = {
 3916 ALWAYS_SEARCH_USER_PATHS = NO;
 3917 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3918 COPY_PHASE_STRIP = YES;
 3919 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3920 GCC_C_LANGUAGE_STANDARD = gnu99;
 3921 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3922 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3923 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3924 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3925 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3926 GCC_WARN_UNUSED_VARIABLE = YES;
 3927 "HEADER_SEARCH_PATHS[arch=*]" = (
 3928 .,
 3929 icu,
 3930 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets$(HEADER_SEARCH_PATHS)",
 3931 );
 3932 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3933 PRODUCT_NAME = "$(TARGET_NAME)";
 3934 SDKROOT = macosx;
 3935 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3936 };
 3937 name = Release;
 3938 };
 3939 0F46809814BA7E5E00BFE272 /* Profiling */ = {
 3940 isa = XCBuildConfiguration;
 3941 buildSettings = {
 3942 ALWAYS_SEARCH_USER_PATHS = NO;
 3943 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3944 COPY_PHASE_STRIP = YES;
 3945 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3946 GCC_C_LANGUAGE_STANDARD = gnu99;
 3947 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3948 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3949 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3950 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3951 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3952 GCC_WARN_UNUSED_VARIABLE = YES;
 3953 "HEADER_SEARCH_PATHS[arch=*]" = (
 3954 .,
 3955 icu,
 3956 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3957 "$(HEADER_SEARCH_PATHS)",
 3958 );
 3959 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3960 PRODUCT_NAME = "$(TARGET_NAME)";
 3961 SDKROOT = macosx;
 3962 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3963 };
 3964 name = Profiling;
 3965 };
 3966 0F46809914BA7E5E00BFE272 /* Production */ = {
 3967 isa = XCBuildConfiguration;
 3968 buildSettings = {
 3969 ALWAYS_SEARCH_USER_PATHS = NO;
 3970 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3971 COPY_PHASE_STRIP = YES;
 3972 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3973 GCC_C_LANGUAGE_STANDARD = gnu99;
 3974 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3975 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3976 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3977 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3978 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3979 GCC_WARN_UNUSED_VARIABLE = YES;
 3980 "HEADER_SEARCH_PATHS[arch=*]" = (
 3981 .,
 3982 icu,
 3983 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3984 "$(HEADER_SEARCH_PATHS)",
 3985 );
 3986 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3987 PRODUCT_NAME = "$(TARGET_NAME)";
 3988 SDKROOT = macosx;
 3989 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3990 };
 3991 name = Production;
 3992 };
 3993 0F4680AD14BA7FD900BFE272 /* Debug */ = {
 3994 isa = XCBuildConfiguration;
 3995 buildSettings = {
 3996 PRODUCT_NAME = "Derived Sources copy";
 3997 };
 3998 name = Debug;
 3999 };
 4000 0F4680AE14BA7FD900BFE272 /* Release */ = {
 4001 isa = XCBuildConfiguration;
 4002 buildSettings = {
 4003 PRODUCT_NAME = "Derived Sources copy";
 4004 };
 4005 name = Release;
 4006 };
 4007 0F4680AF14BA7FD900BFE272 /* Profiling */ = {
 4008 isa = XCBuildConfiguration;
 4009 buildSettings = {
 4010 PRODUCT_NAME = "Derived Sources copy";
 4011 };
 4012 name = Profiling;
 4013 };
 4014 0F4680B014BA7FD900BFE272 /* Production */ = {
 4015 isa = XCBuildConfiguration;
 4016 buildSettings = {
 4017 PRODUCT_NAME = "Derived Sources copy";
 4018 };
 4019 name = Production;
 4020 };
36904021 1412113A0A48798400480255 /* Debug */ = {
36914022 isa = XCBuildConfiguration;
36924023 buildSettings = {

39284259/* End XCBuildConfiguration section */
39294260
39304261/* Begin XCConfigurationList section */
 4262 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */ = {
 4263 isa = XCConfigurationList;
 4264 buildConfigurations = (
 4265 0F46809614BA7E5E00BFE272 /* Debug */,
 4266 0F46809714BA7E5E00BFE272 /* Release */,
 4267 0F46809814BA7E5E00BFE272 /* Profiling */,
 4268 0F46809914BA7E5E00BFE272 /* Production */,
 4269 );
 4270 defaultConfigurationIsVisible = 0;
 4271 defaultConfigurationName = Production;
 4272 };
 4273 0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */ = {
 4274 isa = XCConfigurationList;
 4275 buildConfigurations = (
 4276 0F4680AD14BA7FD900BFE272 /* Debug */,
 4277 0F4680AE14BA7FD900BFE272 /* Release */,
 4278 0F4680AF14BA7FD900BFE272 /* Profiling */,
 4279 0F4680B014BA7FD900BFE272 /* Production */,
 4280 );
 4281 defaultConfigurationIsVisible = 0;
 4282 defaultConfigurationName = Production;
 4283 };
39314284 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
39324285 isa = XCConfigurationList;
39334286 buildConfigurations = (
105770

Source/JavaScriptCore/assembler/LinkBuffer.h

3434#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))
3535#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))
3636
37 #include <MacroAssembler.h>
 37#include "MacroAssembler.h"
3838#include <wtf/Noncopyable.h>
3939
4040namespace JSC {
105770

Source/JavaScriptCore/bytecode/BytecodeConventions.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef BytecodeConventions_h
 27#define BytecodeConventions_h
 28
 29// Register numbers used in bytecode operations have different meaning according to their ranges:
 30// 0x80000000-0xFFFFFFFF Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
 31// 0x00000000-0x3FFFFFFF Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
 32// 0x40000000-0x7FFFFFFF Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
 33static const int FirstConstantRegisterIndex = 0x40000000;
 34
 35#endif // BytecodeConventions_h
 36
0

Source/JavaScriptCore/bytecode/CallLinkStatus.cpp

2727#include "CallLinkStatus.h"
2828
2929#include "CodeBlock.h"
 30#include "LLIntCallLinkInfo.h"
3031
3132namespace JSC {
3233
 34CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex)
 35{
 36 UNUSED_PARAM(profiledBlock);
 37 UNUSED_PARAM(bytecodeIndex);
 38#if ENABLE(LLINT)
 39 Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
 40 LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo;
 41
 42 return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false);
 43#else
 44 return CallLinkStatus(0, false);
 45#endif
 46}
 47
3348CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
3449{
3550 UNUSED_PARAM(profiledBlock);
3651 UNUSED_PARAM(bytecodeIndex);
3752#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
38  return CallLinkStatus(
39  profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get(),
40  profiledBlock->couldTakeSlowCase(bytecodeIndex));
 53 if (!profiledBlock->numberOfCallLinkInfos())
 54 return computeFromLLInt(profiledBlock, bytecodeIndex);
 55
 56 if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
 57 return CallLinkStatus(0, true);
 58
 59 JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get();
 60 if (!target)
 61 return computeFromLLInt(profiledBlock, bytecodeIndex);
 62
 63 return CallLinkStatus(target, false);
4164#else
4265 return CallLinkStatus(0, false);
4366#endif
105770

Source/JavaScriptCore/bytecode/CallLinkStatus.h

@@public:
4747
4848 static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
4949
50  bool isSet() const { return !!m_callTarget; }
 50 bool isSet() const { return !!m_callTarget || m_couldTakeSlowPath; }
5151
52  bool operator!() const { return !m_callTarget; }
 52 bool operator!() const { return !isSet(); }
5353
5454 bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
5555
5656 JSFunction* callTarget() const { return m_callTarget; }
5757
5858private:
 59 static CallLinkStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex);
 60
5961 JSFunction* m_callTarget;
6062 bool m_couldTakeSlowPath;
6163};
105770

Source/JavaScriptCore/bytecode/CodeBlock.cpp

4242#include "JSFunction.h"
4343#include "JSStaticScopeObject.h"
4444#include "JSValue.h"
 45#include "LowLevelInterpreter.h"
4546#include "RepatchBuffer.h"
4647#include "UStringConcatenate.h"
4748#include <stdio.h>

@@namespace JSC {
5960using namespace DFG;
6061#endif
6162
62 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
63 
6463static UString escapeQuotes(const UString& str)
6564{
6665 UString result = str;

@@void CodeBlock::dump(ExecState* exec) co
358357 for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
359358 ++instructionCount;
360359
361  printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
 360 printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n",
362361 static_cast<unsigned long>(instructionCount),
363362 static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
364  this, m_numParameters, m_numCalleeRegisters);
 363 this, m_numParameters, m_numCalleeRegisters, m_numVars);
365364
366365 Vector<Instruction>::const_iterator begin = instructions().begin();
367366 Vector<Instruction>::const_iterator end = instructions().end();

@@void CodeBlock::dump(ExecState* exec, co
898897 printPutByIdOp(exec, location, it, "put_by_id_transition");
899898 break;
900899 }
 900 case op_put_by_id_transition_direct: {
 901 printPutByIdOp(exec, location, it, "put_by_id_transition_direct");
 902 break;
 903 }
 904 case op_put_by_id_transition_normal: {
 905 printPutByIdOp(exec, location, it, "put_by_id_transition_normal");
 906 break;
 907 }
901908 case op_put_by_id_generic: {
902909 printPutByIdOp(exec, location, it, "put_by_id_generic");
903910 break;

@@void CodeBlock::dump(ExecState* exec, co
12911298 }
12921299}
12931300
1294 #endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
1295 
12961301#if DUMP_CODE_BLOCK_STATISTICS
12971302static HashSet<CodeBlock*> liveCodeBlockSet;
12981303#endif

@@CodeBlock::CodeBlock(CopyParsedBlockTag,
14591464{
14601465 setNumParameters(other.numParameters());
14611466 optimizeAfterWarmUp();
 1467 jitAfterWarmUp();
14621468
14631469 if (other.m_rareData) {
14641470 createRareDataIfNecessary();

@@CodeBlock::CodeBlock(ScriptExecutable* o
15071513 ASSERT(m_source);
15081514
15091515 optimizeAfterWarmUp();
 1516 jitAfterWarmUp();
15101517
15111518#if DUMP_CODE_BLOCK_STATISTICS
15121519 liveCodeBlockSet.add(this);

@@CodeBlock::~CodeBlock()
15241531#if ENABLE(VERBOSE_VALUE_PROFILE)
15251532 dumpValueProfiles();
15261533#endif
1527 
 1534
 1535#if ENABLE(LLINT)
 1536 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 1537 m_incomingLLIntCalls.begin()->remove();
 1538#endif // ENABLE(LLINT)
15281539#if ENABLE(JIT)
15291540 // We may be destroyed before any CodeBlocks that refer to us are destroyed.
15301541 // Consider that two CodeBlocks become unreachable at the same time. There

@@void CodeBlock::finalizeUnconditionally(
17361747#else
17371748 static const bool verboseUnlinking = false;
17381749#endif
1739 #endif
 1750#endif // ENABLE(JIT)
17401751
 1752#if ENABLE(LLINT)
 1753 Interpreter* interpreter = m_globalData->interpreter;
 1754 // interpreter->enabled() returns true if the old C++ interpreter is enabled. If that's enabled
 1755 // then we're not using LLInt.
 1756 if (!interpreter->enabled()) {
 1757 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
 1758 Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
 1759 switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
 1760 case op_get_by_id:
 1761 case op_put_by_id:
 1762 if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
 1763 break;
 1764 curInstruction[4].u.structure.clear();
 1765 curInstruction[5].u.operand = 0;
 1766 break;
 1767 case op_put_by_id_transition_direct:
 1768 case op_put_by_id_transition_normal:
 1769 if (Heap::isMarked(curInstruction[4].u.structure.get())
 1770 && Heap::isMarked(curInstruction[6].u.structure.get())
 1771 && Heap::isMarked(curInstruction[7].u.structureChain.get()))
 1772 break;
 1773 curInstruction[4].u.structure.clear();
 1774 curInstruction[6].u.structure.clear();
 1775 curInstruction[7].u.structureChain.clear();
 1776 curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
 1777 break;
 1778 default:
 1779 ASSERT_NOT_REACHED();
 1780 }
 1781 }
 1782 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) {
 1783 Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]];
 1784 ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global
 1785 || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic);
 1786 if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get()))
 1787 continue;
 1788 curInstruction[3].u.structure.clear();
 1789 curInstruction[4].u.operand = 0;
 1790 }
 1791 for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
 1792 if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
 1793 if (verboseUnlinking)
 1794 printf("Clearing LLInt call from %p.\n", this);
 1795 m_llintCallLinkInfos[i].unlink();
 1796 }
 1797 if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
 1798 m_llintCallLinkInfos[i].lastSeenCallee.clear();
 1799 }
 1800 }
 1801#endif // ENABLE(LLINT)
 1802
17411803#if ENABLE(DFG_JIT)
17421804 // Check if we're not live. If we are, then jettison.
17431805 if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {

@@void CodeBlock::stronglyVisitStrongRefer
18581920 for (size_t i = 0; i < m_functionDecls.size(); ++i)
18591921 visitor.append(&m_functionDecls[i]);
18601922#if ENABLE(INTERPRETER)
1861  for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1862  visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1863  for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1864  visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1923 if (m_globalData->interpreter->enabled()) {
 1924 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
 1925 visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
 1926 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
 1927 visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1928 }
18651929#endif
18661930
18671931#if ENABLE(DFG_JIT)

@@void CodeBlock::unlinkCalls()
20702134{
20712135 if (!!m_alternative)
20722136 m_alternative->unlinkCalls();
 2137#if ENABLE(LLINT)
 2138 for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
 2139 if (m_llintCallLinkInfos[i].isLinked())
 2140 m_llintCallLinkInfos[i].unlink();
 2141 }
 2142#endif
20732143 if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
20742144 return;
20752145 if (!m_globalData->canUseJIT())

@@void CodeBlock::unlinkCalls()
20842154
20852155void CodeBlock::unlinkIncomingCalls()
20862156{
 2157#if ENABLE(LLINT)
 2158 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 2159 m_incomingLLIntCalls.begin()->unlink();
 2160#endif
 2161 if (m_incomingCalls.isEmpty())
 2162 return;
20872163 RepatchBuffer repatchBuffer(this);
20882164 while (m_incomingCalls.begin() != m_incomingCalls.end())
20892165 m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
20902166}
 2167
 2168unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
 2169{
 2170#if ENABLE(LLINT)
 2171 if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
 2172 && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
 2173 ASSERT(exec->codeBlock());
 2174 ASSERT(exec->codeBlock() == this);
 2175 ASSERT(JITCode::isBaselineCode(getJITType()));
 2176 Instruction* instruction = exec->currentVPC();
 2177 ASSERT(instruction);
 2178 return bytecodeOffset(instruction);
 2179 }
 2180#else
 2181 UNUSED_PARAM(exec);
 2182#endif
 2183 if (!m_rareData)
 2184 return 1;
 2185 Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
 2186 if (!callIndices.size())
 2187 return 1;
 2188 return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
 2189}
20912190#endif
20922191
20932192void CodeBlock::clearEvalCache()

@@bool FunctionCodeBlock::canCompileWithDF
21832282
21842283void ProgramCodeBlock::jettison()
21852284{
2186  ASSERT(getJITType() != JITCode::BaselineJIT);
 2285 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21872286 ASSERT(this == replacement());
21882287 static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21892288}
21902289
21912290void EvalCodeBlock::jettison()
21922291{
2193  ASSERT(getJITType() != JITCode::BaselineJIT);
 2292 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21942293 ASSERT(this == replacement());
21952294 static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21962295}
21972296
21982297void FunctionCodeBlock::jettison()
21992298{
2200  ASSERT(getJITType() != JITCode::BaselineJIT);
 2299 ASSERT(JITCode::isOptimizingJIT(getJITType()));
22012300 ASSERT(this == replacement());
22022301 static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
22032302}
 2303
 2304void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2305{
 2306 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2307 ASSERT(this == replacement());
 2308 return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData);
 2309}
 2310
 2311void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2312{
 2313 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2314 ASSERT(this == replacement());
 2315 return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData);
 2316}
 2317
 2318void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2319{
 2320 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2321 ASSERT(this == replacement());
 2322 return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall);
 2323}
22042324#endif
22052325
22062326#if ENABLE(VALUE_PROFILER)

@@void CodeBlock::dumpValueProfiles()
23032423}
23042424#endif
23052425
 2426void CodeBlock::handleBytecodeDiscardingOpportunity()
 2427{
 2428#if !ENABLE(OPCODE_SAMPLING) && !ENABLE(LLINT)
 2429 if (BytecodeGenerator::dumpsGeneratedCode())
 2430 return;
 2431 if (!!alternative())
 2432 discardBytecode();
 2433 else
 2434 discardBytecodeLater();
 2435#endif
 2436}
 2437
23062438#ifndef NDEBUG
23072439bool CodeBlock::usesOpcode(OpcodeID opcodeID)
23082440{
105770

Source/JavaScriptCore/bytecode/CodeBlock.h

3030#ifndef CodeBlock_h
3131#define CodeBlock_h
3232
 33#include "BytecodeConventions.h"
3334#include "CallLinkInfo.h"
3435#include "CallReturnOffsetToBytecodeOffset.h"
3536#include "CodeOrigin.h"

5051#include "JITWriteBarrier.h"
5152#include "JSGlobalObject.h"
5253#include "JumpTable.h"
 54#include "LLIntCallLinkInfo.h"
5355#include "LineInfo.h"
5456#include "Nodes.h"
5557#include "PredictionTracker.h"

6567#include <wtf/Vector.h>
6668#include "StructureStubInfo.h"
6769
68 // Register numbers used in bytecode operations have different meaning according to their ranges:
69 // 0x80000000-0xFFFFFFFF Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
70 // 0x00000000-0x3FFFFFFF Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
71 // 0x40000000-0x7FFFFFFF Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
72 static const int FirstConstantRegisterIndex = 0x40000000;
73 
7470namespace JSC {
7571
76  class ExecState;
7772 class DFGCodeBlocks;
 73 class ExecState;
 74 class LLIntOffsetsExtractor;
7875
7976 inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; }
8077

@@namespace JSC {
8380 class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester {
8481 WTF_MAKE_FAST_ALLOCATED;
8582 friend class JIT;
 83 friend class LLIntOffsetsExtractor;
8684 public:
8785 enum CopyParsedBlockTag { CopyParsedBlock };
8886 protected:

@@namespace JSC {
123121 while (result->alternative())
124122 result = result->alternative();
125123 ASSERT(result);
126  ASSERT(result->getJITType() == JITCode::BaselineJIT);
 124 ASSERT(JITCode::isBaselineCode(result->getJITType()));
127125 return result;
128126 }
129127#endif

@@namespace JSC {
134132
135133 static void dumpStatistics();
136134
137 #if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
138135 void dump(ExecState*) const;
139136 void printStructures(const Instruction*) const;
140137 void printStructure(const char* name, const Instruction*, int operand) const;
141 #endif
142138
143139 bool isStrictMode() const { return m_isStrictMode; }
144140

@@namespace JSC {
194190 return *(binarySearch<MethodCallLinkInfo, unsigned, getMethodCallLinkInfoBytecodeIndex>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), bytecodeIndex));
195191 }
196192
197  unsigned bytecodeOffset(ReturnAddressPtr returnAddress)
198  {
199  if (!m_rareData)
200  return 1;
201  Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
202  if (!callIndices.size())
203  return 1;
204  return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
205  }
 193 unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
206194
207195 unsigned bytecodeOffsetForCallAtIndex(unsigned index)
208196 {

@@namespace JSC {
223211 {
224212 m_incomingCalls.push(incoming);
225213 }
 214#if ENABLE(LLINT)
 215 void linkIncomingCall(LLIntCallLinkInfo* incoming)
 216 {
 217 m_incomingLLIntCalls.push(incoming);
 218 }
 219#endif // ENABLE(LLINT)
226220
227221 void unlinkIncomingCalls();
228 #endif
 222#endif // ENABLE(JIT)
229223
230 #if ENABLE(DFG_JIT)
 224#if ENABLE(DFG_JIT) || ENABLE(LLINT)
231225 void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
232226 {
233227 m_jitCodeMap = jitCodeMap;

@@namespace JSC {
236230 {
237231 return m_jitCodeMap.get();
238232 }
 233#endif
239234
 235#if ENABLE(DFG_JIT)
240236 void createDFGDataIfNecessary()
241237 {
242238 if (!!m_dfgData)

@@namespace JSC {
335331 }
336332#endif
337333
338 #if ENABLE(INTERPRETER)
339334 unsigned bytecodeOffset(Instruction* returnAddress)
340335 {
 336 ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
341337 return static_cast<Instruction*>(returnAddress) - instructions().begin();
342338 }
343 #endif
344339
345340 void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
346341 bool isNumericCompareFunction() { return m_isNumericCompareFunction; }

@@namespace JSC {
354349 {
355350 m_shouldDiscardBytecode = true;
356351 }
357  void handleBytecodeDiscardingOpportunity()
358  {
359  if (!!alternative())
360  discardBytecode();
361  else
362  discardBytecodeLater();
363  }
 352 void handleBytecodeDiscardingOpportunity();
364353
365 #ifndef NDEBUG
366354 bool usesOpcode(OpcodeID);
367 #endif
368355
369356 unsigned instructionCount() { return m_instructionCount; }
370357 void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }

@@namespace JSC {
387374 ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
388375 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
389376 virtual void jettison() = 0;
 377 bool jitCompile(JSGlobalData& globalData)
 378 {
 379 if (getJITType() != JITCode::InterpreterThunk) {
 380 ASSERT(getJITType() == JITCode::BaselineJIT);
 381 return false;
 382 }
 383 jitCompileImpl(globalData);
 384 return true;
 385 }
390386 virtual CodeBlock* replacement() = 0;
391387 virtual bool canCompileWithDFG() = 0;
392388 bool hasOptimizedReplacement()
393389 {
394  ASSERT(getJITType() == JITCode::BaselineJIT);
 390 ASSERT(JITCode::isBaselineCode(getJITType()));
395391 bool result = replacement()->getJITType() > getJITType();
396392#if !ASSERT_DISABLED
397393 if (result)
398394 ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
399395 else {
400  ASSERT(replacement()->getJITType() == JITCode::BaselineJIT);
 396 ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
401397 ASSERT(replacement() == this);
402398 }
403399#endif

@@namespace JSC {
456452
457453 void clearEvalCache();
458454
459 #if ENABLE(INTERPRETER)
460455 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
461456 {
462  if (!m_globalData->canUseJIT())
463  m_propertyAccessInstructions.append(propertyAccessInstruction);
 457 m_propertyAccessInstructions.append(propertyAccessInstruction);
464458 }
465459 void addGlobalResolveInstruction(unsigned globalResolveInstruction)
466460 {
467  if (!m_globalData->canUseJIT())
468  m_globalResolveInstructions.append(globalResolveInstruction);
 461 m_globalResolveInstructions.append(globalResolveInstruction);
469462 }
470463 bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
 464#if ENABLE(LLINT)
 465 LLIntCallLinkInfo* addLLIntCallLinkInfo()
 466 {
 467 m_llintCallLinkInfos.append(LLIntCallLinkInfo());
 468 return &m_llintCallLinkInfos.last();
 469 }
471470#endif
472471#if ENABLE(JIT)
473472 void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }

@@namespace JSC {
476475
477476 void addGlobalResolveInfo(unsigned globalResolveInstruction)
478477 {
479  if (m_globalData->canUseJIT())
480  m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
 478 m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
481479 }
482480 GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
483481 bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);

@@namespace JSC {
488486
489487 void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
490488 MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
 489 size_t numberOfMethodCallLinkInfos() { return m_methodCallLinkInfos.size(); }
491490#endif
492491
493492#if ENABLE(VALUE_PROFILER)

@@namespace JSC {
528527 bytecodeOffset].u.opcode)) - 1].u.profile == result);
529528 return result;
530529 }
 530 PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
 531 {
 532 return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
 533 }
531534
532535 unsigned totalNumberOfValueProfiles()
533536 {

@@namespace JSC {
554557
555558 bool likelyToTakeSlowCase(int bytecodeOffset)
556559 {
 560 if (!numberOfRareCaseProfiles())
 561 return false;
557562 unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
558563 return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
559564 }
560565
561566 bool couldTakeSlowCase(int bytecodeOffset)
562567 {
 568 if (!numberOfRareCaseProfiles())
 569 return false;
563570 unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
564571 return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
565572 }

@@namespace JSC {
578585
579586 bool likelyToTakeSpecialFastCase(int bytecodeOffset)
580587 {
 588 if (!numberOfRareCaseProfiles())
 589 return false;
581590 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
582591 return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
583592 }
584593
585594 bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
586595 {
 596 if (!numberOfRareCaseProfiles())
 597 return false;
587598 unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
588599 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
589600 unsigned value = slowCaseCount - specialFastCaseCount;

@@namespace JSC {
592603
593604 bool likelyToTakeAnySlowCase(int bytecodeOffset)
594605 {
 606 if (!numberOfRareCaseProfiles())
 607 return false;
595608 unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
596609 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
597610 unsigned value = slowCaseCount + specialFastCaseCount;

@@namespace JSC {
677690
678691 bool addFrequentExitSite(const DFG::FrequentExitSite& site)
679692 {
680  ASSERT(getJITType() == JITCode::BaselineJIT);
 693 ASSERT(JITCode::isBaselineCode(getJITType()));
681694 return m_exitProfile.add(site);
682695 }
683696

@@namespace JSC {
782795 void copyPostParseDataFrom(CodeBlock* alternative);
783796 void copyPostParseDataFromAlternative();
784797
 798 // Functions for controlling when JITting kicks in, in a mixed mode
 799 // execution world.
 800
 801 void dontJITAnytimeSoon()
 802 {
 803 m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
 804 }
 805
 806 void jitAfterWarmUp()
 807 {
 808 m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
 809 }
 810
 811 void jitSoon()
 812 {
 813 m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
 814 }
 815
 816 int32_t llintExecuteCounter() const
 817 {
 818 return m_llintExecuteCounter;
 819 }
 820
785821 // Functions for controlling when tiered compilation kicks in. This
786822 // controls both when the optimizing compiler is invoked and when OSR
787823 // entry happens. Two triggers exist: the loop trigger and the return

@@namespace JSC {
9741010 bool m_shouldDiscardBytecode;
9751011
9761012 protected:
 1013 virtual void jitCompileImpl(JSGlobalData&) = 0;
9771014 virtual void visitWeakReferences(SlotVisitor&);
9781015 virtual void finalizeUnconditionally();
9791016

@@namespace JSC {
9861023 void tallyFrequentExitSites() { }
9871024#endif
9881025
989 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
9901026 void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
9911027
9921028 CString registerName(ExecState*, int r) const;

@@namespace JSC {
9961032 void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
9971033 void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
9981034 void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
999 #endif
10001035 void visitStructures(SlotVisitor&, Instruction* vPC) const;
10011036
10021037#if ENABLE(DFG_JIT)

@@namespace JSC {
10571092 RefPtr<SourceProvider> m_source;
10581093 unsigned m_sourceOffset;
10591094
1060 #if ENABLE(INTERPRETER)
10611095 Vector<unsigned> m_propertyAccessInstructions;
10621096 Vector<unsigned> m_globalResolveInstructions;
 1097#if ENABLE(LLINT)
 1098 SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
 1099 SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
10631100#endif
10641101#if ENABLE(JIT)
10651102 Vector<StructureStubInfo> m_structureStubInfos;

@@namespace JSC {
10701107 MacroAssemblerCodePtr m_jitCodeWithArityCheck;
10711108 SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
10721109#endif
1073 #if ENABLE(DFG_JIT)
 1110#if ENABLE(DFG_JIT) || ENABLE(LLINT)
10741111 OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1075 
 1112#endif
 1113#if ENABLE(DFG_JIT)
10761114 struct WeakReferenceTransition {
10771115 WeakReferenceTransition() { }
10781116

@@namespace JSC {
11351173
11361174 OwnPtr<CodeBlock> m_alternative;
11371175
 1176 int32_t m_llintExecuteCounter;
 1177
11381178 int32_t m_jitExecuteCounter;
11391179 uint32_t m_speculativeSuccessCounter;
11401180 uint32_t m_speculativeFailCounter;
11411181 uint8_t m_optimizationDelayCounter;
11421182 uint8_t m_reoptimizationRetryCounter;
1143 
 1183
11441184 struct RareData {
11451185 WTF_MAKE_FAST_ALLOCATED;
11461186 public:

@@namespace JSC {
12131253 protected:
12141254 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12151255 virtual void jettison();
 1256 virtual void jitCompileImpl(JSGlobalData&);
12161257 virtual CodeBlock* replacement();
12171258 virtual bool canCompileWithDFG();
12181259#endif

@@namespace JSC {
12471288 protected:
12481289 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12491290 virtual void jettison();
 1291 virtual void jitCompileImpl(JSGlobalData&);
12501292 virtual CodeBlock* replacement();
12511293 virtual bool canCompileWithDFG();
12521294#endif

@@namespace JSC {
12841326 protected:
12851327 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12861328 virtual void jettison();
 1329 virtual void jitCompileImpl(JSGlobalData&);
12871330 virtual CodeBlock* replacement();
12881331 virtual bool canCompileWithDFG();
12891332#endif
105770

Source/JavaScriptCore/bytecode/GetByIdStatus.cpp

2727#include "GetByIdStatus.h"
2828
2929#include "CodeBlock.h"
 30#include "LowLevelInterpreter.h"
3031
3132namespace JSC {
3233
 34GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
 35{
 36 UNUSED_PARAM(profiledBlock);
 37 UNUSED_PARAM(bytecodeIndex);
 38 UNUSED_PARAM(ident);
 39#if ENABLE(LLINT)
 40 Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
 41
 42 if (instruction[0].u.opcode == llint_op_method_check)
 43 instruction++;
 44
 45 Structure* structure = instruction[4].u.structure.get();
 46 if (!structure)
 47 return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
 48
 49 size_t offset = structure->get(*profiledBlock->globalData(), ident);
 50 if (offset == notFound)
 51 return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
 52
 53 return GetByIdStatus(SimpleDirect, StructureSet(structure), offset, false);
 54#else
 55 return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
 56#endif
 57}
 58
3359GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
3460{
3561 UNUSED_PARAM(profiledBlock);
3662 UNUSED_PARAM(bytecodeIndex);
3763 UNUSED_PARAM(ident);
3864#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
 65 if (!profiledBlock->numberOfStructureStubInfos())
 66 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
 67
3968 // First check if it makes either calls, in which case we want to be super careful, or
4069 // if it's not set at all, in which case we punt.
4170 StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
4271 if (!stubInfo.seen)
43  return GetByIdStatus(NoInformation, StructureSet(), notFound);
 72 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
4473
4574 PolymorphicAccessStructureList* list;
4675 int listSize;

@@GetByIdStatus GetByIdStatus::computeFor(
6089 }
6190 for (int i = 0; i < listSize; ++i) {
6291 if (!list->list[i].isDirect)
63  return GetByIdStatus(MakesCalls, StructureSet(), notFound);
 92 return GetByIdStatus(MakesCalls, StructureSet(), notFound, true);
6493 }
6594
6695 // Next check if it takes slow case, in which case we want to be kind of careful.
6796 if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
68  return GetByIdStatus(TakesSlowPath, StructureSet(), notFound);
 97 return GetByIdStatus(TakesSlowPath, StructureSet(), notFound, true);
6998
7099 // Finally figure out if we can derive an access strategy.
71100 GetByIdStatus result;
 101 result.m_wasSeenInJIT = true;
72102 switch (stubInfo.accessType) {
73103 case access_unset:
74  return GetByIdStatus(NoInformation, StructureSet(), notFound);
 104 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
75105
76106 case access_get_by_id_self: {
77107 Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get();

@@GetByIdStatus GetByIdStatus::computeFor(
130160
131161 return result;
132162#else // ENABLE(JIT)
133  return GetByIdStatus(NoInformation, StructureSet(), notFound);
 163 return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
134164#endif // ENABLE(JIT)
135165}
136166
105770

Source/JavaScriptCore/bytecode/GetByIdStatus.h

@@public:
4949 {
5050 }
5151
52  GetByIdStatus(State state, const StructureSet& structureSet, size_t offset)
 52 GetByIdStatus(State state, const StructureSet& structureSet, size_t offset, bool wasSeenInJIT)
5353 : m_state(state)
5454 , m_structureSet(structureSet)
5555 , m_offset(offset)
 56 , m_wasSeenInJIT(wasSeenInJIT)
5657 {
5758 ASSERT((state == SimpleDirect) == (offset != notFound));
5859 }

@@public:
7071 const StructureSet& structureSet() const { return m_structureSet; }
7172 size_t offset() const { return m_offset; }
7273
 74 bool wasSeenInJIT() const { return m_wasSeenInJIT; }
 75
7376private:
 77 static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
 78
7479 State m_state;
7580 StructureSet m_structureSet;
7681 size_t m_offset;
 82 bool m_wasSeenInJIT;
7783};
7884
7985} // namespace JSC
105770

Source/JavaScriptCore/bytecode/Instruction.h

@@namespace JSC {
4848 class JSCell;
4949 class Structure;
5050 class StructureChain;
 51 struct LLIntCallLinkInfo;
5152 struct ValueProfile;
5253
5354#if ENABLE(JIT)

@@namespace JSC {
146147#endif
147148
148149 struct Instruction {
 150 Instruction()
 151 {
 152 u.jsCell.clear();
 153 }
 154
149155 Instruction(Opcode opcode)
150156 {
151157#if !ENABLE(COMPUTED_GOTO_INTERPRETER)

@@namespace JSC {
182188
183189 Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
184190
 191 Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; }
 192
185193 Instruction(ValueProfile* profile) { u.profile = profile; }
186194
187195 union {

@@namespace JSC {
191199 WriteBarrierBase<StructureChain> structureChain;
192200 WriteBarrierBase<JSCell> jsCell;
193201 PropertySlot::GetValueFunc getterFunc;
 202 LLIntCallLinkInfo* callLinkInfo;
194203 ValueProfile* profile;
 204 void* pointer;
195205 } u;
196206
197207 private:
105770

Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntCallLinkInfo_h
 27#define LLIntCallLinkInfo_h
 28
 29#include "JSFunction.h"
 30#include "MacroAssemblerCodeRef.h"
 31#include <wtf/SentinelLinkedList.h>
 32
 33namespace JSC {
 34
 35struct Instruction;
 36
 37struct LLIntCallLinkInfo : public BasicRawSentinelNode<LLIntCallLinkInfo> {
 38 LLIntCallLinkInfo()
 39 {
 40 }
 41
 42 ~LLIntCallLinkInfo()
 43 {
 44 if (isOnList())
 45 remove();
 46 }
 47
 48 bool isLinked() { return callee; }
 49
 50 void unlink()
 51 {
 52 callee.clear();
 53 machineCodeTarget = MacroAssemblerCodePtr();
 54 if (isOnList())
 55 remove();
 56 }
 57
 58 WriteBarrier<JSFunction> callee;
 59 WriteBarrier<JSFunction> lastSeenCallee;
 60 MacroAssemblerCodePtr machineCodeTarget;
 61};
 62
 63} // namespace JSC
 64
 65#endif // LLIntCallLinkInfo_h
 66
0

Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp

@@MethodCallLinkStatus MethodCallLinkStatu
3535 UNUSED_PARAM(profiledBlock);
3636 UNUSED_PARAM(bytecodeIndex);
3737#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
 38 // NOTE: This does not have an LLInt fall-back because LLInt does not do any method
 39 // call link caching.
 40 if (!profiledBlock->numberOfMethodCallLinkInfos())
 41 return MethodCallLinkStatus();
 42
3843 MethodCallLinkInfo& methodCall = profiledBlock->getMethodCallLinkInfo(bytecodeIndex);
3944
4045 if (!methodCall.seen || !methodCall.cachedStructure)
105770

Source/JavaScriptCore/bytecode/Opcode.h

@@namespace JSC {
123123 macro(op_get_arguments_length, 4) \
124124 macro(op_put_by_id, 9) \
125125 macro(op_put_by_id_transition, 9) \
 126 macro(op_put_by_id_transition_direct, 9) \
 127 macro(op_put_by_id_transition_normal, 9) \
126128 macro(op_put_by_id_replace, 9) \
127129 macro(op_put_by_id_generic, 9) \
128130 macro(op_del_by_id, 4) \

@@namespace JSC {
202204 typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
203205 #undef OPCODE_ID_ENUM
204206
 207 const int maxOpcodeLength = 9;
205208 const int numOpcodeIDs = op_end + 1;
206209
207210 #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;

@@namespace JSC {
218221 FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
219222 #undef VERIFY_OPCODE_ID
220223
221 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 224#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
222225#if COMPILER(RVCT) || COMPILER(INTEL)
223226 typedef void* Opcode;
224227#else
105770

Source/JavaScriptCore/bytecode/PutByIdStatus.cpp

2727#include "PutByIdStatus.h"
2828
2929#include "CodeBlock.h"
 30#include "LowLevelInterpreter.h"
3031#include "Structure.h"
3132#include "StructureChain.h"
3233
3334namespace JSC {
3435
 36PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
 37{
 38 UNUSED_PARAM(profiledBlock);
 39 UNUSED_PARAM(bytecodeIndex);
 40 UNUSED_PARAM(ident);
 41#if ENABLE(LLINT)
 42 Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
 43
 44 Structure* structure = instruction[4].u.structure.get();
 45 if (!structure)
 46 return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 47
 48 if (instruction[0].u.opcode == llint_op_put_by_id) {
 49 size_t offset = structure->get(*profiledBlock->globalData(), ident);
 50 if (offset == notFound)
 51 return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 52
 53 return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
 54 }
 55
 56 ASSERT(instruction[0].u.opcode == llint_op_put_by_id_transition_direct
 57 || instruction[0].u.opcode == llint_op_put_by_id_transition_normal);
 58
 59 Structure* newStructure = instruction[6].u.structure.get();
 60 StructureChain* chain = instruction[7].u.structureChain.get();
 61 ASSERT(newStructure);
 62 ASSERT(chain);
 63
 64 size_t offset = newStructure->get(*profiledBlock->globalData(), ident);
 65 if (offset == notFound)
 66 return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 67
 68 return PutByIdStatus(SimpleTransition, structure, newStructure, chain, offset);
 69#else
 70 return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 71#endif
 72}
 73
3574PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
3675{
3776 UNUSED_PARAM(profiledBlock);
3877 UNUSED_PARAM(bytecodeIndex);
3978 UNUSED_PARAM(ident);
4079#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
 80 if (!profiledBlock->numberOfStructureStubInfos())
 81 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
 82
4183 if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
4284 return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
4385
4486 StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
4587 if (!stubInfo.seen)
46  return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 88 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
4789
4890 switch (stubInfo.accessType) {
4991 case access_unset:
50  return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
 92 return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
5193
5294 case access_put_by_id_replace: {
5395 size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
105770

Source/JavaScriptCore/bytecode/PutByIdStatus.h

@@public:
9393 size_t offset() const { return m_offset; }
9494
9595private:
 96 static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
 97
9698 State m_state;
9799 Structure* m_oldStructure;
98100 Structure* m_newStructure;
105770

Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

3333#include "BatchedTransitionOptimizer.h"
3434#include "JSFunction.h"
3535#include "Interpreter.h"
 36#include "LowLevelInterpreter.h"
3637#include "ScopeChain.h"
3738#include "StrongInlines.h"
3839#include "UString.h"

@@namespace JSC {
116117 expected by the callee.
117118*/
118119
119 #ifndef NDEBUG
120120static bool s_dumpsGeneratedCode = false;
121 #endif
122121
123122void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
124123{
125 #ifndef NDEBUG
126124 s_dumpsGeneratedCode = dumpsGeneratedCode;
127 #else
128  UNUSED_PARAM(dumpsGeneratedCode);
129 #endif
130125}
131126
132127bool BytecodeGenerator::dumpsGeneratedCode()
133128{
134 #ifndef NDEBUG
135129 return s_dumpsGeneratedCode;
136 #else
137  return false;
138 #endif
139130}
140131
141132JSObject* BytecodeGenerator::generate()

@@JSObject* BytecodeGenerator::generate()
148139
149140 m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
150141
151 #ifndef NDEBUG
152142 if (s_dumpsGeneratedCode)
153143 m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
154 #endif
155144
156145 if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
157146 symbolTable().clear();

@@RegisterID* BytecodeGenerator::emitResol
12761265#if ENABLE(JIT)
12771266 m_codeBlock->addGlobalResolveInfo(instructions().size());
12781267#endif
1279 #if ENABLE(INTERPRETER)
12801268 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1281 #endif
12821269 ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
12831270 instructions().append(dst->index());
12841271 instructions().append(addConstant(property));

@@RegisterID* BytecodeGenerator::emitResol
14401427#if ENABLE(JIT)
14411428 m_codeBlock->addGlobalResolveInfo(instructions().size());
14421429#endif
1443 #if ENABLE(INTERPRETER)
14441430 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1445 #endif
14461431 ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
14471432 instructions().append(propDst->index());
14481433 instructions().append(addConstant(property));

@@RegisterID* BytecodeGenerator::emitResol
14901475#if ENABLE(JIT)
14911476 m_codeBlock->addGlobalResolveInfo(instructions().size());
14921477#endif
1493 #if ENABLE(INTERPRETER)
14941478 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1495 #endif
14961479 ValueProfile* profile = emitProfiledOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
14971480 instructions().append(propDst->index());
14981481 instructions().append(addConstant(property));

@@void BytecodeGenerator::emitMethodCheck(
15111494
15121495RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
15131496{
1514 #if ENABLE(INTERPRETER)
15151497 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1516 #endif
15171498
15181499 ValueProfile* profile = emitProfiledOpcode(op_get_by_id);
15191500 instructions().append(dst->index());

@@RegisterID* BytecodeGenerator::emitGetAr
15391520
15401521RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
15411522{
1542 #if ENABLE(INTERPRETER)
15431523 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1544 #endif
15451524
15461525 emitOpcode(op_put_by_id);
15471526 instructions().append(base->index());

@@RegisterID* BytecodeGenerator::emitPutBy
15571536
15581537RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
15591538{
1560 #if ENABLE(INTERPRETER)
15611539 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1562 #endif
15631540
15641541 emitOpcode(op_put_by_id);
15651542 instructions().append(base->index());

@@RegisterID* BytecodeGenerator::emitCall(
18481825 instructions().append(func->index()); // func
18491826 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
18501827 instructions().append(callArguments.registerOffset()); // registerOffset
 1828#if ENABLE(LLINT)
 1829 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1830#else
18511831 instructions().append(0);
 1832#endif
18521833 instructions().append(0);
18531834 if (dst != ignoredResult()) {
18541835 ValueProfile* profile = emitProfiledOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitConst
19521933 instructions().append(func->index()); // func
19531934 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
19541935 instructions().append(callArguments.registerOffset()); // registerOffset
 1936#if ENABLE(LLINT)
 1937 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1938#else
19551939 instructions().append(0);
 1940#endif
19561941 instructions().append(0);
19571942 if (dst != ignoredResult()) {
19581943 ValueProfile* profile = emitProfiledOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitCatch
22132198{
22142199 m_usesExceptions = true;
22152200#if ENABLE(JIT)
 2201#if ENABLE(LLINT)
 2202 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(bitwise_cast<void*>(&llint_op_catch)) };
 2203#else
22162204 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
 2205#endif
22172206#else
22182207 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
22192208#endif
105770

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@private:
604604 {
605605 UNUSED_PARAM(nodeIndex);
606606
607  ValueProfile* profile = m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(bytecodeIndex);
608  ASSERT(profile);
609  PredictedType prediction = profile->computeUpdatedPrediction();
 607 PredictedType prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(bytecodeIndex);
610608#if DFG_ENABLE(DEBUG_VERBOSE)
611609 printf("Dynamic [@%u, bc#%u] prediction: %s\n", nodeIndex, bytecodeIndex, predictionToString(prediction));
612610#endif

@@bool ByteCodeParser::handleInlining(bool
10411039
10421040 // If we get here then it looks like we should definitely inline this code. Proceed
10431041 // with parsing the code to get bytecode, so that we can then parse the bytecode.
 1042 // Note that if LLInt is enabled, the bytecode will always be available. Also note
 1043 // that if LLInt is enabled, we may inline a code block that has never been JITted
 1044 // before!
10441045 CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
10451046 if (!codeBlock)
10461047 return false;

@@bool ByteCodeParser::parseBlock(unsigned
17411742 m_inlineStackTop->m_profiledBlock, m_currentIndex);
17421743
17431744 if (methodCallStatus.isSet()
1744  && !getByIdStatus.isSet()
 1745 && !getByIdStatus.wasSeenInJIT()
17451746 && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
17461747 // It's monomorphic as far as we can tell, since the method_check was linked
17471748 // but the slow path (i.e. the normal get_by_id) never fired.

@@bool ByteCodeParser::parseBlock(unsigned
18101811
18111812 NEXT_OPCODE(op_get_by_id);
18121813 }
1813  case op_put_by_id: {
 1814 case op_put_by_id:
 1815 case op_put_by_id_transition_direct:
 1816 case op_put_by_id_transition_normal: {
18141817 NodeIndex value = get(currentInstruction[3].u.operand);
18151818 NodeIndex base = get(currentInstruction[1].u.operand);
18161819 unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
105770

Source/JavaScriptCore/dfg/DFGCapabilities.h

@@inline bool canCompileOpcode(OpcodeID op
111111 case op_put_scoped_var:
112112 case op_get_by_id:
113113 case op_put_by_id:
 114 case op_put_by_id_transition_direct:
 115 case op_put_by_id_transition_normal:
114116 case op_get_global_var:
115117 case op_put_global_var:
116118 case op_jmp:
105770

Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp

@@void compileOSRExit(ExecState* exec)
4848 uint32_t exitIndex = globalData->osrExitIndex;
4949 OSRExit& exit = codeBlock->osrExit(exitIndex);
5050
 51 // Make sure all code on our inline stack is JIT compiled. This is necessary since
 52 // we may opt to inline a code block even before it had ever been compiled by the
 53 // JIT, but our OSR exit infrastructure currently only works if the target of the
 54 // OSR exit is JIT code. This could be changed since there is nothing particularly
 55 // hard about doing an OSR exit into the interpreter, but for now this seems to make
 56 // sense in that if we're OSR exiting from inlined code of a DFG code block, then
 57 // probably it's a good sign that the thing we're exiting into is hot. Even more
 58 // interestingly, since the code was inlined, it may never otherwise get JIT
 59 // compiled since the act of inlining it may ensure that it otherwise never runs.
 60 for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
 61 static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())
 62 ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)
 63 ->jitCompile(*globalData);
 64 }
 65
5166 SpeculationRecovery* recovery = 0;
5267 if (exit.m_recoveryIndex)
5368 recovery = &codeBlock->speculationRecovery(exit.m_recoveryIndex - 1);
105770

Source/JavaScriptCore/dfg/DFGOperations.cpp

3131#include "CodeBlock.h"
3232#include "DFGOSRExit.h"
3333#include "DFGRepatch.h"
 34#include "HostCallReturnValue.h"
3435#include "GetterSetter.h"
3536#include "InlineASM.h"
3637#include "Interpreter.h"

@@size_t DFG_OPERATION operationCompareStr
561562 return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
562563}
563564
564 EncodedJSValue DFG_OPERATION getHostCallReturnValue();
565 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
566 
567 #if CPU(X86_64)
568 asm (
569 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
570 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
571  "mov -40(%r13), %r13\n"
572  "mov %r13, %rdi\n"
573  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
574 );
575 #elif CPU(X86)
576 asm (
577 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
578 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
579  "mov -40(%edi), %edi\n"
580  "mov %edi, 4(%esp)\n"
581  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
582 );
583 #elif CPU(ARM_THUMB2)
584 asm (
585 ".text" "\n"
586 ".align 2" "\n"
587 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
588 HIDE_SYMBOL(getHostCallReturnValue) "\n"
589 ".thumb" "\n"
590 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
591 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
592  "ldr r5, [r5, #-40]" "\n"
593  "cpy r0, r5" "\n"
594  "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
595 );
596 #endif
597 
598 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
599 {
600  return JSValue::encode(exec->globalData().hostCallReturnValue);
601 }
602 
603565static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
604566{
605567 ExecState* exec = execCallee->callerFrame();
105770

Source/JavaScriptCore/heap/AllocationSpace.h

3434namespace JSC {
3535
3636class Heap;
 37class LLIntOffsetsExtractor;
3738class MarkedBlock;
3839
3940class AllocationSpace {

@@public:
6768 void shrink();
6869
6970private:
 71 friend class LLIntOffsetsExtractor;
 72
7073 enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
7174
7275 void* allocate(MarkedSpace::SizeClass&);
105770

Source/JavaScriptCore/heap/Heap.cpp

@@void Heap::collect(SweepToggle sweepTogg
837837 setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
838838 }
839839 JAVASCRIPTCORE_GC_END();
840 
 840
841841 (*m_activityCallback)();
842842}
843843
105770

Source/JavaScriptCore/heap/Heap.h

@@namespace JSC {
5050 class JSGlobalData;
5151 class JSValue;
5252 class LiveObjectIterator;
 53 class LLIntOffsetsExtractor;
5354 class MarkedArgumentBuffer;
5455 class RegisterFile;
5556 class UString;

@@namespace JSC {
136137 void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
137138
138139 private:
139  friend class MarkedBlock;
140140 friend class AllocationSpace;
 141 friend class CodeBlock;
 142 friend class LLIntOffsetsExtractor;
 143 friend class MarkedBlock;
141144 friend class BumpSpace;
142145 friend class SlotVisitor;
143  friend class CodeBlock;
144146
145147 size_t waterMark();
146148 size_t highWaterMark();
105770

Source/JavaScriptCore/heap/MarkStack.cpp

@@ALWAYS_INLINE static void visitChildren(
304304#endif
305305
306306 ASSERT(Heap::isMarked(cell));
307 
 307
308308 if (isJSString(cell)) {
309309 JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
310310 return;
105770

Source/JavaScriptCore/heap/MarkedSpace.h

@@namespace JSC {
3939class Heap;
4040class JSCell;
4141class LiveObjectIterator;
 42class LLIntOffsetsExtractor;
4243class WeakGCHandle;
4344class SlotVisitor;
4445

@@public:
7778 template<typename Functor> typename Functor::ReturnType forEachBlock();
7879
7980private:
 81 friend class LLIntOffsetsExtractor;
 82
8083 // [ 32... 256 ]
8184 static const size_t preciseStep = MarkedBlock::atomSize;
8285 static const size_t preciseCutoff = 256;
105770

Source/JavaScriptCore/interpreter/CallFrame.h

@@namespace JSC {
119119#if ENABLE(INTERPRETER)
120120 Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
121121#endif
 122#if ENABLE(LLINT)
 123 Instruction* currentVPC() const { return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag()); }
 124#endif
122125
123126 void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
124127 void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
105770

Source/JavaScriptCore/interpreter/Interpreter.cpp

6969#include "JIT.h"
7070#endif
7171
72 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_INTERPRETER) && !defined(__llvm__))
 72#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND ((ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)) && !defined(__llvm__))
7373
7474using namespace std;
7575

@@Interpreter::Interpreter()
547547{
548548}
549549
550 void Interpreter::initialize(bool canUseJIT)
 550Interpreter::~Interpreter()
551551{
552 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 552#if ENABLE(LLINT)
 553 if (m_enabled)
 554 delete[] m_opcodeTable;
 555#endif
 556}
 557
 558void Interpreter::initialize(LLInt::Data* llintData, bool canUseJIT)
 559{
 560 UNUSED_PARAM(llintData);
 561 UNUSED_PARAM(canUseJIT);
 562#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
 563#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
 564 // Having LLInt enabled, but not being able to use the JIT, and not having
 565 // a computed goto interpreter, is not supported. Not because we cannot
 566 // support it, but because I decided to draw the line at the number of
 567 // permutations of execution engines that I wanted this code to grok.
 568 ASSERT(canUseJIT);
 569#endif
553570 if (canUseJIT) {
 571#if ENABLE(LLINT)
 572 m_opcodeTable = llintData->opcodeMap();
 573 for (int i = 0; i < numOpcodeIDs; ++i)
 574 m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
 575#else
554576 // If the JIT is present, don't use jump destinations for opcodes.
555577
556578 for (int i = 0; i < numOpcodeIDs; ++i) {
557579 Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
558580 m_opcodeTable[i] = opcode;
559581 }
 582#endif
560583 } else {
 584#if ENABLE(LLINT)
 585 m_opcodeTable = new Opcode[numOpcodeIDs];
 586#endif
561587 privateExecute(InitializeAndReturn, 0, 0);
562588
563589 for (int i = 0; i < numOpcodeIDs; ++i)

@@void Interpreter::initialize(bool canUse
566592 m_enabled = true;
567593 }
568594#else
569  UNUSED_PARAM(canUseJIT);
570595#if ENABLE(INTERPRETER)
571596 m_enabled = true;
572597#else

@@void Interpreter::dumpRegisters(CallFram
667692
668693bool Interpreter::isOpcode(Opcode opcode)
669694{
670 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 695#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
 696#if !ENABLE(LLINT)
671697 if (!m_enabled)
672698 return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
 699#endif
673700 return opcode != HashTraits<Opcode>::emptyValue()
674701 && !HashTraits<Opcode>::isDeletedValue(opcode)
675702 && m_opcodeIDTable.contains(opcode);

@@NEVER_INLINE bool Interpreter::unwindCal
726753 // have to subtract 1.
727754#if ENABLE(JIT) && ENABLE(INTERPRETER)
728755 if (callerFrame->globalData().canUseJIT())
729  bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
 756 bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
730757 else
731758 bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
732759#elif ENABLE(JIT)
733  bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
 760 bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
734761#else
735762 bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
736763#endif

@@void Interpreter::retrieveLastCaller(Cal
51705197 bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
51715198#if ENABLE(JIT)
51725199 else
5173  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5200 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51745201#endif
51755202#else
5176  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5203 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51775204#endif
51785205 lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
51795206 sourceID = callerCodeBlock->ownerExecutable()->sourceID();
105770

Source/JavaScriptCore/interpreter/Interpreter.h

3333#include "JSCell.h"
3434#include "JSValue.h"
3535#include "JSObject.h"
 36#include "LLIntData.h"
3637#include "Opcode.h"
3738#include "RegisterFile.h"
3839

@@namespace JSC {
4546 class FunctionExecutable;
4647 class JSFunction;
4748 class JSGlobalObject;
 49 class LLIntOffsetsExtractor;
4850 class ProgramExecutable;
4951 class Register;
5052 class ScopeChainNode;

@@namespace JSC {
9092
9193 class Interpreter {
9294 WTF_MAKE_FAST_ALLOCATED;
93  friend class JIT;
9495 friend class CachedCall;
 96 friend class LLIntOffsetsExtractor;
 97 friend class JIT;
9598 public:
9699 Interpreter();
 100 ~Interpreter();
97101
98  void initialize(bool canUseJIT);
 102 void initialize(LLInt::Data*, bool canUseJIT);
99103
100104 RegisterFile& registerFile() { return m_registerFile; }
101105
102106 Opcode getOpcode(OpcodeID id)
103107 {
104108 ASSERT(m_initialized);
105 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 109#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
106110 return m_opcodeTable[id];
107111#else
108112 return id;

@@namespace JSC {
112116 OpcodeID getOpcodeID(Opcode opcode)
113117 {
114118 ASSERT(m_initialized);
115 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 119#if ENABLE(LLINT)
 120 ASSERT(isOpcode(opcode));
 121 return m_opcodeIDTable.get(opcode);
 122#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
116123 ASSERT(isOpcode(opcode));
117124 if (!m_enabled)
118125 return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));

@@namespace JSC {
122129 return opcode;
123130#endif
124131 }
 132
 133 bool enabled()
 134 {
 135 return m_enabled;
 136 }
125137
126138 bool isOpcode(Opcode);
127139

@@namespace JSC {
189201
190202 RegisterFile m_registerFile;
191203
192 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 204#if ENABLE(LLINT)
 205 Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
 206 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
 207#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
193208 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
194209 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
195210#endif
105770

Source/JavaScriptCore/interpreter/RegisterFile.h

@@namespace JSC {
3939
4040 class ConservativeRoots;
4141 class DFGCodeBlocks;
 42 class LLIntOffsetsExtractor;
4243
4344 class RegisterFile {
4445 WTF_MAKE_NONCOPYABLE(RegisterFile);

@@namespace JSC {
8182 }
8283
8384 private:
 85 friend class LLIntOffsetsExtractor;
 86
8487 bool growSlowCase(Register*);
8588 void releaseExcessCapacity();
8689 void addToCommittedByteCount(long);
105770

Source/JavaScriptCore/jit/HostCallReturnValue.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "HostCallReturnValue.h"
 28
 29#include "CallFrame.h"
 30#include "InlineASM.h"
 31#include "JSObject.h"
 32#include "JSValueInlineMethods.h"
 33#include "ScopeChain.h"
 34
 35namespace JSC {
 36
 37extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue();
 38extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*);
 39
 40#if CPU(X86_64)
 41asm (
 42".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 43SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 44 "mov -40(%r13), %r13\n"
 45 "mov %r13, %rdi\n"
 46 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 47);
 48#elif CPU(X86)
 49asm (
 50".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 51SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 52 "mov -40(%edi), %edi\n"
 53 "mov %edi, 4(%esp)\n"
 54 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 55);
 56#elif CPU(ARM_THUMB2)
 57asm (
 58".text" "\n"
 59".align 2" "\n"
 60".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 61HIDE_SYMBOL(getHostCallReturnValue) "\n"
 62".thumb" "\n"
 63".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
 64SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 65 "ldr r5, [r5, #-40]" "\n"
 66 "cpy r0, r5" "\n"
 67 "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 68);
 69#endif
 70
 71extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
 72{
 73 return JSValue::encode(exec->globalData().hostCallReturnValue);
 74}
 75
 76} // namespace JSC
0

Source/JavaScriptCore/jit/HostCallReturnValue.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef HostCallReturnValue_h
 27#define HostCallReturnValue_h
 28
 29#include "JSValue.h"
 30#include "MacroAssemblerCodeRef.h"
 31#include <wtf/Platform.h>
 32
 33#if CALLING_CONVENTION_IS_STDCALL
 34#define HOST_CALL_RETURN_VALUE_OPTION CDECL
 35#else
 36#define HOST_CALL_RETURN_VALUE_OPTION
 37#endif
 38
 39namespace JSC {
 40extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue();
 41}
 42
 43#endif // HostCallReturnValue_h
 44
0

Source/JavaScriptCore/jit/JIT.cpp

@@void JIT::privateCompileMainPass()
325325 DEFINE_OP(op_profile_will_call)
326326 DEFINE_OP(op_push_new_scope)
327327 DEFINE_OP(op_push_scope)
 328 case op_put_by_id_transition_direct:
 329 case op_put_by_id_transition_normal:
328330 DEFINE_OP(op_put_by_id)
329331 DEFINE_OP(op_put_by_index)
330332 DEFINE_OP(op_put_by_val)

@@void JIT::privateCompileSlowCases()
487489 DEFINE_SLOWCASE_OP(op_post_inc)
488490 DEFINE_SLOWCASE_OP(op_pre_dec)
489491 DEFINE_SLOWCASE_OP(op_pre_inc)
 492 case op_put_by_id_transition_direct:
 493 case op_put_by_id_transition_normal:
490494 DEFINE_SLOWCASE_OP(op_put_by_id)
491495 DEFINE_SLOWCASE_OP(op_put_by_val)
492496 DEFINE_SLOWCASE_OP(op_resolve_global)

@@void JIT::privateCompileSlowCases()
526530
527531JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
528532{
 533#if ENABLE(JIT_VERBOSE_OSR)
 534 printf("Compiling JIT code!\n");
 535#endif
 536
529537#if ENABLE(VALUE_PROFILER)
530538 m_canBeOptimized = m_codeBlock->canCompileWithDFG();
531539#endif

@@JITCode JIT::privateCompile(CodePtr* fun
690698 info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
691699 }
692700
693 #if ENABLE(DFG_JIT)
694  if (m_canBeOptimized) {
 701#if ENABLE(DFG_JIT) || ENABLE(LLINT)
 702 if (m_canBeOptimized
 703#if ENABLE(LLINT)
 704 || true
 705#endif
 706 ) {
695707 CompactJITCodeMap::Encoder jitCodeMapEncoder;
696708 for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
697709 if (m_labels[bytecodeOffset].isSet())
105770

Source/JavaScriptCore/jit/JITCode.h

@@namespace JSC {
4848 JITCode() { }
4949#endif
5050 public:
51  enum JITType { HostCallThunk, BaselineJIT, DFGJIT };
 51 enum JITType { None, HostCallThunk, InterpreterThunk, BaselineJIT, DFGJIT };
5252
5353 static JITType bottomTierJIT()
5454 {

@@namespace JSC {
6666 return DFGJIT;
6767 }
6868
 69 static bool isOptimizingJIT(JITType jitType)
 70 {
 71 return jitType == DFGJIT;
 72 }
 73
 74 static bool isBaselineCode(JITType jitType)
 75 {
 76 return jitType == InterpreterThunk || jitType == BaselineJIT;
 77 }
 78
6979#if ENABLE(JIT)
7080 JITCode()
 81 : m_jitType(None)
7182 {
7283 }
7384

@@namespace JSC {
7586 : m_ref(ref)
7687 , m_jitType(jitType)
7788 {
 89 ASSERT(jitType != None);
7890 }
7991
8092 bool operator !() const
105770

Source/JavaScriptCore/jit/JITDriver.h

3333#include "BytecodeGenerator.h"
3434#include "DFGDriver.h"
3535#include "JIT.h"
 36#include "LLIntEntrypoints.h"
3637
3738namespace JSC {
3839
3940template<typename CodeBlockType>
4041inline bool jitCompileIfAppropriate(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
4142{
 43 if (jitType == codeBlock->getJITType())
 44 return true;
 45
4246 if (!globalData.canUseJIT())
4347 return true;
4448
 49 codeBlock->unlinkIncomingCalls();
 50
4551 bool dfgCompiled = false;
4652 if (jitType == JITCode::DFGJIT)
4753 dfgCompiled = DFG::tryCompile(globalData, codeBlock.get(), jitCode);

@@inline bool jitCompileIfAppropriate(JSGl
5561 }
5662 jitCode = JIT::compile(&globalData, codeBlock.get());
5763 }
58 #if !ENABLE(OPCODE_SAMPLING)
59  if (!BytecodeGenerator::dumpsGeneratedCode())
60  codeBlock->handleBytecodeDiscardingOpportunity();
61 #endif
 64 codeBlock->handleBytecodeDiscardingOpportunity();
6265 codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
6366
6467 return true;

@@inline bool jitCompileIfAppropriate(JSGl
6669
6770inline bool jitCompileFunctionIfAppropriate(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
6871{
 72 if (jitType == codeBlock->getJITType())
 73 return true;
 74
6975 if (!globalData.canUseJIT())
7076 return true;
7177
 78 codeBlock->unlinkIncomingCalls();
 79
7280 bool dfgCompiled = false;
7381 if (jitType == JITCode::DFGJIT)
7482 dfgCompiled = DFG::tryCompileFunction(globalData, codeBlock.get(), jitCode, jitCodeWithArityCheck);

@@inline bool jitCompileFunctionIfAppropri
8391 }
8492 jitCode = JIT::compile(&globalData, codeBlock.get(), &jitCodeWithArityCheck);
8593 }
86 #if !ENABLE(OPCODE_SAMPLING)
87  if (!BytecodeGenerator::dumpsGeneratedCode())
88  codeBlock->handleBytecodeDiscardingOpportunity();
89 #endif
90 
 94 codeBlock->handleBytecodeDiscardingOpportunity();
9195 codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
9296
9397 return true;
105770

Source/JavaScriptCore/jit/JITExceptions.cpp

@@ExceptionHandler genericThrow(JSGlobalDa
6464
6565ExceptionHandler jitThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
6666{
67  return genericThrow(globalData, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(faultLocation));
 67 return genericThrow(globalData, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation));
6868}
6969
7070}
105770

Source/JavaScriptCore/jit/JITStubs.cpp

@@DEFINE_STUB_FUNCTION(void, optimize_from
19131913 unsigned bytecodeIndex = stackFrame.args[0].int32();
19141914
19151915#if ENABLE(JIT_VERBOSE_OSR)
1916  printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
 1916 printf("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
19171917#endif
19181918
19191919 if (codeBlock->hasOptimizedReplacement()) {

@@DEFINE_STUB_FUNCTION(void*, op_construct
21682168 return result;
21692169}
21702170
2171 inline CallFrame* arityCheckFor(CallFrame* callFrame, RegisterFile* registerFile, CodeSpecializationKind kind)
2172 {
2173  JSFunction* callee = asFunction(callFrame->callee());
2174  ASSERT(!callee->isHostFunction());
2175  CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
2176  int argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
2177 
2178  // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
2179  if (!registerFile->grow(callFrame->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
2180  return 0;
2181 
2182  ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
2183 
2184  // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
2185  size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
2186  Register* src = callFrame->registers();
2187  Register* dst = callFrame->registers() + delta;
2188 
2189  int i;
2190  int end = -CallFrame::offsetFor(argumentCountIncludingThis);
2191  for (i = -1; i >= end; --i)
2192  dst[i] = src[i];
2193 
2194  end -= delta;
2195  for ( ; i >= end; --i)
2196  dst[i] = jsUndefined();
2197 
2198  CallFrame* newCallFrame = CallFrame::create(dst);
2199  ASSERT((void*)newCallFrame <= registerFile->end());
2200  return newCallFrame;
2201 }
2202 
22032171DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
22042172{
22052173 STUB_INIT_STACK_FRAME(stackFrame);
22062174
22072175 CallFrame* callFrame = stackFrame.callFrame;
22082176
2209  CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
 2177 CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
22102178 if (!newCallFrame)
22112179 return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
22122180

@@DEFINE_STUB_FUNCTION(void*, op_construct
22192187
22202188 CallFrame* callFrame = stackFrame.callFrame;
22212189
2222  CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
 2190 CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
22232191 if (!newCallFrame)
22242192 return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
22252193
105770

Source/JavaScriptCore/jit/JSInterfaceJIT.h

2626#ifndef JSInterfaceJIT_h
2727#define JSInterfaceJIT_h
2828
 29#include "BytecodeConventions.h"
2930#include "JITCode.h"
3031#include "JITStubs.h"
 32#include "JSString.h"
3133#include "JSValue.h"
3234#include "MacroAssembler.h"
3335#include "RegisterFile.h"
105770

Source/JavaScriptCore/llint/LLIntCommon.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntCommon_h
 27#define LLIntCommon_h
 28
 29#define LLINT_EXECUTION_TRACING 0
 30#define LLINT_HELPER_TRACING 0
 31
 32#endif // LLIntCommon_h
 33
0

Source/JavaScriptCore/llint/LLIntData.cpp

 1/*
 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LLIntData.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "Instruction.h"
 32#include "LowLevelInterpreter.h"
 33#include "Opcode.h"
 34
 35namespace JSC { namespace LLInt {
 36
 37Data::Data()
 38 : m_exceptionInstructions(new Instruction[maxOpcodeLength + 1])
 39 , m_opcodeMap(new Opcode[numOpcodeIDs])
 40{
 41 for (int i = 0; i < maxOpcodeLength + 1; ++i)
 42 m_exceptionInstructions[i].u.pointer = bitwise_cast<void*>(&llint_throw_from_helper_trampoline);
 43#define OPCODE_ENTRY(opcode, length) m_opcodeMap[opcode] = bitwise_cast<void*>(&llint_##opcode);
 44 FOR_EACH_OPCODE_ID(OPCODE_ENTRY);
 45#undef OPCODE_ENTRY
 46}
 47
 48Data::~Data()
 49{
 50 delete[] m_exceptionInstructions;
 51 delete[] m_opcodeMap;
 52}
 53
 54} } // namespace JSC::LLInt
 55
 56#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LLIntData.h

 1/*
 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntData_h
 27#define LLIntData_h
 28
 29#include "Opcode.h"
 30#include <wtf/Platform.h>
 31
 32namespace JSC {
 33
 34struct Instruction;
 35
 36namespace LLInt {
 37
 38#if ENABLE(LLINT)
 39class Data {
 40public:
 41 Data();
 42 ~Data();
 43
 44 Instruction* exceptionInstructions()
 45 {
 46 return m_exceptionInstructions;
 47 }
 48
 49 Opcode* opcodeMap()
 50 {
 51 return m_opcodeMap;
 52 }
 53private:
 54 Instruction* m_exceptionInstructions;
 55 Opcode* m_opcodeMap;
 56};
 57#else // ENABLE(LLINT)
 58
 59#if COMPILER(CLANG)
 60#pragma clang diagnostic push
 61#pragma clang diagnostic ignored "-Wmissing-noreturn"
 62#endif
 63
 64class Data {
 65public:
 66 Instruction* exceptionInstructions()
 67 {
 68 ASSERT_NOT_REACHED();
 69 return 0;
 70 }
 71
 72 Opcode* opcodeMap()
 73 {
 74 ASSERT_NOT_REACHED();
 75 return 0;
 76 }
 77};
 78
 79#if COMPILER(CLANG)
 80#pragma clang diagnostic pop
 81#endif
 82
 83#endif // ENABLE(LLINT)
 84
 85} } // namespace JSC::LLInt
 86
 87#endif // LLIntData_h
 88
0

Source/JavaScriptCore/llint/LLIntEntrypoints.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LLIntEntrypoints.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "JITCode.h"
 32#include "JSGlobalData.h"
 33#include "LLIntThunks.h"
 34#include "LowLevelInterpreter.h"
 35
 36namespace JSC { namespace LLInt {
 37
 38void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind, JITCode& jitCode, MacroAssemblerCodePtr& arityCheck)
 39{
 40 if (!globalData.canUseJIT()) {
 41 if (kind == CodeForCall) {
 42 jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_prologue))));
 43 arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_arity_check));
 44 return;
 45 }
 46
 47 ASSERT(kind == CodeForConstruct);
 48 jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_prologue))));
 49 arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_arity_check));
 50 return;
 51 }
 52
 53 if (kind == CodeForCall) {
 54 jitCode = JITCode(globalData.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk);
 55 arityCheck = globalData.getCTIStub(functionForCallArityCheckThunkGenerator).code();
 56 return;
 57 }
 58
 59 ASSERT(kind == CodeForConstruct);
 60 jitCode = JITCode(globalData.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk);
 61 arityCheck = globalData.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
 62}
 63
 64void getEvalEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
 65{
 66 if (!globalData.canUseJIT()) {
 67 jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_eval_prologue))));
 68 return;
 69 }
 70
 71 jitCode = JITCode(globalData.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk);
 72}
 73
 74void getProgramEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
 75{
 76 if (!globalData.canUseJIT()) {
 77 jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_program_prologue))));
 78 return;
 79 }
 80
 81 jitCode = JITCode(globalData.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk);
 82}
 83
 84} } // namespace JSC::LLInt
 85
 86#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LLIntEntrypoints.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntEntrypoints_h
 27#define LLIntEntrypoints_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(LLINT)
 32
 33#include "CodeSpecializationKind.h"
 34
 35namespace JSC {
 36
 37class EvalCodeBlock;
 38class JITCode;
 39class JSGlobalData;
 40class MacroAssemblerCodePtr;
 41class MacroAssemblerCodeRef;
 42class ProgramCodeBlock;
 43
 44namespace LLInt {
 45
 46void getFunctionEntrypoint(JSGlobalData&, CodeSpecializationKind, JITCode&, MacroAssemblerCodePtr& arityCheck);
 47void getEvalEntrypoint(JSGlobalData&, JITCode&);
 48void getProgramEntrypoint(JSGlobalData&, JITCode&);
 49
 50inline void getEntrypoint(JSGlobalData& globalData, EvalCodeBlock*, JITCode& jitCode)
 51{
 52 getEvalEntrypoint(globalData, jitCode);
 53}
 54
 55inline void getEntrypoint(JSGlobalData& globalData, ProgramCodeBlock*, JITCode& jitCode)
 56{
 57 getProgramEntrypoint(globalData, jitCode);
 58}
 59
 60} } // namespace JSC::LLInt
 61
 62#endif // ENABLE(LLINT)
 63
 64#endif // LLIntEntrypoints_h
0

Source/JavaScriptCore/llint/LLIntExceptions.cpp

 1/*
 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LLIntExceptions.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "CallFrame.h"
 32#include "CodeBlock.h"
 33#include "Instruction.h"
 34#include "JITExceptions.h"
 35#include "LLIntCommon.h"
 36#include "LowLevelInterpreter.h"
 37
 38namespace JSC { namespace LLInt {
 39
 40void interpreterThrowInCaller(ExecState* exec)
 41{
 42 JSGlobalData* globalData = &exec->globalData();
 43#if LLINT_HELPER_TRACING
 44 printf("Throwing exception %s.\n", globalData->exception.description());
 45#endif
 46 genericThrow(
 47 globalData, exec->callerFrame(), globalData->exception,
 48 exec->callerFrame()->codeBlock()->bytecodeOffset(exec->callerFrame(), exec->returnPC()));
 49}
 50
 51Instruction* returnToThrowForThrownException(ExecState* exec)
 52{
 53 return exec->globalData().llintData.exceptionInstructions();
 54}
 55
 56Instruction* returnToThrow(ExecState* exec, Instruction* pc)
 57{
 58 JSGlobalData* globalData = &exec->globalData();
 59#if LLINT_HELPER_TRACING
 60 printf("Throwing exception %s (returnToThrow).\n", globalData->exception.description());
 61#endif
 62 genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
 63
 64 return globalData->llintData.exceptionInstructions();
 65}
 66
 67void* callToThrow(ExecState* exec, Instruction* pc)
 68{
 69 JSGlobalData* globalData = &exec->globalData();
 70#if LLINT_HELPER_TRACING
 71 printf("Throwing exception %s (callToThrow).\n", globalData->exception.description());
 72#endif
 73 genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
 74
 75 return bitwise_cast<void*>(&llint_throw_during_call_trampoline);
 76}
 77
 78} } // namespace JSC::LLInt
 79
 80#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LLIntExceptions.h

 1/*
 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntExceptions_h
 27#define LLIntExceptions_h
 28
 29#include <wtf/Platform.h>
 30#include <wtf/StdLibExtras.h>
 31
 32#if ENABLE(LLINT)
 33
 34namespace JSC {
 35
 36class ExecState;
 37struct Instruction;
 38
 39namespace LLInt {
 40
 41// Throw the currently active exception in the context of the caller's call frame.
 42void interpreterThrowInCaller(ExecState*);
 43
 44// Tells you where to jump to if you want to return-to-throw, after you've already
 45// set up all information needed to throw the exception.
 46Instruction* returnToThrowForThrownException(ExecState*);
 47
 48// Saves the current PC in the global data for safe-keeping, and gives you a PC
 49// that you can tell the interpreter to go to, which when advanced between 1
 50// and 9 slots will give you an "instruction" that threads to the interpreter's
 51// exception handler. Note that if you give it the PC for exception handling,
 52// it's smart enough to just return that PC without doing anything else; this
 53// lets you thread exception handling through common helper functions used by
 54// other helpers.
 55Instruction* returnToThrow(ExecState*, Instruction*);
 56
 57// Use this when you're throwing to a call thunk.
 58void* callToThrow(ExecState*, Instruction*);
 59
 60} } // namespace JSC::LLInt
 61
 62#endif // ENABLE(LLINT)
 63
 64#endif // LLIntExceptions_h
0

Source/JavaScriptCore/llint/LLIntHelpers.cpp

 1/*
 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LLIntHelpers.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "Arguments.h"
 32#include "CallFrame.h"
 33#include "CommonSlowPaths.h"
 34#include "HostCallReturnValue.h"
 35#include "Interpreter.h"
 36#include "JIT.h"
 37#include "JITDriver.h"
 38#include "JSActivation.h"
 39#include "JSByteArray.h"
 40#include "JSGlobalObjectFunctions.h"
 41#include "JSPropertyNameIterator.h"
 42#include "JSStaticScopeObject.h"
 43#include "JSString.h"
 44#include "JSValue.h"
 45#include "LLIntCommon.h"
 46#include "LLIntExceptions.h"
 47#include "LowLevelInterpreter.h"
 48#include "Operations.h"
 49
 50namespace JSC { namespace LLInt {
 51
 52#define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
 53#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
 54
 55#define LLINT_RETURN_TWO(first, second) do { \
 56 union { \
 57 struct { \
 58 void* a; \
 59 void* b; \
 60 } pair; \
 61 int64_t i; \
 62 } __rt_u; \
 63 __rt_u.pair.a = first; \
 64 __rt_u.pair.b = second; \
 65 return __rt_u.i; \
 66 } while (false)
 67
 68#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
 69
 70#define LLINT_THROW(exceptionToThrow) do { \
 71 JSGlobalData& __t_globalData = exec->globalData(); \
 72 __t_globalData.exception = (exceptionToThrow); \
 73 pc = returnToThrow(exec, pc); \
 74 LLINT_END_IMPL(); \
 75 } while (false)
 76
 77#define LLINT_CHECK_EXCEPTION() do { \
 78 if (UNLIKELY(exec->globalData().exception)) { \
 79 pc = returnToThrow(exec, pc); \
 80 LLINT_END_IMPL(); \
 81 } \
 82 } while (false)
 83
 84#define LLINT_END() do { \
 85 LLINT_CHECK_EXCEPTION(); \
 86 LLINT_END_IMPL(); \
 87 } while (false)
 88
 89#define LLINT_BRANCH(opcode, condition) do { \
 90 bool __b_condition = (condition); \
 91 LLINT_CHECK_EXCEPTION(); \
 92 if (__b_condition) \
 93 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
 94 else \
 95 pc += OPCODE_LENGTH(opcode); \
 96 LLINT_END_IMPL(); \
 97 } while (false)
 98
 99#define LLINT_RETURN(value) do { \
 100 JSValue __r_returnValue = (value); \
 101 LLINT_CHECK_EXCEPTION(); \
 102 LLINT_OP(1) = __r_returnValue; \
 103 LLINT_END_IMPL(); \
 104 } while (false)
 105
 106#define LLINT_RETURN_PROFILED(opcode, value) do { \
 107 JSValue __rp_returnValue = (value); \
 108 LLINT_CHECK_EXCEPTION(); \
 109 LLINT_OP(1) = __rp_returnValue; \
 110 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
 111 JSValue::encode(__rp_returnValue); \
 112 LLINT_END_IMPL(); \
 113 } while (false)
 114
 115#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
 116
 117#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
 118 ExecState* __ct_exec = (exec); \
 119 Instruction* __ct_pc = (pc); \
 120 JSGlobalData& __ct_globalData = (__ct_exec)->globalData(); \
 121 __ct_globalData.exception = (exceptionToThrow); \
 122 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
 123 } while (false)
 124
 125#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
 126 ExecState* __cce_exec = (exec); \
 127 Instruction* __cce_pc = (pc); \
 128 if (UNLIKELY(__cce_exec->globalData().exception)) \
 129 LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
 130 } while (false)
 131
 132#define LLINT_CALL_RETURN(exec, pc, callTarget) do { \
 133 ExecState* __cr_exec = (exec); \
 134 Instruction* __cr_pc = (pc); \
 135 void* __cr_callTarget = (callTarget); \
 136 LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc); \
 137 LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget); \
 138 } while (false)
 139
 140extern "C" HelperReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 141{
 142 printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
 143 exec->codeBlock(),
 144 exec,
 145 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 146 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 147 fromWhere,
 148 operand,
 149 pc[operand].u.operand);
 150 LLINT_END();
 151}
 152
 153extern "C" HelperReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 154{
 155 JSValue value = LLINT_OP_C(operand).jsValue();
 156 union {
 157 struct {
 158 uint32_t tag;
 159 uint32_t payload;
 160 } bits;
 161 EncodedJSValue asValue;
 162 } u;
 163 u.asValue = JSValue::encode(value);
 164 printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x",
 165 exec->codeBlock(),
 166 exec,
 167 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 168 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 169 fromWhere,
 170 operand,
 171 pc[operand].u.operand,
 172 u.bits.tag,
 173 u.bits.payload);
 174#ifndef NDEBUG
 175 printf(": %s", value.description());
 176#endif
 177 printf("\n");
 178 LLINT_END();
 179}
 180
 181LLINT_HELPER_DECL(trace_prologue)
 182{
 183 printf("%p / %p: in prologue.\n", exec->codeBlock(), exec);
 184 LLINT_END();
 185}
 186
 187static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
 188{
 189 JSFunction* callee = asFunction(exec->callee());
 190 FunctionExecutable* executable = callee->jsExecutable();
 191 CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
 192 printf("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u.\n",
 193 codeBlock, exec, comment, callee, executable,
 194 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters);
 195}
 196
 197LLINT_HELPER_DECL(trace_prologue_function_for_call)
 198{
 199 traceFunctionPrologue(exec, "call prologue", CodeForCall);
 200 LLINT_END();
 201}
 202
 203LLINT_HELPER_DECL(trace_prologue_function_for_construct)
 204{
 205 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
 206 LLINT_END();
 207}
 208
 209LLINT_HELPER_DECL(trace_arityCheck_for_call)
 210{
 211 traceFunctionPrologue(exec, "call arity check", CodeForCall);
 212 LLINT_END();
 213}
 214
 215LLINT_HELPER_DECL(trace_arityCheck_for_construct)
 216{
 217 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
 218 LLINT_END();
 219}
 220
 221LLINT_HELPER_DECL(trace)
 222{
 223 printf("%p / %p: executing bc#%zu, ",
 224 exec->codeBlock(),
 225 exec,
 226 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()));
 227#ifndef NDEBUG
 228 printf("%s, ", opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)]);
 229#else
 230 printf("op#%u, ", exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode));
 231#endif
 232 printf("scope %p\n", exec->scopeChain());
 233 LLINT_END();
 234}
 235
 236LLINT_HELPER_DECL(special_trace)
 237{
 238 printf("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
 239 exec->codeBlock(),
 240 exec,
 241 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 242 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 243 exec->returnPC().value());
 244 LLINT_END();
 245}
 246
 247inline bool shouldJIT(ExecState* exec)
 248{
 249 // You can modify this to turn off JITting without rebuilding the world.
 250 return exec->globalData().canUseJIT();
 251}
 252
 253enum EntryKind { Prologue, ArityCheck };
 254static HelperReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
 255{
 256#if ENABLE(JIT_VERBOSE_OSR)
 257 printf("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter());
 258#endif
 259
 260 if (!shouldJIT(exec)) {
 261 codeBlock->dontJITAnytimeSoon();
 262 LLINT_RETURN_TWO(0, exec);
 263 }
 264 if (!codeBlock->jitCompile(exec->globalData())) {
 265#if ENABLE(JIT_VERBOSE_OSR)
 266 printf(" Code was already compiled.\n");
 267#endif
 268 }
 269 codeBlock->jitSoon();
 270 if (kind == Prologue)
 271 LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
 272 ASSERT(kind == ArityCheck);
 273 LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
 274}
 275
 276LLINT_HELPER_DECL(entry_osr)
 277{
 278 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
 279}
 280
 281LLINT_HELPER_DECL(entry_osr_function_for_call)
 282{
 283 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
 284}
 285
 286LLINT_HELPER_DECL(entry_osr_function_for_construct)
 287{
 288 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
 289}
 290
 291LLINT_HELPER_DECL(entry_osr_function_for_call_arityCheck)
 292{
 293 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
 294}
 295
 296LLINT_HELPER_DECL(entry_osr_function_for_construct_arityCheck)
 297{
 298 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
 299}
 300
 301LLINT_HELPER_DECL(loop_osr)
 302{
 303 CodeBlock* codeBlock = exec->codeBlock();
 304
 305#if ENABLE(JIT_VERBOSE_OSR)
 306 printf("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
 307#endif
 308
 309 if (!shouldJIT(exec)) {
 310 codeBlock->dontJITAnytimeSoon();
 311 LLINT_RETURN_TWO(0, exec);
 312 }
 313
 314 if (!codeBlock->jitCompile(exec->globalData())) {
 315#if ENABLE(JIT_VERBOSE_OSR)
 316 printf(" Code was already compiled.\n");
 317#endif
 318 }
 319 codeBlock->jitSoon();
 320
 321 ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
 322
 323 Vector<BytecodeAndMachineOffset> map;
 324 codeBlock->jitCodeMap()->decode(map);
 325 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
 326 ASSERT(mapping);
 327 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
 328
 329 void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
 330 ASSERT(jumpTarget);
 331
 332 LLINT_RETURN_TWO(jumpTarget, exec);
 333}
 334
 335LLINT_HELPER_DECL(replace)
 336{
 337 CodeBlock* codeBlock = exec->codeBlock();
 338
 339#if ENABLE(JIT_VERBOSE_OSR)
 340 printf("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
 341#endif
 342
 343 if (shouldJIT(exec)) {
 344 if (!codeBlock->jitCompile(exec->globalData())) {
 345#if ENABLE(JIT_VERBOSE_OSR)
 346 printf(" Code was already compiled.\n");
 347#endif
 348 }
 349 codeBlock->jitSoon();
 350 } else
 351 codeBlock->dontJITAnytimeSoon();
 352 LLINT_END();
 353}
 354
 355LLINT_HELPER_DECL(register_file_check)
 356{
 357#if LLINT_HELPER_TRACING
 358 printf("Checking stack height with exec = %p.\n", exec);
 359 printf("CodeBlock = %p.\n", exec->codeBlock());
 360 printf("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
 361 printf("Num vars = %u.\n", exec->codeBlock()->m_numVars);
 362 printf("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end());
 363#endif
 364 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end());
 365 if (UNLIKELY(!exec->globalData().interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
 366 exec = exec->callerFrame();
 367 exec->globalData().exception = createStackOverflowError(exec);
 368 interpreterThrowInCaller(exec);
 369 pc = returnToThrowForThrownException(exec);
 370 }
 371 LLINT_END_IMPL();
 372}
 373
 374LLINT_HELPER_DECL(helper_call_arityCheck)
 375{
 376 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForCall);
 377 if (!newExec) {
 378 exec = exec->callerFrame();
 379 exec->globalData().exception = createStackOverflowError(exec);
 380 interpreterThrowInCaller(exec);
 381 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
 382 }
 383 LLINT_RETURN_TWO(0, newExec);
 384}
 385
 386LLINT_HELPER_DECL(helper_construct_arityCheck)
 387{
 388 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForConstruct);
 389 if (!newExec) {
 390 exec = exec->callerFrame();
 391 exec->globalData().exception = createStackOverflowError(exec);
 392 interpreterThrowInCaller(exec);
 393 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
 394 }
 395 LLINT_RETURN_TWO(0, newExec);
 396}
 397
 398LLINT_HELPER_DECL(helper_create_activation)
 399{
 400#if LLINT_HELPER_TRACING
 401 printf("Creating an activation, exec = %p!\n", exec);
 402#endif
 403 JSActivation* activation = JSActivation::create(exec->globalData(), exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
 404 exec->setScopeChain(exec->scopeChain()->push(activation));
 405 LLINT_RETURN(JSValue(activation));
 406}
 407
 408LLINT_HELPER_DECL(helper_create_arguments)
 409{
 410 JSValue arguments = JSValue(Arguments::create(exec->globalData(), exec));
 411 LLINT_CHECK_EXCEPTION();
 412 exec->uncheckedR(pc[1].u.operand) = arguments;
 413 exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
 414 LLINT_END();
 415}
 416
 417LLINT_HELPER_DECL(helper_create_this)
 418{
 419 JSFunction* constructor = asFunction(exec->callee());
 420
 421#if !ASSERT_DISABLED
 422 ConstructData constructData;
 423 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
 424#endif
 425
 426 Structure* structure;
 427 JSValue proto = LLINT_OP(2).jsValue();
 428 if (proto.isObject())
 429 structure = asObject(proto)->inheritorID(exec->globalData());
 430 else
 431 structure = constructor->scope()->globalObject->emptyObjectStructure();
 432
 433 LLINT_RETURN(constructEmptyObject(exec, structure));
 434}
 435
 436LLINT_HELPER_DECL(helper_convert_this)
 437{
 438 JSValue v1 = LLINT_OP(1).jsValue();
 439 ASSERT(v1.isPrimitive());
 440 LLINT_RETURN(v1.toThisObject(exec));
 441}
 442
 443LLINT_HELPER_DECL(helper_new_object)
 444{
 445 LLINT_RETURN(constructEmptyObject(exec));
 446}
 447
 448LLINT_HELPER_DECL(helper_new_array)
 449{
 450 LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
 451}
 452
 453LLINT_HELPER_DECL(helper_new_array_buffer)
 454{
 455 LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
 456}
 457
 458LLINT_HELPER_DECL(helper_new_regexp)
 459{
 460 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
 461 if (!regExp->isValid())
 462 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
 463 LLINT_RETURN(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
 464}
 465
 466LLINT_HELPER_DECL(helper_not)
 467{
 468 LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
 469}
 470
 471LLINT_HELPER_DECL(helper_eq)
 472{
 473 LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 474}
 475
 476LLINT_HELPER_DECL(helper_neq)
 477{
 478 LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 479}
 480
 481LLINT_HELPER_DECL(helper_stricteq)
 482{
 483 LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 484}
 485
 486LLINT_HELPER_DECL(helper_nstricteq)
 487{
 488 LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 489}
 490
 491LLINT_HELPER_DECL(helper_less)
 492{
 493 LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 494}
 495
 496LLINT_HELPER_DECL(helper_lesseq)
 497{
 498 LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 499}
 500
 501LLINT_HELPER_DECL(helper_greater)
 502{
 503 LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
 504}
 505
 506LLINT_HELPER_DECL(helper_greatereq)
 507{
 508 LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
 509}
 510
 511LLINT_HELPER_DECL(helper_pre_inc)
 512{
 513 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
 514}
 515
 516LLINT_HELPER_DECL(helper_pre_dec)
 517{
 518 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
 519}
 520
 521LLINT_HELPER_DECL(helper_post_inc)
 522{
 523 double result = LLINT_OP(2).jsValue().toNumber(exec);
 524 LLINT_OP(2) = jsNumber(result + 1);
 525 LLINT_RETURN(jsNumber(result));
 526}
 527
 528LLINT_HELPER_DECL(helper_post_dec)
 529{
 530 double result = LLINT_OP(2).jsValue().toNumber(exec);
 531 LLINT_OP(2) = jsNumber(result - 1);
 532 LLINT_RETURN(jsNumber(result));
 533}
 534
 535LLINT_HELPER_DECL(helper_to_jsnumber)
 536{
 537 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
 538}
 539
 540LLINT_HELPER_DECL(helper_negate)
 541{
 542 LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
 543}
 544
 545LLINT_HELPER_DECL(helper_add)
 546{
 547 JSValue v1 = LLINT_OP_C(2).jsValue();
 548 JSValue v2 = LLINT_OP_C(3).jsValue();
 549
 550#if LLINT_HELPER_TRACING
 551 printf("Trying to add %s", v1.description());
 552 printf(" to %s.\n", v2.description());
 553#endif
 554
 555 if (v1.isString() && !v2.isObject())
 556 LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
 557
 558 if (v1.isNumber() && v2.isNumber())
 559 LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
 560
 561 LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
 562}
 563
 564LLINT_HELPER_DECL(helper_mul)
 565{
 566 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) * LLINT_OP_C(3).jsValue().toNumber(exec)));
 567}
 568
 569LLINT_HELPER_DECL(helper_sub)
 570{
 571 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) - LLINT_OP_C(3).jsValue().toNumber(exec)));
 572}
 573
 574LLINT_HELPER_DECL(helper_div)
 575{
 576 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) / LLINT_OP_C(3).jsValue().toNumber(exec)));
 577}
 578
 579LLINT_HELPER_DECL(helper_mod)
 580{
 581 LLINT_RETURN(jsNumber(fmod(LLINT_OP_C(2).jsValue().toNumber(exec), LLINT_OP_C(3).jsValue().toNumber(exec))));
 582}
 583
 584LLINT_HELPER_DECL(helper_lshift)
 585{
 586 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) << LLINT_OP_C(3).jsValue().toUInt32(exec)));
 587}
 588
 589LLINT_HELPER_DECL(helper_rshift)
 590{
 591 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
 592}
 593
 594LLINT_HELPER_DECL(helper_urshift)
 595{
 596 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toUInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
 597}
 598
 599LLINT_HELPER_DECL(helper_bitand)
 600{
 601 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) & LLINT_OP_C(3).jsValue().toInt32(exec)));
 602}
 603
 604LLINT_HELPER_DECL(helper_bitor)
 605{
 606 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) | LLINT_OP_C(3).jsValue().toInt32(exec)));
 607}
 608
 609LLINT_HELPER_DECL(helper_bitxor)
 610{
 611 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
 612}
 613
 614LLINT_HELPER_DECL(helper_bitnot)
 615{
 616 LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
 617}
 618
 619LLINT_HELPER_DECL(helper_check_has_instance)
 620{
 621 JSValue baseVal = LLINT_OP_C(1).jsValue();
 622#ifndef NDEBUG
 623 TypeInfo typeInfo(UnspecifiedType);
 624 ASSERT(!baseVal.isObject()
 625 || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
 626#endif
 627 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
 628}
 629
 630LLINT_HELPER_DECL(helper_instanceof)
 631{
 632 LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue())));
 633}
 634
 635LLINT_HELPER_DECL(helper_typeof)
 636{
 637 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
 638}
 639
 640LLINT_HELPER_DECL(helper_is_undefined)
 641{
 642 JSValue v = LLINT_OP_C(2).jsValue();
 643 LLINT_RETURN(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
 644}
 645
 646LLINT_HELPER_DECL(helper_is_boolean)
 647{
 648 LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isBoolean()));
 649}
 650
 651LLINT_HELPER_DECL(helper_is_number)
 652{
 653 LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isNumber()));
 654}
 655
 656LLINT_HELPER_DECL(helper_is_string)
 657{
 658 LLINT_RETURN(jsBoolean(isJSString(LLINT_OP_C(2).jsValue())));
 659}
 660
 661LLINT_HELPER_DECL(helper_is_object)
 662{
 663 LLINT_RETURN(jsBoolean(jsIsObjectType(LLINT_OP_C(2).jsValue())));
 664}
 665
 666LLINT_HELPER_DECL(helper_is_function)
 667{
 668 LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
 669}
 670
 671LLINT_HELPER_DECL(helper_in)
 672{
 673 LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 674}
 675
 676LLINT_HELPER_DECL(helper_resolve)
 677{
 678 LLINT_RETURN_PROFILED(op_resolve, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
 679}
 680
 681LLINT_HELPER_DECL(helper_resolve_skip)
 682{
 683 LLINT_RETURN_PROFILED(
 684 op_resolve_skip,
 685 CommonSlowPaths::opResolveSkip(
 686 exec,
 687 exec->codeBlock()->identifier(pc[2].u.operand),
 688 pc[3].u.operand));
 689}
 690
 691static JSValue resolveGlobal(ExecState* exec, Instruction* pc)
 692{
 693 CodeBlock* codeBlock = exec->codeBlock();
 694 JSGlobalObject* globalObject = codeBlock->globalObject();
 695 ASSERT(globalObject->isGlobalObject());
 696 int property = pc[2].u.operand;
 697 Structure* structure = pc[3].u.structure.get();
 698
 699 ASSERT_UNUSED(structure, structure != globalObject->structure());
 700
 701 Identifier& ident = codeBlock->identifier(property);
 702 PropertySlot slot(globalObject);
 703
 704 if (globalObject->getPropertySlot(exec, ident, slot)) {
 705 JSValue result = slot.getValue(exec, ident);
 706 if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary()
 707 && slot.slotBase() == globalObject) {
 708 pc[3].u.structure.set(
 709 exec->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
 710 pc[4] = slot.cachedOffset();
 711 }
 712
 713 return result;
 714 }
 715
 716 exec->globalData().exception = createUndefinedVariableError(exec, ident);
 717 return JSValue();
 718}
 719
 720LLINT_HELPER_DECL(helper_resolve_global)
 721{
 722 LLINT_RETURN_PROFILED(op_resolve_global, resolveGlobal(exec, pc));
 723}
 724
 725LLINT_HELPER_DECL(helper_resolve_global_dynamic)
 726{
 727 LLINT_RETURN_PROFILED(op_resolve_global_dynamic, resolveGlobal(exec, pc));
 728}
 729
 730LLINT_HELPER_DECL(helper_resolve_for_resolve_global_dynamic)
 731{
 732 LLINT_RETURN_PROFILED(op_resolve_global_dynamic, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
 733}
 734
 735LLINT_HELPER_DECL(helper_resolve_base)
 736{
 737 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 738 if (pc[3].u.operand) {
 739 JSValue base = JSC::resolveBase(exec, ident, exec->scopeChain(), true);
 740 if (!base)
 741 LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
 742 LLINT_RETURN(base);
 743 }
 744
 745 LLINT_RETURN_PROFILED(op_resolve_base, JSC::resolveBase(exec, ident, exec->scopeChain(), false));
 746}
 747
 748LLINT_HELPER_DECL(helper_ensure_property_exists)
 749{
 750 JSObject* object = asObject(LLINT_OP(1).jsValue());
 751 PropertySlot slot(object);
 752 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 753 if (!object->getPropertySlot(exec, ident, slot))
 754 LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
 755 LLINT_END();
 756}
 757
 758LLINT_HELPER_DECL(helper_resolve_with_base)
 759{
 760 JSValue result = CommonSlowPaths::opResolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
 761 LLINT_CHECK_EXCEPTION();
 762 LLINT_OP(2) = result;
 763 // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
 764 LLINT_END();
 765}
 766
 767LLINT_HELPER_DECL(helper_resolve_with_this)
 768{
 769 JSValue result = CommonSlowPaths::opResolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
 770 LLINT_CHECK_EXCEPTION();
 771 LLINT_OP(2) = result;
 772 // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
 773 LLINT_END();
 774}
 775
 776LLINT_HELPER_DECL(helper_get_by_id)
 777{
 778 CodeBlock* codeBlock = exec->codeBlock();
 779 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
 780 JSValue baseValue = LLINT_OP_C(2).jsValue();
 781 PropertySlot slot(baseValue);
 782
 783 JSValue result = baseValue.get(exec, ident, slot);
 784 LLINT_CHECK_EXCEPTION();
 785 LLINT_OP(1) = result;
 786
 787 if (baseValue.isCell()
 788 && slot.isCacheable()
 789 && slot.slotBase() == baseValue
 790 && slot.cachedPropertyType() == PropertySlot::Value) {
 791
 792 JSCell* baseCell = baseValue.asCell();
 793 Structure* structure = baseCell->structure();
 794
 795 if (!structure->isUncacheableDictionary()
 796 && !structure->typeInfo().prohibitsPropertyCaching()) {
 797 pc[4].u.structure.set(
 798 exec->globalData(), codeBlock->ownerExecutable(), structure);
 799 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 800 }
 801 }
 802
 803 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
 804 LLINT_END();
 805}
 806
 807LLINT_HELPER_DECL(helper_get_arguments_length)
 808{
 809 CodeBlock* codeBlock = exec->codeBlock();
 810 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
 811 JSValue baseValue = LLINT_OP(2).jsValue();
 812 PropertySlot slot(baseValue);
 813 LLINT_RETURN(baseValue.get(exec, ident, slot));
 814}
 815
 816LLINT_HELPER_DECL(helper_put_by_id)
 817{
 818 CodeBlock* codeBlock = exec->codeBlock();
 819 Identifier& ident = codeBlock->identifier(pc[2].u.operand);
 820 JSValue baseValue = LLINT_OP_C(1).jsValue();
 821 PutPropertySlot slot(codeBlock->isStrictMode());
 822 if (pc[8].u.operand)
 823 asObject(baseValue)->putDirect(exec->globalData(), ident, LLINT_OP_C(3).jsValue(), slot);
 824 else
 825 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
 826 LLINT_CHECK_EXCEPTION();
 827
 828 if (baseValue.isCell()
 829 && slot.isCacheable()) {
 830
 831 JSCell* baseCell = baseValue.asCell();
 832 Structure* structure = baseCell->structure();
 833
 834 if (!structure->isUncacheableDictionary()
 835 && !structure->typeInfo().prohibitsPropertyCaching()
 836 && baseCell == slot.base()) {
 837
 838 if (slot.type() == PutPropertySlot::NewProperty) {
 839 if (!structure->isDictionary() && structure->previousID()->propertyStorageCapacity() == structure->propertyStorageCapacity()) {
 840 // This is needed because some of the methods we call
 841 // below may GC.
 842 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
 843
 844 normalizePrototypeChain(exec, baseCell);
 845
 846 ASSERT(structure->previousID()->isObject());
 847 pc[4].u.structure.set(
 848 exec->globalData(), codeBlock->ownerExecutable(), structure->previousID());
 849 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 850 pc[6].u.structure.set(
 851 exec->globalData(), codeBlock->ownerExecutable(), structure);
 852 StructureChain* chain = structure->prototypeChain(exec);
 853 ASSERT(chain);
 854 pc[7].u.structureChain.set(
 855 exec->globalData(), codeBlock->ownerExecutable(), chain);
 856
 857 if (pc[8].u.operand)
 858 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
 859 else
 860 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
 861 }
 862 } else {
 863 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
 864 pc[4].u.structure.set(
 865 exec->globalData(), codeBlock->ownerExecutable(), structure);
 866 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 867 }
 868 }
 869 }
 870
 871 LLINT_END();
 872}
 873
 874LLINT_HELPER_DECL(helper_del_by_id)
 875{
 876 CodeBlock* codeBlock = exec->codeBlock();
 877 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
 878 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
 879 LLINT_CHECK_EXCEPTION();
 880 if (!couldDelete && codeBlock->isStrictMode())
 881 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
 882 LLINT_RETURN(jsBoolean(couldDelete));
 883}
 884
 885inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
 886{
 887 if (LIKELY(baseValue.isCell() && subscript.isString())) {
 888 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
 889 return result;
 890 }
 891
 892 if (subscript.isUInt32()) {
 893 uint32_t i = subscript.asUInt32();
 894 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
 895 return asString(baseValue)->getIndex(exec, i);
 896
 897 if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
 898 return asByteArray(baseValue)->getIndex(exec, i);
 899
 900 return baseValue.get(exec, i);
 901 }
 902
 903 Identifier property(exec, subscript.toString(exec)->value(exec));
 904 return baseValue.get(exec, property);
 905}
 906
 907LLINT_HELPER_DECL(helper_get_by_val)
 908{
 909 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
 910}
 911
 912LLINT_HELPER_DECL(helper_get_argument_by_val)
 913{
 914 JSValue arguments = LLINT_OP(2).jsValue();
 915 if (!arguments) {
 916 arguments = Arguments::create(exec->globalData(), exec);
 917 LLINT_CHECK_EXCEPTION();
 918 LLINT_OP(2) = arguments;
 919 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
 920 }
 921
 922 LLINT_RETURN(getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
 923}
 924
 925LLINT_HELPER_DECL(helper_get_by_pname)
 926{
 927 LLINT_RETURN(getByVal(exec, LLINT_OP(2).jsValue(), LLINT_OP(3).jsValue()));
 928}
 929
 930LLINT_HELPER_DECL(helper_put_by_val)
 931{
 932 JSGlobalData& globalData = exec->globalData();
 933
 934 JSValue baseValue = LLINT_OP_C(1).jsValue();
 935 JSValue subscript = LLINT_OP_C(2).jsValue();
 936 JSValue value = LLINT_OP_C(3).jsValue();
 937
 938 if (LIKELY(subscript.isUInt32())) {
 939 uint32_t i = subscript.asUInt32();
 940 if (isJSArray(baseValue)) {
 941 JSArray* jsArray = asArray(baseValue);
 942 if (jsArray->canSetIndex(i))
 943 jsArray->setIndex(globalData, i, value);
 944 else
 945 JSArray::putByIndex(jsArray, exec, i, value);
 946 LLINT_END();
 947 }
 948 if (isJSByteArray(baseValue)
 949 && asByteArray(baseValue)->canAccessIndex(i)) {
 950 JSByteArray* jsByteArray = asByteArray(baseValue);
 951 if (value.isInt32()) {
 952 jsByteArray->setIndex(i, value.asInt32());
 953 LLINT_END();
 954 }
 955 if (value.isNumber()) {
 956 jsByteArray->setIndex(i, value.asNumber());
 957 LLINT_END();
 958 }
 959 }
 960 baseValue.put(exec, i, value);
 961 LLINT_END();
 962 }
 963
 964 Identifier property(exec, subscript.toString(exec)->value(exec));
 965 LLINT_CHECK_EXCEPTION();
 966 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
 967 baseValue.put(exec, property, value, slot);
 968 LLINT_END();
 969}
 970
 971LLINT_HELPER_DECL(helper_del_by_val)
 972{
 973 JSValue baseValue = LLINT_OP_C(2).jsValue();
 974 JSObject* baseObject = baseValue.toObject(exec);
 975
 976 JSValue subscript = LLINT_OP_C(3).jsValue();
 977
 978 bool couldDelete;
 979
 980 uint32_t i;
 981 if (subscript.getUInt32(i))
 982 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
 983 else {
 984 LLINT_CHECK_EXCEPTION();
 985 Identifier property(exec, subscript.toString(exec)->value(exec));
 986 LLINT_CHECK_EXCEPTION();
 987 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
 988 }
 989
 990 if (!couldDelete && exec->codeBlock()->isStrictMode())
 991 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
 992
 993 LLINT_RETURN(jsBoolean(couldDelete));
 994}
 995
 996LLINT_HELPER_DECL(helper_put_by_index)
 997{
 998 LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
 999 LLINT_END();
 1000}
 1001
 1002LLINT_HELPER_DECL(helper_put_getter)
 1003{
 1004 ASSERT(LLINT_OP(1).jsValue().isObject());
 1005 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
 1006 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 1007 ASSERT(LLINT_OP(3).jsValue().isObject());
 1008 baseObj->methodTable()->defineGetter(baseObj, exec, ident, asObject(LLINT_OP(3).jsValue()), 0);
 1009 LLINT_END();
 1010}
 1011
 1012LLINT_HELPER_DECL(helper_put_setter)
 1013{
 1014 ASSERT(LLINT_OP(1).jsValue().isObject());
 1015 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
 1016 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 1017 ASSERT(LLINT_OP(3).jsValue().isObject());
 1018 baseObj->methodTable()->defineSetter(baseObj, exec, ident, asObject(LLINT_OP(3).jsValue()), 0);
 1019 LLINT_END();
 1020}
 1021
 1022LLINT_HELPER_DECL(helper_jmp_scopes)
 1023{
 1024 unsigned count = pc[1].u.operand;
 1025 ScopeChainNode* tmp = exec->scopeChain();
 1026 while (count--)
 1027 tmp = tmp->pop();
 1028 exec->setScopeChain(tmp);
 1029 pc += pc[2].u.operand;
 1030 LLINT_END();
 1031}
 1032
 1033LLINT_HELPER_DECL(helper_jtrue)
 1034{
 1035 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
 1036}
 1037
 1038LLINT_HELPER_DECL(helper_jfalse)
 1039{
 1040 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
 1041}
 1042
 1043LLINT_HELPER_DECL(helper_jless)
 1044{
 1045 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1046}
 1047
 1048LLINT_HELPER_DECL(helper_jnless)
 1049{
 1050 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1051}
 1052
 1053LLINT_HELPER_DECL(helper_jgreater)
 1054{
 1055 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1056}
 1057
 1058LLINT_HELPER_DECL(helper_jngreater)
 1059{
 1060 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1061}
 1062
 1063LLINT_HELPER_DECL(helper_jlesseq)
 1064{
 1065 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1066}
 1067
 1068LLINT_HELPER_DECL(helper_jnlesseq)
 1069{
 1070 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1071}
 1072
 1073LLINT_HELPER_DECL(helper_jgreatereq)
 1074{
 1075 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1076}
 1077
 1078LLINT_HELPER_DECL(helper_jngreatereq)
 1079{
 1080 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1081}
 1082
 1083LLINT_HELPER_DECL(helper_switch_imm)
 1084{
 1085 JSValue scrutinee = LLINT_OP_C(3).jsValue();
 1086 ASSERT(scrutinee.isDouble());
 1087 double value = scrutinee.asDouble();
 1088 int32_t intValue = static_cast<int32_t>(value);
 1089 int defaultOffset = pc[2].u.operand;
 1090 if (value == intValue) {
 1091 CodeBlock* codeBlock = exec->codeBlock();
 1092 pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
 1093 } else
 1094 pc += defaultOffset;
 1095 LLINT_END();
 1096}
 1097
 1098LLINT_HELPER_DECL(helper_switch_string)
 1099{
 1100 JSValue scrutinee = LLINT_OP_C(3).jsValue();
 1101 int defaultOffset = pc[2].u.operand;
 1102 if (!scrutinee.isString())
 1103 pc += defaultOffset;
 1104 else {
 1105 CodeBlock* codeBlock = exec->codeBlock();
 1106 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
 1107 }
 1108 LLINT_END();
 1109}
 1110
 1111LLINT_HELPER_DECL(helper_new_func)
 1112{
 1113 CodeBlock* codeBlock = exec->codeBlock();
 1114 ASSERT(codeBlock->codeType() != FunctionCode
 1115 || !codeBlock->needsFullScopeChain()
 1116 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
 1117#if LLINT_HELPER_TRACING
 1118 printf("Creating function!\n");
 1119#endif
 1120 LLINT_RETURN(codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scopeChain()));
 1121}
 1122
 1123LLINT_HELPER_DECL(helper_new_func_exp)
 1124{
 1125 CodeBlock* codeBlock = exec->codeBlock();
 1126 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
 1127 JSFunction* func = function->make(exec, exec->scopeChain());
 1128
 1129 if (!function->name().isNull()) {
 1130 JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(exec, function->name(), func, ReadOnly | DontDelete);
 1131 func->setScope(exec->globalData(), func->scope()->push(functionScopeObject));
 1132 }
 1133
 1134 LLINT_RETURN(func);
 1135}
 1136
 1137static HelperReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
 1138{
 1139 ExecState* exec = execCallee->callerFrame();
 1140 JSGlobalData* globalData = &exec->globalData();
 1141
 1142 execCallee->setScopeChain(exec->scopeChain());
 1143 execCallee->setCodeBlock(0);
 1144
 1145 if (kind == CodeForCall) {
 1146 CallData callData;
 1147 CallType callType = getCallData(callee, callData);
 1148
 1149 ASSERT(callType != CallTypeJS);
 1150
 1151 if (callType == CallTypeHost) {
 1152 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
 1153
 1154 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1155 }
 1156
 1157#if LLINT_HELPER_TRACING
 1158 printf("Call callee is not a function: %s\n", callee.description());
 1159#endif
 1160
 1161 ASSERT(callType == CallTypeNone);
 1162 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
 1163 }
 1164
 1165 ASSERT(kind == CodeForConstruct);
 1166
 1167 ConstructData constructData;
 1168 ConstructType constructType = getConstructData(callee, constructData);
 1169
 1170 ASSERT(constructType != ConstructTypeJS);
 1171
 1172 if (constructType == ConstructTypeHost) {
 1173 globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
 1174 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1175 }
 1176
 1177#if LLINT_HELPER_TRACING
 1178 printf("Constructor callee is not a function: %s\n", callee.description());
 1179#endif
 1180
 1181 ASSERT(constructType == ConstructTypeNone);
 1182 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
 1183}
 1184
 1185inline HelperReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
 1186{
 1187 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
 1188 if (!calleeAsFunctionCell)
 1189 return handleHostCall(execCallee, pc, calleeAsValue, kind);
 1190
 1191 JSFunction* callee = asFunction(calleeAsFunctionCell);
 1192 execCallee->setScopeChain(callee->scopeUnchecked());
 1193 ExecutableBase* executable = callee->executable();
 1194
 1195 MacroAssemblerCodePtr codePtr;
 1196 CodeBlock* codeBlock = 0;
 1197 if (executable->isHostFunction())
 1198 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
 1199 else {
 1200 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 1201 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
 1202 if (error)
 1203 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
 1204 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
 1205 ASSERT(codeBlock);
 1206 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
 1207 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
 1208 else
 1209 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
 1210 }
 1211
 1212 if (callLinkInfo) {
 1213 if (callLinkInfo->isOnList())
 1214 callLinkInfo->remove();
 1215 ExecState* execCaller = execCallee->callerFrame();
 1216 callLinkInfo->callee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
 1217 callLinkInfo->lastSeenCallee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
 1218 callLinkInfo->machineCodeTarget = codePtr;
 1219 if (codeBlock)
 1220 codeBlock->linkIncomingCall(callLinkInfo);
 1221 }
 1222
 1223 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
 1224}
 1225
 1226inline HelperReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
 1227{
 1228 // This needs to:
 1229 // - Set up a call frame.
 1230 // - Figure out what to call and compile it if necessary.
 1231 // - If possible, link the call's inline cache.
 1232 // - Return a tuple of machine code address to call and the new call frame.
 1233
 1234 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
 1235
 1236 ExecState* execCallee = exec + pc[3].u.operand;
 1237
 1238 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
 1239 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1240 execCallee->setCallerFrame(exec);
 1241
 1242 ASSERT(pc[4].u.callLinkInfo);
 1243 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
 1244}
 1245
 1246LLINT_HELPER_DECL(helper_call)
 1247{
 1248 return genericCall(exec, pc, CodeForCall);
 1249}
 1250
 1251LLINT_HELPER_DECL(helper_construct)
 1252{
 1253 return genericCall(exec, pc, CodeForConstruct);
 1254}
 1255
 1256LLINT_HELPER_DECL(helper_call_varargs)
 1257{
 1258 // This needs to:
 1259 // - Set up a call frame while respecting the variable arguments.
 1260 // - Figure out what to call and compile it if necessary.
 1261 // - Return a tuple of machine code address to call and the new call frame.
 1262
 1263 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
 1264
 1265 ExecState* execCallee = loadVarargs(
 1266 exec, &exec->globalData().interpreter->registerFile(),
 1267 LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
 1268 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
 1269
 1270 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1271 execCallee->setCallerFrame(exec);
 1272 exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_varargs));
 1273
 1274 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
 1275}
 1276
 1277LLINT_HELPER_DECL(helper_call_eval)
 1278{
 1279 JSValue calleeAsValue = LLINT_OP(1).jsValue();
 1280
 1281 ExecState* execCallee = exec + pc[3].u.operand;
 1282 JSGlobalData& globalData = exec->globalData();
 1283
 1284 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
 1285 execCallee->setCallerFrame(exec);
 1286 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1287 execCallee->setScopeChain(exec->scopeChain());
 1288 execCallee->setReturnPC(bitwise_cast<Instruction*>(&llint_generic_return_point));
 1289 execCallee->setCodeBlock(0);
 1290 exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_eval));
 1291
 1292 if (!isHostFunction(calleeAsValue, globalFuncEval))
 1293 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
 1294
 1295 globalData.hostCallReturnValue = eval(execCallee);
 1296 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1297}
 1298
 1299LLINT_HELPER_DECL(helper_tear_off_activation)
 1300{
 1301 ASSERT(exec->codeBlock()->needsFullScopeChain());
 1302 JSValue activationValue = LLINT_OP(1).jsValue();
 1303 if (!activationValue) {
 1304 if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue()) {
 1305 if (!exec->codeBlock()->isStrictMode())
 1306 asArguments(v)->tearOff(exec);
 1307 }
 1308 LLINT_END();
 1309 }
 1310 JSActivation* activation = asActivation(activationValue);
 1311 activation->tearOff(exec->globalData());
 1312 if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue())
 1313 asArguments(v)->didTearOffActivation(exec->globalData(), activation);
 1314 LLINT_END();
 1315}
 1316
 1317LLINT_HELPER_DECL(helper_tear_off_arguments)
 1318{
 1319 ASSERT(exec->codeBlock()->usesArguments() && !exec->codeBlock()->needsFullScopeChain());
 1320 asArguments(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue())->tearOff(exec);
 1321 LLINT_END();
 1322}
 1323
 1324LLINT_HELPER_DECL(helper_strcat)
 1325{
 1326 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
 1327}
 1328
 1329LLINT_HELPER_DECL(helper_to_primitive)
 1330{
 1331 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
 1332}
 1333
 1334LLINT_HELPER_DECL(helper_get_pnames)
 1335{
 1336 JSValue v = LLINT_OP(2).jsValue();
 1337 if (v.isUndefinedOrNull()) {
 1338 pc += pc[5].u.operand;
 1339 LLINT_END();
 1340 }
 1341
 1342 JSObject* o = v.toObject(exec);
 1343 Structure* structure = o->structure();
 1344 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
 1345 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
 1346 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
 1347
 1348 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
 1349 LLINT_OP(2) = JSValue(o);
 1350 LLINT_OP(3) = Register::withInt(0);
 1351 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
 1352
 1353 pc += OPCODE_LENGTH(op_get_pnames);
 1354 LLINT_END();
 1355}
 1356
 1357LLINT_HELPER_DECL(helper_next_pname)
 1358{
 1359 JSObject* base = asObject(LLINT_OP(2).jsValue());
 1360 JSString* property = asString(LLINT_OP(1).jsValue());
 1361 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
 1362 // Go to target.
 1363 pc += pc[6].u.operand;
 1364 } // Else, don't change the PC, so the interpreter will reloop.
 1365 LLINT_END();
 1366}
 1367
 1368LLINT_HELPER_DECL(helper_push_scope)
 1369{
 1370 JSValue v = LLINT_OP(1).jsValue();
 1371 JSObject* o = v.toObject(exec);
 1372 LLINT_CHECK_EXCEPTION();
 1373
 1374 LLINT_OP(1) = o;
 1375 exec->setScopeChain(exec->scopeChain()->push(o));
 1376
 1377 LLINT_END();
 1378}
 1379
 1380LLINT_HELPER_DECL(helper_pop_scope)
 1381{
 1382 exec->setScopeChain(exec->scopeChain()->pop());
 1383 LLINT_END();
 1384}
 1385
 1386LLINT_HELPER_DECL(helper_push_new_scope)
 1387{
 1388 CodeBlock* codeBlock = exec->codeBlock();
 1389 JSObject* scope = JSStaticScopeObject::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), DontDelete);
 1390 exec->setScopeChain(exec->scopeChain()->push(scope));
 1391 LLINT_RETURN(scope);
 1392}
 1393
 1394LLINT_HELPER_DECL(helper_throw)
 1395{
 1396 LLINT_THROW(LLINT_OP_C(1).jsValue());
 1397}
 1398
 1399LLINT_HELPER_DECL(helper_throw_reference_error)
 1400{
 1401 LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
 1402}
 1403
 1404LLINT_HELPER_DECL(helper_debug)
 1405{
 1406 int debugHookID = pc[1].u.operand;
 1407 int firstLine = pc[2].u.operand;
 1408 int lastLine = pc[3].u.operand;
 1409
 1410 exec->globalData().interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
 1411
 1412 LLINT_END();
 1413}
 1414
 1415LLINT_HELPER_DECL(helper_profile_will_call)
 1416{
 1417 (*Profiler::enabledProfilerReference())->willExecute(exec, LLINT_OP(1).jsValue());
 1418 LLINT_END();
 1419}
 1420
 1421LLINT_HELPER_DECL(helper_profile_did_call)
 1422{
 1423 (*Profiler::enabledProfilerReference())->didExecute(exec, LLINT_OP(1).jsValue());
 1424 LLINT_END();
 1425}
 1426
 1427} } // namespace JSC::LLInt
 1428
 1429#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LLIntHelpers.h

 1/*
 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntHelpers_h
 27#define LLIntHelpers_h
 28
 29#include <wtf/Platform.h>
 30#include <wtf/StdLibExtras.h>
 31
 32#if ENABLE(LLINT)
 33
 34namespace JSC {
 35
 36class ExecState;
 37struct Instruction;
 38
 39namespace LLInt {
 40
 41typedef int64_t HelperReturnType;
 42
 43extern "C" HelperReturnType llint_trace_operand(ExecState*, Instruction*, int fromWhere, int operand);
 44extern "C" HelperReturnType llint_trace_value(ExecState*, Instruction*, int fromWhere, int operand);
 45
 46#define LLINT_HELPER_DECL(name) \
 47 extern "C" HelperReturnType llint_##name(ExecState* exec, Instruction* pc)
 48
 49LLINT_HELPER_DECL(trace_prologue);
 50LLINT_HELPER_DECL(trace_prologue_function_for_call);
 51LLINT_HELPER_DECL(trace_prologue_function_for_construct);
 52LLINT_HELPER_DECL(trace_arityCheck_for_call);
 53LLINT_HELPER_DECL(trace_arityCheck_for_construct);
 54LLINT_HELPER_DECL(trace);
 55LLINT_HELPER_DECL(special_trace);
 56LLINT_HELPER_DECL(entry_osr);
 57LLINT_HELPER_DECL(entry_osr_function_for_call);
 58LLINT_HELPER_DECL(entry_osr_function_for_construct);
 59LLINT_HELPER_DECL(entry_osr_function_for_call_arityCheck);
 60LLINT_HELPER_DECL(entry_osr_function_for_construct_arityCheck);
 61LLINT_HELPER_DECL(loop_osr);
 62LLINT_HELPER_DECL(replace);
 63LLINT_HELPER_DECL(register_file_check);
 64LLINT_HELPER_DECL(helper_call_arityCheck);
 65LLINT_HELPER_DECL(helper_construct_arityCheck);
 66LLINT_HELPER_DECL(helper_create_activation);
 67LLINT_HELPER_DECL(helper_create_arguments);
 68LLINT_HELPER_DECL(helper_create_this);
 69LLINT_HELPER_DECL(helper_convert_this);
 70LLINT_HELPER_DECL(helper_new_object);
 71LLINT_HELPER_DECL(helper_new_array);
 72LLINT_HELPER_DECL(helper_new_array_buffer);
 73LLINT_HELPER_DECL(helper_new_regexp);
 74LLINT_HELPER_DECL(helper_not);
 75LLINT_HELPER_DECL(helper_eq);
 76LLINT_HELPER_DECL(helper_neq);
 77LLINT_HELPER_DECL(helper_stricteq);
 78LLINT_HELPER_DECL(helper_nstricteq);
 79LLINT_HELPER_DECL(helper_less);
 80LLINT_HELPER_DECL(helper_lesseq);
 81LLINT_HELPER_DECL(helper_greater);
 82LLINT_HELPER_DECL(helper_greatereq);
 83LLINT_HELPER_DECL(helper_pre_inc);
 84LLINT_HELPER_DECL(helper_pre_dec);
 85LLINT_HELPER_DECL(helper_post_inc);
 86LLINT_HELPER_DECL(helper_post_dec);
 87LLINT_HELPER_DECL(helper_to_jsnumber);
 88LLINT_HELPER_DECL(helper_negate);
 89LLINT_HELPER_DECL(helper_add);
 90LLINT_HELPER_DECL(helper_mul);
 91LLINT_HELPER_DECL(helper_sub);
 92LLINT_HELPER_DECL(helper_div);
 93LLINT_HELPER_DECL(helper_mod);
 94LLINT_HELPER_DECL(helper_lshift);
 95LLINT_HELPER_DECL(helper_rshift);
 96LLINT_HELPER_DECL(helper_urshift);
 97LLINT_HELPER_DECL(helper_bitand);
 98LLINT_HELPER_DECL(helper_bitor);
 99LLINT_HELPER_DECL(helper_bitxor);
 100LLINT_HELPER_DECL(helper_bitnot);
 101LLINT_HELPER_DECL(helper_check_has_instance);
 102LLINT_HELPER_DECL(helper_instanceof);
 103LLINT_HELPER_DECL(helper_typeof);
 104LLINT_HELPER_DECL(helper_is_undefined);
 105LLINT_HELPER_DECL(helper_is_boolean);
 106LLINT_HELPER_DECL(helper_is_number);
 107LLINT_HELPER_DECL(helper_is_string);
 108LLINT_HELPER_DECL(helper_is_object);
 109LLINT_HELPER_DECL(helper_is_function);
 110LLINT_HELPER_DECL(helper_in);
 111LLINT_HELPER_DECL(helper_resolve);
 112LLINT_HELPER_DECL(helper_resolve_skip);
 113LLINT_HELPER_DECL(helper_resolve_global);
 114LLINT_HELPER_DECL(helper_resolve_global_dynamic);
 115LLINT_HELPER_DECL(helper_resolve_for_resolve_global_dynamic);
 116LLINT_HELPER_DECL(helper_resolve_base);
 117LLINT_HELPER_DECL(helper_ensure_property_exists);
 118LLINT_HELPER_DECL(helper_resolve_with_base);
 119LLINT_HELPER_DECL(helper_resolve_with_this);
 120LLINT_HELPER_DECL(helper_get_by_id);
 121LLINT_HELPER_DECL(helper_get_arguments_length);
 122LLINT_HELPER_DECL(helper_put_by_id);
 123LLINT_HELPER_DECL(helper_del_by_id);
 124LLINT_HELPER_DECL(helper_get_by_val);
 125LLINT_HELPER_DECL(helper_get_argument_by_val);
 126LLINT_HELPER_DECL(helper_get_by_pname);
 127LLINT_HELPER_DECL(helper_put_by_val);
 128LLINT_HELPER_DECL(helper_del_by_val);
 129LLINT_HELPER_DECL(helper_put_by_index);
 130LLINT_HELPER_DECL(helper_put_getter);
 131LLINT_HELPER_DECL(helper_put_setter);
 132LLINT_HELPER_DECL(helper_jmp_scopes);
 133LLINT_HELPER_DECL(helper_jtrue);
 134LLINT_HELPER_DECL(helper_jfalse);
 135LLINT_HELPER_DECL(helper_jless);
 136LLINT_HELPER_DECL(helper_jnless);
 137LLINT_HELPER_DECL(helper_jgreater);
 138LLINT_HELPER_DECL(helper_jngreater);
 139LLINT_HELPER_DECL(helper_jlesseq);
 140LLINT_HELPER_DECL(helper_jnlesseq);
 141LLINT_HELPER_DECL(helper_jgreatereq);
 142LLINT_HELPER_DECL(helper_jngreatereq);
 143LLINT_HELPER_DECL(helper_switch_imm);
 144LLINT_HELPER_DECL(helper_switch_char);
 145LLINT_HELPER_DECL(helper_switch_string);
 146LLINT_HELPER_DECL(helper_new_func);
 147LLINT_HELPER_DECL(helper_new_func_exp);
 148LLINT_HELPER_DECL(helper_call);
 149LLINT_HELPER_DECL(helper_construct);
 150LLINT_HELPER_DECL(helper_call_varargs);
 151LLINT_HELPER_DECL(helper_call_eval);
 152LLINT_HELPER_DECL(helper_tear_off_activation);
 153LLINT_HELPER_DECL(helper_tear_off_arguments);
 154LLINT_HELPER_DECL(helper_strcat);
 155LLINT_HELPER_DECL(helper_to_primitive);
 156LLINT_HELPER_DECL(helper_get_pnames);
 157LLINT_HELPER_DECL(helper_next_pname);
 158LLINT_HELPER_DECL(helper_push_scope);
 159LLINT_HELPER_DECL(helper_pop_scope);
 160LLINT_HELPER_DECL(helper_push_new_scope);
 161LLINT_HELPER_DECL(helper_throw);
 162LLINT_HELPER_DECL(helper_throw_reference_error);
 163LLINT_HELPER_DECL(helper_debug);
 164LLINT_HELPER_DECL(helper_profile_will_call);
 165LLINT_HELPER_DECL(helper_profile_did_call);
 166
 167} } // namespace JSC::LLInt
 168
 169#endif // ENABLE(LLINT)
 170
 171#endif // LLIntHelpers_h
 172
0

Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntOfflineAsmConfig_h
 27#define LLIntOfflineAsmConfig_h
 28
 29#include "LLIntCommon.h"
 30#include <wtf/Assertions.h>
 31#include <wtf/Platform.h>
 32
 33#if CPU(X86)
 34#define OFFLINE_ASM_X86 1
 35#else
 36#define OFFLINE_ASM_X86 0
 37#endif
 38
 39#if CPU(ARMv7)
 40#define OFFLINE_ASM_ARMv7 1
 41#else
 42#define OFFLINE_ASM_ARMv7 0
 43#endif
 44
 45#if !ASSERT_DISABLED
 46#define OFFLINE_ASM_ASSERT_ENABLED 1
 47#else
 48#define OFFLINE_ASM_ASSERT_ENABLED 0
 49#endif
 50
 51#if CPU(BIG_ENDIAN)
 52#define OFFLINE_ASM_BIG_ENDIAN 1
 53#else
 54#define OFFLINE_ASM_BIG_ENDIAN 0
 55#endif
 56
 57#if ENABLE(LLINT_OSR_TO_JIT)
 58#define OFFLINE_ASM_JIT_ENABLED 1
 59#else
 60#define OFFLINE_ASM_JIT_ENABLED 0
 61#endif
 62
 63#if LLINT_EXECUTION_TRACING
 64#define OFFLINE_ASM_EXECUTION_TRACING 1
 65#else
 66#define OFFLINE_ASM_EXECUTION_TRACING 0
 67#endif
 68
 69#endif // LLIntOfflineAsmConfig_h
0

Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27
 28#include "AllocationSpace.h"
 29#include "CodeBlock.h"
 30#include "Executable.h"
 31#include "Heap.h"
 32#include "Interpreter.h"
 33#include "JITStubs.h"
 34#include "JSArray.h"
 35#include "JSCell.h"
 36#include "JSFunction.h"
 37#include "JSGlobalData.h"
 38#include "JSGlobalObject.h"
 39#include "JSObject.h"
 40#include "JSPropertyNameIterator.h"
 41#include "JSString.h"
 42#include "JSTypeInfo.h"
 43#include "JSVariableObject.h"
 44#include "JumpTable.h"
 45#include "LLIntOfflineAsmConfig.h"
 46#include "MarkedSpace.h"
 47#include "RegisterFile.h"
 48#include "ScopeChain.h"
 49#include "Structure.h"
 50#include "StructureChain.h"
 51#include "ValueProfile.h"
 52#include <wtf/text/StringImpl.h>
 53
 54namespace JSC {
 55
 56#define OFFLINE_ASM_OFFSETOF(clazz, field) OBJECT_OFFSETOF(clazz, field)
 57
 58class LLIntOffsetsExtractor {
 59public:
 60 static const unsigned* dummy();
 61};
 62
 63const unsigned* LLIntOffsetsExtractor::dummy()
 64{
 65#include "LLIntDesiredOffsets.h"
 66 return extractorTable;
 67}
 68
 69} // namespace JSC
 70
 71int main(int, char**)
 72{
 73 // Out of an abundance of caution, make sure that LLIntOffsetsExtractor::dummy() is live,
 74 // and the extractorTable is live, too.
 75 printf("%p\n", JSC::LLIntOffsetsExtractor::dummy());
 76 return 0;
 77}
0

Source/JavaScriptCore/llint/LLIntThunks.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LLIntThunks.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "JSInterfaceJIT.h"
 32#include "LinkBuffer.h"
 33#include "LowLevelInterpreter.h"
 34
 35namespace JSC { namespace LLInt {
 36
 37static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)())
 38{
 39 JSInterfaceJIT jit;
 40
 41 // FIXME: there's probably a better way to do it on X86, but I'm not sure I care.
 42 jit.move(JSInterfaceJIT::TrustedImmPtr(bitwise_cast<void*>(target)), JSInterfaceJIT::regT0);
 43 jit.jump(JSInterfaceJIT::regT0);
 44
 45 LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
 46 return patchBuffer.finalizeCode();
 47}
 48
 49MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData* globalData)
 50{
 51 return generateThunkWithJumpTo(globalData, llint_function_for_call_prologue);
 52}
 53
 54MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData* globalData)
 55{
 56 return generateThunkWithJumpTo(globalData, llint_function_for_construct_prologue);
 57}
 58
 59MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData* globalData)
 60{
 61 return generateThunkWithJumpTo(globalData, llint_function_for_call_arity_check);
 62}
 63
 64MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData* globalData)
 65{
 66 return generateThunkWithJumpTo(globalData, llint_function_for_construct_arity_check);
 67}
 68
 69MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData* globalData)
 70{
 71 return generateThunkWithJumpTo(globalData, llint_eval_prologue);
 72}
 73
 74MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData* globalData)
 75{
 76 return generateThunkWithJumpTo(globalData, llint_program_prologue);
 77}
 78
 79} } // namespace JSC::LLInt
 80
 81#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LLIntThunks.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LLIntThunks_h
 27#define LLIntThunks_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(LLINT)
 32
 33#include "MacroAssemblerCodeRef.h"
 34
 35namespace JSC {
 36
 37class JSGlobalData;
 38
 39namespace LLInt {
 40
 41MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData*);
 42MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData*);
 43MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData*);
 44MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData*);
 45MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData*);
 46MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData*);
 47
 48} } // namespace JSC::LLInt
 49
 50#endif // ENABLE(LLINT)
 51
 52#endif // LLIntThunks_h
0

Source/JavaScriptCore/llint/LowLevelInterpreter.asm

 1# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24
 25# Crash course on the language that this is written in (which I just call
 26# "assembly" even though it's more than that):
 27#
 28# - Mostly gas-style operand ordering. The last operand tends to be the
 29# destination. So "a := b" is written as "mov b, a". But unlike gas,
 30# comparisons are in-order, so "if (a < b)" is written as
 31# "bilt a, b, ...".
 32#
 33# - "b" = byte, "h" = 16-bit word, "i" = 32-bit word, "p" = pointer.
 34# Currently this is just 32-bit so "i" and "p" are interchangeable
 35# except when an op supports one but not the other.
 36#
 37# - In general, valid operands for macro invocations and instructions are
 38# registers (eg "t0"), addresses (eg "4[t0]"), base-index addresses
 39# (eg "7[t0, t1, 2]"), absolute addresses (eg "0xa0000000[]"), or labels
 40# (eg "_foo" or ".foo"). Macro invocations can also take anonymous
 41# macros as operands. Instructions cannot take anonymous macros.
 42#
 43# - Labels must have names that begin with either "_" or ".". A "." label
 44# is local and gets renamed before code gen to minimize namespace
 45# pollution. A "_" label is an extern symbol (i.e. ".globl"). The "_"
 46# may or may not be removed during code gen depending on whether the asm
 47# conventions for C name mangling on the target platform mandate a "_"
 48# prefix.
 49#
 50# - A "macro" is a lambda expression, which may be either anonymous or
 51# named. But this has caveats. "macro" can take zero or more arguments,
 52# which may be macros or any valid operands, but it can only return
 53# code. But you can do Turing-complete things via continuation passing
 54# style: "macro foo (a, b) b(a) end foo(foo, foo)". Actually, don't do
 55# that, since you'll just crash the assembler.
 56#
 57# - An "if" is a conditional on settings. Any identifier supplied in the
 58# predicate of an "if" is assumed to be a #define that is available
 59# during code gen. So you can't use "if" for computation in a macro, but
 60# you can use it to select different pieces of code for different
 61# platforms.
 62#
 63# - Arguments to macros follow lexical scoping rather than dynamic scoping.
 64# Const's also follow lexical scoping and may override (hide) arguments
 65# or other consts. All variables (arguments and constants) can be bound
 66# to operands. Additionally, arguments (but not constants) can be bound
 67# to macros.
 68
 69
 70# These declarations must match interpreter/RegisterFile.h.
 71const CallFrameHeaderSize = 48
 72const ArgumentCount = -48
 73const CallerFrame = -40
 74const Callee = -32
 75const ScopeChain = -24
 76const ReturnPC = -16
 77const CodeBlock = -8
 78
 79const ThisArgumentOffset = -CallFrameHeaderSize - 8
 80
 81# Declare some aliases for the registers we will use.
 82const PC = t4
 83
 84# Offsets needed for reasoning about value representation.
 85if BIG_ENDIAN
 86 const TagOffset = 0
 87 const PayloadOffset = 4
 88else
 89 const TagOffset = 4
 90 const PayloadOffset = 0
 91end
 92
 93# Value representation constants.
 94const Int32Tag = -1
 95const BooleanTag = -2
 96const NullTag = -3
 97const UndefinedTag = -4
 98const CellTag = -5
 99const EmptyValueTag = -6
 100const DeletedValueTag = -7
 101const LowestTag = DeletedValueTag
 102
 103# Type constants.
 104const StringType = 5
 105const ObjectType = 10
 106
 107# Type flags constants.
 108const MasqueradesAsUndefined = 1
 109const ImplementsHasInstance = 2
 110const ImplementsDefaultHasInstance = 8
 111
 112# Heap allocation constants.
 113const JSFinalObjectSizeClassIndex = 3
 114
 115# Bytecode operand constants.
 116const FirstConstantRegisterIndex = 0x40000000
 117
 118# Code type constants.
 119const GlobalCode = 0
 120const EvalCode = 1
 121const FunctionCode = 2
 122
 123# The interpreter steals the tag word of the argument count.
 124const LLIntReturnPC = ArgumentCount + TagOffset
 125
 126# This must match wtf/Vector.h.
 127const VectorSizeOffset = 0
 128const VectorBufferOffset = 4
 129
 130# String flags.
 131const HashFlags8BitBuffer = 64
 132
 133# Utilities
 134macro crash()
 135 storei 0, 0xbbadbeef[]
 136 move 0, t0
 137 call t0
 138end
 139
 140macro assert(assertion)
 141 if ASSERT_ENABLED
 142 assertion(.ok)
 143 crash()
 144 .ok:
 145 end
 146end
 147
 148macro preserveReturnAddressAfterCall(destinationRegister)
 149 if ARMv7
 150 move lr, destinationRegister
 151 elsif X86
 152 pop destinationRegister
 153 else
 154 error
 155 end
 156end
 157
 158macro restoreReturnAddressBeforeReturn(sourceRegister)
 159 if ARMv7
 160 move sourceRegister, lr
 161 elsif X86
 162 push sourceRegister
 163 else
 164 error
 165 end
 166end
 167
 168macro dispatch(advance)
 169 addp advance * 4, PC
 170 jmp [PC]
 171end
 172
 173macro dispatchBranchWithOffset(pcOffset)
 174 lshifti 2, pcOffset
 175 addp pcOffset, PC
 176 jmp [PC]
 177end
 178
 179macro dispatchBranch(pcOffset)
 180 loadi pcOffset, t0
 181 dispatchBranchWithOffset(t0)
 182end
 183
 184macro dispatchAfterCall()
 185 loadi ArgumentCount + TagOffset[cfr], PC
 186 jmp [PC]
 187end
 188
 189macro cCall2(function, arg1, arg2)
 190 if ARMv7
 191 move arg1, t0
 192 move arg2, t1
 193 elsif X86
 194 poke arg1, 0
 195 poke arg2, 1
 196 else
 197 error
 198 end
 199 call function
 200end
 201
 202# This barely works. arg3 and arg4 should probably be immediates.
 203macro cCall4(function, arg1, arg2, arg3, arg4)
 204 if ARMv7
 205 move arg1, t0
 206 move arg2, t1
 207 move arg3, t2
 208 move arg4, t3
 209 elsif X86
 210 poke arg1, 0
 211 poke arg2, 1
 212 poke arg3, 2
 213 poke arg4, 3
 214 else
 215 error
 216 end
 217 call function
 218end
 219
 220macro callHelper(helper)
 221 cCall2(helper, cfr, PC)
 222 move t0, PC
 223 move t1, cfr
 224end
 225
 226# Debugging operation if you'd like to print an operand in the instruction stream.
 227macro traceOperand(fromWhere, operand)
 228 cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
 229 move t0, PC
 230 move t1, cfr
 231end
 232
 233# Debugging operation if you'd like to print the value of an operand in the instruction
 234# stream.
 235macro traceValue(fromWhere, operand)
 236 cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
 237 move t0, PC
 238 move t1, cfr
 239end
 240
 241macro traceExecution()
 242 if EXECUTION_TRACING
 243 callHelper(_llint_trace)
 244 end
 245end
 246
 247# Call a helper for call opcodes.
 248macro callCallHelper(advance, helper, action)
 249 addp advance * 4, PC, t0
 250 storep t0, ArgumentCount + TagOffset[cfr]
 251 cCall2(helper, cfr, PC)
 252 move t1, cfr
 253 action(t0)
 254end
 255
 256macro slowPathForCall(advance, helper)
 257 callCallHelper(
 258 advance,
 259 helper,
 260 macro (callee)
 261 call callee
 262 dispatchAfterCall()
 263 end)
 264end
 265
 266macro checkSwitchToJIT(increment, action)
 267 if JIT_ENABLED
 268 loadp CodeBlock[cfr], t0
 269 baddis increment, CodeBlock::m_llintExecuteCounter[t0], .continue
 270 action()
 271 .continue:
 272 end
 273end
 274
 275macro checkSwitchToJITForLoop()
 276 checkSwitchToJIT(
 277 1,
 278 macro ()
 279 storei PC, ArgumentCount + TagOffset[cfr]
 280 cCall2(_llint_loop_osr, cfr, PC)
 281 move t1, cfr
 282 btpz t0, .recover
 283 jmp t0
 284 .recover:
 285 loadi ArgumentCount + TagOffset[cfr], PC
 286 end)
 287end
 288
 289macro checkSwitchToJITForEpilogue()
 290 checkSwitchToJIT(
 291 10,
 292 macro ()
 293 callHelper(_llint_replace)
 294 end)
 295end
 296
 297macro assertNotConstant(index)
 298 assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
 299end
 300
 301# Index, tag, and payload must be different registers. Index is not
 302# changed.
 303macro loadConstantOrVariable(index, tag, payload)
 304 bigteq index, FirstConstantRegisterIndex, .constant
 305 loadi TagOffset[cfr, index, 8], tag
 306 loadi PayloadOffset[cfr, index, 8], payload
 307 jmp .done
 308.constant:
 309 loadp CodeBlock[cfr], payload
 310 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
 311 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 312 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 313 loadp TagOffset[payload, index, 8], tag
 314 loadp PayloadOffset[payload, index, 8], payload
 315.done:
 316end
 317
 318# Index and payload may be the same register. Index may be clobbered.
 319macro loadConstantOrVariable2Reg(index, tag, payload)
 320 bigteq index, FirstConstantRegisterIndex, .constant
 321 loadi TagOffset[cfr, index, 8], tag
 322 loadi PayloadOffset[cfr, index, 8], payload
 323 jmp .done
 324.constant:
 325 loadp CodeBlock[cfr], tag
 326 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
 327 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 328 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 329 lshifti 3, index
 330 addp index, tag
 331 loadp PayloadOffset[tag], payload
 332 loadp TagOffset[tag], tag
 333.done:
 334end
 335
 336macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
 337 bigteq index, FirstConstantRegisterIndex, .constant
 338 tagCheck(TagOffset[cfr, index, 8])
 339 loadi PayloadOffset[cfr, index, 8], payload
 340 jmp .done
 341.constant:
 342 loadp CodeBlock[cfr], payload
 343 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
 344 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 345 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 346 tagCheck(TagOffset[payload, index, 8])
 347 loadp PayloadOffset[payload, index, 8], payload
 348.done:
 349end
 350
 351# Index and payload must be different registers. Index is not mutated. Use
 352# this if you know what the tag of the variable should be. Doing the tag
 353# test as part of loading the variable reduces register use, but may not
 354# be faster than doing loadConstantOrVariable followed by a branch on the
 355# tag.
 356macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
 357 loadConstantOrVariablePayloadTagCustom(
 358 index,
 359 macro (actualTag) bineq actualTag, expectedTag, slow end,
 360 payload)
 361end
 362
 363macro loadConstantOrVariablePayloadUnchecked(index, payload)
 364 loadConstantOrVariablePayloadTagCustom(
 365 index,
 366 macro (actualTag) end,
 367 payload)
 368end
 369
 370macro writeBarrier(tag, payload)
 371 # Nothing to do, since we don't have a generational or incremental collector.
 372end
 373
 374macro valueProfile(tag, payload, profile)
 375 storei tag, ValueProfile::m_buckets + TagOffset[profile]
 376 storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
 377end
 378
 379
 380# Indicate the beginning of LLInt.
 381_llint_begin:
 382 crash()
 383
 384
 385# Entrypoints into the interpreter
 386
 387macro functionForCallCodeBlockGetter(targetRegister)
 388 loadp Callee[cfr], targetRegister
 389 loadp JSFunction::m_executable[targetRegister], targetRegister
 390 loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
 391end
 392
 393macro functionForConstructCodeBlockGetter(targetRegister)
 394 loadp Callee[cfr], targetRegister
 395 loadp JSFunction::m_executable[targetRegister], targetRegister
 396 loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
 397end
 398
 399macro notFunctionCodeBlockGetter(targetRegister)
 400 loadp CodeBlock[cfr], targetRegister
 401end
 402
 403macro functionCodeBlockSetter(sourceRegister)
 404 storep sourceRegister, CodeBlock[cfr]
 405end
 406
 407macro notFunctionCodeBlockSetter(sourceRegister)
 408 # Nothing to do!
 409end
 410
 411# Do the bare minimum required to execute code. Sets up the PC, leave the CodeBlock*
 412# in t1. May also trigger prologue entry OSR.
 413macro prologue(codeBlockGetter, codeBlockSetter, osrHelper, traceHelper)
 414 preserveReturnAddressAfterCall(t2)
 415
 416 # Set up the call frame and check if we should OSR.
 417 storep t2, ReturnPC[cfr]
 418 if EXECUTION_TRACING
 419 callHelper(traceHelper)
 420 end
 421 codeBlockGetter(t1)
 422 if JIT_ENABLED
 423 baddis 5, CodeBlock::m_llintExecuteCounter[t1], .continue
 424 cCall2(osrHelper, cfr, PC)
 425 move t1, cfr
 426 btpz t0, .recover
 427 loadp ReturnPC[cfr], t2
 428 restoreReturnAddressBeforeReturn(t2)
 429 jmp t0
 430 .recover:
 431 codeBlockGetter(t1)
 432 .continue:
 433 end
 434 codeBlockSetter(t1)
 435
 436 # Set up the PC.
 437 loadp CodeBlock::m_instructions[t1], t0
 438 loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
 439end
 440
 441# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
 442# Must call dispatch(0) after calling this.
 443macro functionInitialization(profileArgSkip)
 444 # Profile the arguments. Unfortunately, we have no choice but to do this. This
 445 # code is pretty horrendous because of the difference in ordering between
 446 # arguments and value profiles, the desire to have a simple loop-down-to-zero
 447 # loop, and the desire to use only three registers so as to preserve the PC and
 448 # the code block. It is likely that this code should be rewritten in a more
 449 # optimal way for architectures that have more than five registers available
 450 # for arbitrary use in the interpreter.
 451 loadi CodeBlock::m_numParameters[t1], t0
 452 addi -profileArgSkip, t0 # Use addi because that's what has the peephole
 453 assert(macro (ok) bigteq t0, 0, ok end)
 454 btiz t0, .argumentProfileDone
 455 loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
 456 muli sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
 457 negi t0
 458 lshifti 3, t0
 459 addp t2, t3
 460.argumentProfileLoop:
 461 loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
 462 subp sizeof ValueProfile, t3
 463 storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
 464 loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
 465 storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
 466 baddinz 8, t0, .argumentProfileLoop
 467.argumentProfileDone:
 468
 469 # Check stack height.
 470 loadi CodeBlock::m_numCalleeRegisters[t1], t0
 471 loadp CodeBlock::m_globalData[t1], t2
 472 loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the RegisterFile from the JITStackFrame
 473 lshifti 3, t0
 474 addp t0, cfr, t0
 475 bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK
 476
 477 # Stack height check failed - need to call a helper.
 478 callHelper(_llint_register_file_check)
 479.stackHeightOK:
 480end
 481
 482# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
 483macro functionArityCheck(doneLabel, helper)
 484 loadi PayloadOffset + ArgumentCount[cfr], t0
 485 biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
 486 cCall2(helper, cfr, PC) # This helper has a simple protocol: t0 = 0 => no error, t0 != 0 => error
 487 move t1, cfr
 488 btiz t0, .continue
 489 loadp JITStackFrame::globalData[sp], t1
 490 loadp JSGlobalData::callFrameForThrow[t1], t0
 491 jmp JSGlobalData::targetMachinePCForThrow[t1]
 492.continue:
 493 # Reload CodeBlock and PC, since the helper clobbered it.
 494 loadp CodeBlock[cfr], t1
 495 loadp CodeBlock::m_instructions[t1], t0
 496 loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
 497 jmp doneLabel
 498end
 499
 500_llint_program_prologue:
 501 prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
 502 dispatch(0)
 503
 504
 505_llint_eval_prologue:
 506 prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
 507 dispatch(0)
 508
 509
 510_llint_function_for_call_prologue:
 511 prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
 512.functionForCallBegin:
 513 functionInitialization(0)
 514 dispatch(0)
 515
 516
 517_llint_function_for_construct_prologue:
 518 prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
 519.functionForConstructBegin:
 520 functionInitialization(1)
 521 dispatch(0)
 522
 523
 524_llint_function_for_call_arity_check:
 525 prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
 526 functionArityCheck(.functionForCallBegin, _llint_helper_call_arityCheck)
 527
 528
 529_llint_function_for_construct_arity_check:
 530 prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
 531 functionArityCheck(.functionForConstructBegin, _llint_helper_construct_arityCheck)
 532
 533# Instruction implementations
 534
 535_llint_op_enter:
 536 traceExecution()
 537 loadp CodeBlock[cfr], t2
 538 loadi CodeBlock::m_numVars[t2], t2
 539 btiz t2, .opEnterDone
 540 move UndefinedTag, t0
 541 move 0, t1
 542.opEnterLoop:
 543 subi 1, t2
 544 storei t0, TagOffset[cfr, t2, 8]
 545 storei t1, PayloadOffset[cfr, t2, 8]
 546 btinz t2, .opEnterLoop
 547.opEnterDone:
 548 dispatch(1)
 549
 550
 551_llint_op_create_activation:
 552 traceExecution()
 553 loadi 4[PC], t0
 554 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateActivationDone
 555 callHelper(_llint_helper_create_activation)
 556.opCreateActivationDone:
 557 dispatch(2)
 558
 559
 560_llint_op_init_lazy_reg:
 561 traceExecution()
 562 loadi 4[PC], t0
 563 storei EmptyValueTag, TagOffset[cfr, t0, 8]
 564 storei 0, PayloadOffset[cfr, t0, 8]
 565 dispatch(2)
 566
 567
 568_llint_op_create_arguments:
 569 traceExecution()
 570 loadi 4[PC], t0
 571 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
 572 callHelper(_llint_helper_create_arguments)
 573.opCreateArgumentsDone:
 574 dispatch(2)
 575
 576
 577macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result, scratch1, scratch2, slowCase)
 578 const offsetOfMySizeClass = JSGlobalData::heap + Heap::m_objectSpace + AllocationSpace::m_markedSpace + MarkedSpace::m_preciseSizeClasses + sizeClassIndex * sizeof MarkedSpace::SizeClass
 579
 580 # FIXME: we can get the global data in one load from the stack.
 581 loadp CodeBlock[cfr], scratch1
 582 loadp CodeBlock::m_globalData[scratch1], scratch1
 583
 584 # Get the object from the free list.
 585 loadp offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1], result
 586 btpz result, slowCase
 587
 588 # Remove the object from the free list.
 589 loadp [result], scratch2
 590 storep scratch2, offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1]
 591
 592 # Initialize the object.
 593 loadp classInfoOffset[scratch1], scratch2
 594 storep scratch2, [result]
 595 storep structure, JSCell::m_structure[result]
 596 storep 0, JSObject::m_inheritorID[result]
 597 addp sizeof JSObject, result, scratch1
 598 storep scratch1, JSObject::m_propertyStorage[result]
 599end
 600
 601_llint_op_create_this:
 602 traceExecution()
 603 loadi 8[PC], t0
 604 assertNotConstant(t0)
 605 bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
 606 loadi PayloadOffset[cfr, t0, 8], t0
 607 loadp JSCell::m_structure[t0], t1
 608 bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
 609 loadp JSObject::m_inheritorID[t0], t2
 610 btpz t2, .opCreateThisSlow
 611 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
 612 loadi 4[PC], t1
 613 storei CellTag, TagOffset[cfr, t1, 8]
 614 storei t0, PayloadOffset[cfr, t1, 8]
 615 dispatch(3)
 616
 617.opCreateThisSlow:
 618 callHelper(_llint_helper_create_this)
 619 dispatch(3)
 620
 621
 622_llint_op_get_callee:
 623 traceExecution()
 624 loadi 4[PC], t0
 625 loadp PayloadOffset + Callee[cfr], t1
 626 storei CellTag, TagOffset[cfr, t0, 8]
 627 storei t1, PayloadOffset[cfr, t0, 8]
 628 dispatch(2)
 629
 630
 631_llint_op_convert_this:
 632 traceExecution()
 633 loadi 4[PC], t0
 634 bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
 635 loadi PayloadOffset[cfr, t0, 8], t0
 636 loadp JSCell::m_structure[t0], t0
 637 bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
 638 dispatch(2)
 639
 640.opConvertThisSlow:
 641 callHelper(_llint_helper_convert_this)
 642 dispatch(2)
 643
 644
 645_llint_op_new_object:
 646 traceExecution()
 647 loadp CodeBlock[cfr], t0
 648 loadp CodeBlock::m_globalObject[t0], t0
 649 loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
 650 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
 651 loadi 4[PC], t1
 652 storei CellTag, TagOffset[cfr, t1, 8]
 653 storei t0, PayloadOffset[cfr, t1, 8]
 654 dispatch(2)
 655
 656.opNewObjectSlow:
 657 callHelper(_llint_helper_new_object)
 658 dispatch(2)
 659
 660
 661_llint_op_new_array:
 662 traceExecution()
 663 callHelper(_llint_helper_new_array)
 664 dispatch(4)
 665
 666
 667_llint_op_new_array_buffer:
 668 traceExecution()
 669 callHelper(_llint_helper_new_array_buffer)
 670 dispatch(4)
 671
 672
 673_llint_op_new_regexp:
 674 traceExecution()
 675 callHelper(_llint_helper_new_regexp)
 676 dispatch(3)
 677
 678
 679_llint_op_mov:
 680 traceExecution()
 681 loadi 8[PC], t1
 682 loadi 4[PC], t0
 683 loadConstantOrVariable(t1, t2, t3)
 684 storei t2, TagOffset[cfr, t0, 8]
 685 storei t3, PayloadOffset[cfr, t0, 8]
 686 dispatch(3)
 687
 688
 689_llint_op_not:
 690 traceExecution()
 691 loadi 8[PC], t0
 692 loadi 4[PC], t1
 693 loadConstantOrVariable(t0, t2, t3)
 694 bineq t2, BooleanTag, .opNotSlow
 695 xori 1, t3
 696 storei t2, TagOffset[cfr, t1, 8]
 697 storei t3, PayloadOffset[cfr, t1, 8]
 698 dispatch(3)
 699
 700.opNotSlow:
 701 callHelper(_llint_helper_not)
 702 dispatch(3)
 703
 704
 705_llint_op_eq:
 706 traceExecution()
 707 loadi 12[PC], t2
 708 loadi 8[PC], t0
 709 loadConstantOrVariable(t2, t3, t1)
 710 loadConstantOrVariable2Reg(t0, t2, t0)
 711 bineq t2, t3, .opEqSlow
 712 bieq t2, CellTag, .opEqSlow
 713 bib t2, LowestTag, .opEqSlow
 714 loadi 4[PC], t2
 715 cieq t0, t1, t0
 716 storei BooleanTag, TagOffset[cfr, t2, 8]
 717 storei t0, PayloadOffset[cfr, t2, 8]
 718 dispatch(4)
 719
 720.opEqSlow:
 721 callHelper(_llint_helper_eq)
 722 dispatch(4)
 723
 724
 725_llint_op_eq_null:
 726 traceExecution()
 727 loadi 8[PC], t0
 728 loadi 4[PC], t3
 729 assertNotConstant(t0)
 730 loadi TagOffset[cfr, t0, 8], t1
 731 loadi PayloadOffset[cfr, t0, 8], t0
 732 bineq t1, CellTag, .opEqNullImmediate
 733 loadp JSCell::m_structure[t0], t1
 734 tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
 735 jmp .opEqNullNotImmediate
 736.opEqNullImmediate:
 737 cieq t1, NullTag, t2
 738 cieq t1, UndefinedTag, t1
 739 ori t2, t1
 740.opEqNullNotImmediate:
 741 storei BooleanTag, TagOffset[cfr, t3, 8]
 742 storei t1, PayloadOffset[cfr, t3, 8]
 743 dispatch(3)
 744
 745
 746_llint_op_neq:
 747 traceExecution()
 748 loadi 12[PC], t2
 749 loadi 8[PC], t0
 750 loadConstantOrVariable(t2, t3, t1)
 751 loadConstantOrVariable2Reg(t0, t2, t0)
 752 bineq t2, t3, .opNeqSlow
 753 bieq t2, CellTag, .opNeqSlow
 754 bib t2, LowestTag, .opNeqSlow
 755 loadi 4[PC], t2
 756 cineq t0, t1, t0
 757 storei BooleanTag, TagOffset[cfr, t2, 8]
 758 storei t0, PayloadOffset[cfr, t2, 8]
 759 dispatch(4)
 760
 761.opNeqSlow:
 762 callHelper(_llint_helper_neq)
 763 dispatch(4)
 764
 765
 766_llint_op_neq_null:
 767 traceExecution()
 768 loadi 8[PC], t0
 769 loadi 4[PC], t3
 770 assertNotConstant(t0)
 771 loadi TagOffset[cfr, t0, 8], t1
 772 loadi PayloadOffset[cfr, t0, 8], t0
 773 bineq t1, CellTag, .opNeqNullImmediate
 774 loadp JSCell::m_structure[t0], t1
 775 tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
 776 jmp .opNeqNullNotImmediate
 777.opNeqNullImmediate:
 778 cineq t1, NullTag, t2
 779 cineq t1, UndefinedTag, t1
 780 andi t2, t1
 781.opNeqNullNotImmediate:
 782 storei BooleanTag, TagOffset[cfr, t3, 8]
 783 storei t1, PayloadOffset[cfr, t3, 8]
 784 dispatch(3)
 785
 786
 787macro strictEq(equalityOperation, helper)
 788 loadi 12[PC], t2
 789 loadi 8[PC], t0
 790 loadConstantOrVariable(t2, t3, t1)
 791 loadConstantOrVariable2Reg(t0, t2, t0)
 792 bineq t2, t3, .slow
 793 bib t2, LowestTag, .slow
 794 bineq t2, CellTag, .notString
 795 loadp JSCell::m_structure[t0], t2
 796 loadp JSCell::m_structure[t1], t3
 797 bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
 798 bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
 799.notString:
 800 loadi 4[PC], t2
 801 equalityOperation(t0, t1, t0)
 802 storei BooleanTag, TagOffset[cfr, t2, 8]
 803 storei t0, PayloadOffset[cfr, t2, 8]
 804 dispatch(4)
 805
 806.slow:
 807 callHelper(helper)
 808 dispatch(4)
 809end
 810
 811_llint_op_stricteq:
 812 traceExecution()
 813 strictEq(macro (left, right, result) cieq left, right, result end, _llint_helper_stricteq)
 814
 815
 816_llint_op_nstricteq:
 817 traceExecution()
 818 strictEq(macro (left, right, result) cineq left, right, result end, _llint_helper_nstricteq)
 819
 820
 821_llint_op_less:
 822 traceExecution()
 823 callHelper(_llint_helper_less)
 824 dispatch(4)
 825
 826
 827_llint_op_lesseq:
 828 traceExecution()
 829 callHelper(_llint_helper_lesseq)
 830 dispatch(4)
 831
 832
 833_llint_op_greater:
 834 traceExecution()
 835 callHelper(_llint_helper_greater)
 836 dispatch(4)
 837
 838
 839_llint_op_greatereq:
 840 traceExecution()
 841 callHelper(_llint_helper_greatereq)
 842 dispatch(4)
 843
 844
 845_llint_op_pre_inc:
 846 traceExecution()
 847 loadi 4[PC], t0
 848 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
 849 loadi PayloadOffset[cfr, t0, 8], t1
 850 baddio 1, t1, .opPreIncSlow
 851 storei t1, PayloadOffset[cfr, t0, 8]
 852 dispatch(2)
 853
 854.opPreIncSlow:
 855 callHelper(_llint_helper_pre_inc)
 856 dispatch(2)
 857
 858
 859_llint_op_pre_dec:
 860 traceExecution()
 861 loadi 4[PC], t0
 862 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
 863 loadi PayloadOffset[cfr, t0, 8], t1
 864 bsubio 1, t1, .opPreDecSlow
 865 storei t1, PayloadOffset[cfr, t0, 8]
 866 dispatch(2)
 867
 868.opPreDecSlow:
 869 callHelper(_llint_helper_pre_dec)
 870 dispatch(2)
 871
 872
 873_llint_op_post_inc:
 874 traceExecution()
 875 loadi 8[PC], t0
 876 loadi 4[PC], t1
 877 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
 878 bieq t0, t1, .opPostIncDone
 879 loadi PayloadOffset[cfr, t0, 8], t2
 880 move t2, t3
 881 baddio 1, t3, .opPostIncSlow
 882 storei Int32Tag, TagOffset[cfr, t1, 8]
 883 storei t2, PayloadOffset[cfr, t1, 8]
 884 storei t3, PayloadOffset[cfr, t0, 8]
 885.opPostIncDone:
 886 dispatch(3)
 887
 888.opPostIncSlow:
 889 callHelper(_llint_helper_post_inc)
 890 dispatch(3)
 891
 892
 893_llint_op_post_dec:
 894 traceExecution()
 895 loadi 8[PC], t0
 896 loadi 4[PC], t1
 897 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
 898 bieq t0, t1, .opPostDecDone
 899 loadi PayloadOffset[cfr, t0, 8], t2
 900 move t2, t3
 901 bsubio 1, t3, .opPostDecSlow
 902 storei Int32Tag, TagOffset[cfr, t1, 8]
 903 storei t2, PayloadOffset[cfr, t1, 8]
 904 storei t3, PayloadOffset[cfr, t0, 8]
 905.opPostDecDone:
 906 dispatch(3)
 907
 908.opPostDecSlow:
 909 callHelper(_llint_helper_post_dec)
 910 dispatch(3)
 911
 912
 913_llint_op_to_jsnumber:
 914 traceExecution()
 915 loadi 8[PC], t0
 916 loadi 4[PC], t1
 917 loadConstantOrVariable(t0, t2, t3)
 918 bieq t2, Int32Tag, .opToJsnumberIsInt
 919 biaeq t2, EmptyValueTag, .opToJsnumberSlow
 920.opToJsnumberIsInt:
 921 storei t2, TagOffset[cfr, t1, 8]
 922 storei t3, PayloadOffset[cfr, t1, 8]
 923 dispatch(3)
 924
 925.opToJsnumberSlow:
 926 callHelper(_llint_helper_to_jsnumber)
 927 dispatch(3)
 928
 929
 930_llint_op_negate:
 931 traceExecution()
 932 loadi 8[PC], t0
 933 loadi 4[PC], t3
 934 loadConstantOrVariable(t0, t1, t2)
 935 bineq t1, Int32Tag, .opNegateSrcNotInt
 936 btiz t2, 0x7fffffff, .opNegateSlow
 937 negi t2
 938 storei Int32Tag, TagOffset[cfr, t3, 8]
 939 storei t2, PayloadOffset[cfr, t3, 8]
 940 dispatch(3)
 941.opNegateSrcNotInt:
 942 bia t1, LowestTag, .opNegateSlow
 943 xori 0x80000000, t1
 944 storei t1, TagOffset[cfr, t3, 8]
 945 storei t2, PayloadOffset[cfr, t3, 8]
 946 dispatch(3)
 947
 948.opNegateSlow:
 949 callHelper(_llint_helper_negate)
 950 dispatch(3)
 951
 952
 953macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, helper)
 954 loadi 12[PC], t2
 955 loadi 8[PC], t0
 956 loadConstantOrVariable(t2, t3, t1)
 957 loadConstantOrVariable2Reg(t0, t2, t0)
 958 bineq t2, Int32Tag, .op1NotInt
 959 bineq t3, Int32Tag, .op2NotInt
 960 loadi 4[PC], t2
 961 integerOperationAndStore(t3, t1, t0, .slow, t2)
 962 dispatch(5)
 963
 964.op1NotInt:
 965 # First operand is definitely not an int, the second operand could be anything.
 966 bia t2, LowestTag, .slow
 967 bib t3, LowestTag, .op1NotIntOp2Double
 968 bineq t3, Int32Tag, .slow
 969 ci2d t1, ft1
 970 jmp .op1NotIntReady
 971.op1NotIntOp2Double:
 972 fii2d t1, t3, ft1
 973.op1NotIntReady:
 974 loadi 4[PC], t1
 975 fii2d t0, t2, ft0
 976 doubleOperation(ft1, ft0)
 977 stored ft0, [cfr, t1, 8]
 978 dispatch(5)
 979
 980.op2NotInt:
 981 # First operand is definitely an int, the second operand is definitely not.
 982 loadi 4[PC], t2
 983 bia t3, LowestTag, .slow
 984 ci2d t0, ft0
 985 fii2d t1, t3, ft1
 986 doubleOperation(ft1, ft0)
 987 stored ft0, [cfr, t2, 8]
 988 dispatch(5)
 989
 990.slow:
 991 callHelper(helper)
 992 dispatch(5)
 993end
 994
 995macro binaryOp(integerOperation, doubleOperation, helper)
 996 binaryOpCustomStore(
 997 macro (int32Tag, left, right, slow, index)
 998 integerOperation(left, right, slow)
 999 storei int32Tag, TagOffset[cfr, index, 8]
 1000 storei right, PayloadOffset[cfr, index, 8]
 1001 end,
 1002 doubleOperation, helper)
 1003end
 1004
 1005_llint_op_add:
 1006 traceExecution()
 1007 binaryOp(
 1008 macro (left, right, slow) baddio left, right, slow end,
 1009 macro (left, right) addd left, right end,
 1010 _llint_helper_add)
 1011
 1012
 1013_llint_op_mul:
 1014 traceExecution()
 1015 binaryOpCustomStore(
 1016 macro (int32Tag, left, right, slow, index)
 1017 const scratch = int32Tag # We know that we can reuse the int32Tag register since it has a constant.
 1018 move right, scratch
 1019 bmulio left, scratch, slow
 1020 btinz scratch, .done
 1021 bilt left, 0, .slow
 1022 bilt right, 0, .slow
 1023 .done:
 1024 storei Int32Tag, TagOffset[cfr, index, 8]
 1025 storei scratch, PayloadOffset[cfr, index, 8]
 1026 end,
 1027 macro (left, right) muld left, right end,
 1028 _llint_helper_mul)
 1029
 1030
 1031_llint_op_sub:
 1032 traceExecution()
 1033 binaryOp(
 1034 macro (left, right, slow) bsubio left, right, slow end,
 1035 macro (left, right) subd left, right end,
 1036 _llint_helper_sub)
 1037
 1038
 1039_llint_op_div:
 1040 traceExecution()
 1041 binaryOpCustomStore(
 1042 macro (int32Tag, left, right, slow, index)
 1043 ci2d left, ft0
 1044 ci2d right, ft1
 1045 divd ft0, ft1
 1046 bcd2i ft1, right, .notInt
 1047 storei int32Tag, TagOffset[cfr, index, 8]
 1048 storei right, PayloadOffset[cfr, index, 8]
 1049 jmp .done
 1050 .notInt:
 1051 stored ft1, [cfr, index, 8]
 1052 .done:
 1053 end,
 1054 macro (left, right) divd left, right end,
 1055 _llint_helper_div)
 1056
 1057
 1058_llint_op_mod:
 1059 traceExecution()
 1060 callHelper(_llint_helper_mod)
 1061 dispatch(4)
 1062
 1063
 1064macro bitOp(operation, helper, advance)
 1065 loadi 12[PC], t2
 1066 loadi 8[PC], t0
 1067 loadConstantOrVariable(t2, t3, t1)
 1068 loadConstantOrVariable2Reg(t0, t2, t0)
 1069 bineq t3, Int32Tag, .slow
 1070 bineq t2, Int32Tag, .slow
 1071 loadi 4[PC], t2
 1072 operation(t1, t0, .slow)
 1073 storei t3, TagOffset[cfr, t2, 8]
 1074 storei t0, PayloadOffset[cfr, t2, 8]
 1075 dispatch(advance)
 1076
 1077.slow:
 1078 callHelper(helper)
 1079 dispatch(advance)
 1080end
 1081
 1082_llint_op_lshift:
 1083 traceExecution()
 1084 bitOp(
 1085 macro (left, right, slow) lshifti left, right end,
 1086 _llint_helper_lshift,
 1087 4)
 1088
 1089
 1090_llint_op_rshift:
 1091 traceExecution()
 1092 bitOp(
 1093 macro (left, right, slow) rshifti left, right end,
 1094 _llint_helper_rshift,
 1095 4)
 1096
 1097
 1098_llint_op_urshift:
 1099 traceExecution()
 1100 bitOp(
 1101 macro (left, right, slow)
 1102 urshifti left, right
 1103 bilt right, 0, slow
 1104 end,
 1105 _llint_helper_urshift,
 1106 4)
 1107
 1108
 1109_llint_op_bitand:
 1110 traceExecution()
 1111 bitOp(
 1112 macro (left, right, slow) andi left, right end,
 1113 _llint_helper_bitand,
 1114 5)
 1115
 1116
 1117_llint_op_bitxor:
 1118 traceExecution()
 1119 bitOp(
 1120 macro (left, right, slow) xori left, right end,
 1121 _llint_helper_bitxor,
 1122 5)
 1123
 1124
 1125_llint_op_bitor:
 1126 traceExecution()
 1127 bitOp(
 1128 macro (left, right, slow) ori left, right end,
 1129 _llint_helper_bitor,
 1130 5)
 1131
 1132
 1133_llint_op_bitnot:
 1134 traceExecution()
 1135 loadi 8[PC], t1
 1136 loadi 4[PC], t0
 1137 loadConstantOrVariable(t1, t2, t3)
 1138 bineq t2, Int32Tag, .opBitnotSlow
 1139 noti t3
 1140 storei t2, TagOffset[cfr, t0, 8]
 1141 storei t3, PayloadOffset[cfr, t0, 8]
 1142 dispatch(3)
 1143
 1144.opBitnotSlow:
 1145 callHelper(_llint_helper_bitnot)
 1146 dispatch(3)
 1147
 1148
 1149_llint_op_check_has_instance:
 1150 traceExecution()
 1151 loadi 4[PC], t1
 1152 loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
 1153 loadp JSCell::m_structure[t0], t0
 1154 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
 1155 dispatch(2)
 1156
 1157.opCheckHasInstanceSlow:
 1158 callHelper(_llint_helper_check_has_instance)
 1159 dispatch(2)
 1160
 1161
 1162_llint_op_instanceof:
 1163 traceExecution()
 1164 # Check that baseVal implements the default HasInstance behavior.
 1165 # FIXME: This should be deprecated.
 1166 loadi 12[PC], t1
 1167 loadConstantOrVariablePayloadUnchecked(t1, t0)
 1168 loadp JSCell::m_structure[t0], t0
 1169 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
 1170
 1171 # Actually do the work.
 1172 loadi 16[PC], t0
 1173 loadi 4[PC], t3
 1174 loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
 1175 loadp JSCell::m_structure[t1], t2
 1176 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
 1177 loadi 8[PC], t0
 1178 loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
 1179
 1180 # Register state: t1 = prototype, t2 = value
 1181 move 1, t0
 1182.opInstanceofLoop:
 1183 loadp JSCell::m_structure[t2], t2
 1184 loadi Structure::m_prototype + PayloadOffset[t2], t2
 1185 bpeq t2, t1, .opInstanceofDone
 1186 btinz t2, .opInstanceofLoop
 1187
 1188 move 0, t0
 1189.opInstanceofDone:
 1190 storei BooleanTag, TagOffset[cfr, t3, 8]
 1191 storei t0, PayloadOffset[cfr, t3, 8]
 1192 dispatch(5)
 1193
 1194.opInstanceofSlow:
 1195 callHelper(_llint_helper_instanceof)
 1196 dispatch(5)
 1197
 1198
 1199_llint_op_typeof:
 1200 traceExecution()
 1201 callHelper(_llint_helper_typeof)
 1202 dispatch(3)
 1203
 1204
 1205_llint_op_is_undefined:
 1206 traceExecution()
 1207 callHelper(_llint_helper_is_undefined)
 1208 dispatch(3)
 1209
 1210
 1211_llint_op_is_boolean:
 1212 traceExecution()
 1213 callHelper(_llint_helper_is_boolean)
 1214 dispatch(3)
 1215
 1216
 1217_llint_op_is_number:
 1218 traceExecution()
 1219 callHelper(_llint_helper_is_number)
 1220 dispatch(3)
 1221
 1222
 1223_llint_op_is_string:
 1224 traceExecution()
 1225 callHelper(_llint_helper_is_string)
 1226 dispatch(3)
 1227
 1228
 1229_llint_op_is_object:
 1230 traceExecution()
 1231 callHelper(_llint_helper_is_object)
 1232 dispatch(3)
 1233
 1234
 1235_llint_op_is_function:
 1236 traceExecution()
 1237 callHelper(_llint_helper_is_function)
 1238 dispatch(3)
 1239
 1240
 1241_llint_op_in:
 1242 traceExecution()
 1243 callHelper(_llint_helper_in)
 1244 dispatch(4)
 1245
 1246
 1247_llint_op_resolve:
 1248 traceExecution()
 1249 callHelper(_llint_helper_resolve)
 1250 dispatch(4)
 1251
 1252
 1253_llint_op_resolve_skip:
 1254 traceExecution()
 1255 callHelper(_llint_helper_resolve_skip)
 1256 dispatch(5)
 1257
 1258
 1259macro resolveGlobal(size, slow)
 1260 # Operands are as follows:
 1261 # 4[PC] Destination for the load.
 1262 # 8[PC] Property identifier index in the code block.
 1263 # 12[PC] Structure pointer, initialized to 0 by bytecode generator.
 1264 # 16[PC] Offset in global object, initialized to 0 by bytecode generator.
 1265 loadp CodeBlock[cfr], t0
 1266 loadp CodeBlock::m_globalObject[t0], t0
 1267 loadp JSCell::m_structure[t0], t1
 1268 bpneq t1, 12[PC], slow
 1269 loadi 16[PC], t1
 1270 loadp JSObject::m_propertyStorage[t0], t0
 1271 loadi TagOffset[t0, t1, 8], t2
 1272 loadi PayloadOffset[t0, t1, 8], t3
 1273 loadi 4[PC], t0
 1274 storei t2, TagOffset[cfr, t0, 8]
 1275 storei t3, PayloadOffset[cfr, t0, 8]
 1276 loadi (size - 1) * 4[PC], t0
 1277 valueProfile(t2, t3, t0)
 1278end
 1279
 1280_llint_op_resolve_global:
 1281 traceExecution()
 1282 resolveGlobal(6, .opResolveGlobalSlow)
 1283 dispatch(6)
 1284
 1285.opResolveGlobalSlow:
 1286 callHelper(_llint_helper_resolve_global)
 1287 dispatch(6)
 1288
 1289
 1290# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
 1291# scopes as they are traversed. scopeCheck() is called with two arguments: the register
 1292# holding the scope, and a register that can be used for scratch. Note that this does not
 1293# use t3, so you can hold stuff in t3 if need be.
 1294macro getScope(deBruijinIndexOperand, scopeCheck)
 1295 loadp ScopeChain + PayloadOffset[cfr], t0
 1296 loadi deBruijinIndexOperand, t2
 1297
 1298 btiz t2, .done
 1299
 1300 loadp CodeBlock[cfr], t1
 1301 bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
 1302 btbz CodeBlock::m_needsFullScopeChain[t1], .loop
 1303
 1304 loadi CodeBlock::m_activationRegister[t1], t1
 1305
 1306 # Need to conditionally skip over one scope.
 1307 bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
 1308 scopeCheck(t0, t1)
 1309 loadp ScopeChainNode::next[t0], t0
 1310.noActivation:
 1311 subi 1, t2
 1312
 1313 btiz t2, .done
 1314.loop:
 1315 scopeCheck(t0, t1)
 1316 loadp ScopeChainNode::next[t0], t0
 1317 subi 1, t2
 1318 btinz t2, .loop
 1319
 1320.done:
 1321end
 1322
 1323_llint_op_resolve_global_dynamic:
 1324 traceExecution()
 1325 loadp JITStackFrame::globalData[sp], t3
 1326 loadp JSGlobalData::activationStructure[t3], t3
 1327 getScope(
 1328 20[PC],
 1329 macro (scope, scratch)
 1330 loadp ScopeChainNode::object[scope], scratch
 1331 bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
 1332 end)
 1333 resolveGlobal(7, .opResolveGlobalDynamicSlow)
 1334 dispatch(7)
 1335
 1336.opResolveGlobalDynamicSuperSlow:
 1337 callHelper(_llint_helper_resolve_for_resolve_global_dynamic)
 1338 dispatch(7)
 1339
 1340.opResolveGlobalDynamicSlow:
 1341 callHelper(_llint_helper_resolve_global_dynamic)
 1342 dispatch(7)
 1343
 1344
 1345_llint_op_get_scoped_var:
 1346 traceExecution()
 1347 # Operands are as follows:
 1348 # 4[PC] Destination for the load.
 1349 # 8[PC] Index of register in the scope.
 1350 # 12[PC] De Bruijin index.
 1351 getScope(12[PC], macro (scope, scratch) end)
 1352 loadi 4[PC], t1
 1353 loadi 8[PC], t2
 1354 loadp ScopeChainNode::object[t0], t0
 1355 loadp JSVariableObject::m_registers[t0], t0
 1356 loadi TagOffset[t0, t2, 8], t3
 1357 loadi PayloadOffset[t0, t2, 8], t0
 1358 storei t3, TagOffset[cfr, t1, 8]
 1359 storei t0, PayloadOffset[cfr, t1, 8]
 1360 loadi 16[PC], t1
 1361 valueProfile(t3, t0, t1)
 1362 dispatch(5)
 1363
 1364
 1365_llint_op_put_scoped_var:
 1366 traceExecution()
 1367 getScope(8[PC], macro (scope, scratch) end)
 1368 loadi 12[PC], t1
 1369 loadConstantOrVariable(t1, t3, t2)
 1370 loadi 4[PC], t1
 1371 writeBarrier(t3, t2)
 1372 loadp ScopeChainNode::object[t0], t0
 1373 loadp JSVariableObject::m_registers[t0], t0
 1374 storei t3, TagOffset[t0, t1, 8]
 1375 storei t2, PayloadOffset[t0, t1, 8]
 1376 dispatch(4)
 1377
 1378
 1379_llint_op_get_global_var:
 1380 traceExecution()
 1381 loadi 8[PC], t1
 1382 loadi 4[PC], t3
 1383 loadp CodeBlock[cfr], t0
 1384 loadp CodeBlock::m_globalObject[t0], t0
 1385 loadp JSGlobalObject::m_registers[t0], t0
 1386 loadi TagOffset[t0, t1, 8], t2
 1387 loadi PayloadOffset[t0, t1, 8], t1
 1388 storei t2, TagOffset[cfr, t3, 8]
 1389 storei t1, PayloadOffset[cfr, t3, 8]
 1390 loadi 12[PC], t3
 1391 valueProfile(t2, t1, t3)
 1392 dispatch(4)
 1393
 1394
 1395_llint_op_put_global_var:
 1396 traceExecution()
 1397 loadi 8[PC], t1
 1398 loadp CodeBlock[cfr], t0
 1399 loadp CodeBlock::m_globalObject[t0], t0
 1400 loadp JSGlobalObject::m_registers[t0], t0
 1401 loadConstantOrVariable(t1, t2, t3)
 1402 loadi 4[PC], t1
 1403 writeBarrier(t2, t3)
 1404 storei t2, TagOffset[t0, t1, 8]
 1405 storei t3, PayloadOffset[t0, t1, 8]
 1406 dispatch(3)
 1407
 1408
 1409_llint_op_resolve_base:
 1410 traceExecution()
 1411 callHelper(_llint_helper_resolve_base)
 1412 dispatch(5)
 1413
 1414
 1415_llint_op_ensure_property_exists:
 1416 traceExecution()
 1417 callHelper(_llint_helper_ensure_property_exists)
 1418 dispatch(3)
 1419
 1420
 1421_llint_op_resolve_with_base:
 1422 traceExecution()
 1423 callHelper(_llint_helper_resolve_with_base)
 1424 dispatch(5)
 1425
 1426
 1427_llint_op_resolve_with_this:
 1428 traceExecution()
 1429 callHelper(_llint_helper_resolve_with_this)
 1430 dispatch(5)
 1431
 1432
 1433_llint_op_get_by_id:
 1434 traceExecution()
 1435 # We only do monomorphic get_by_id caching for now, and we do not modify the
 1436 # opcode. We do, however, allow for the cache to change anytime if fails, since
 1437 # ping-ponging is free. At best we get lucky and the get_by_id will continue
 1438 # to take fast path on the new cache. At worst we take slow path, which is what
 1439 # we would have been doing anyway.
 1440 loadi 8[PC], t0
 1441 loadi 16[PC], t1
 1442 loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
 1443 loadi 20[PC], t2
 1444 loadp JSObject::m_propertyStorage[t3], t0
 1445 bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
 1446 loadi 4[PC], t1
 1447 loadi TagOffset[t0, t2], t3
 1448 loadi PayloadOffset[t0, t2], t2
 1449 storei t3, TagOffset[cfr, t1, 8]
 1450 storei t2, PayloadOffset[cfr, t1, 8]
 1451 loadi 32[PC], t1
 1452 valueProfile(t3, t2, t1)
 1453 dispatch(9)
 1454
 1455.opGetByIdSlow:
 1456 callHelper(_llint_helper_get_by_id)
 1457 dispatch(9)
 1458
 1459
 1460_llint_op_get_arguments_length:
 1461 traceExecution()
 1462 loadi 8[PC], t0
 1463 loadi 4[PC], t1
 1464 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
 1465 loadi ArgumentCount + PayloadOffset[cfr], t2
 1466 subi 1, t2
 1467 storei Int32Tag, TagOffset[cfr, t1, 8]
 1468 storei t2, PayloadOffset[cfr, t1, 8]
 1469 dispatch(4)
 1470
 1471.opGetArgumentsLengthSlow:
 1472 callHelper(_llint_helper_get_arguments_length)
 1473 dispatch(4)
 1474
 1475
 1476_llint_op_put_by_id:
 1477 traceExecution()
 1478 loadi 4[PC], t3
 1479 loadi 16[PC], t1
 1480 loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
 1481 loadi 12[PC], t2
 1482 loadp JSObject::m_propertyStorage[t0], t3
 1483 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
 1484 loadi 20[PC], t1
 1485 loadConstantOrVariable2Reg(t2, t0, t2)
 1486 writeBarrier(t0, t2)
 1487 storei t0, TagOffset[t3, t1]
 1488 storei t2, PayloadOffset[t3, t1]
 1489 dispatch(9)
 1490
 1491.opPutByIdSlow:
 1492 callHelper(_llint_helper_put_by_id)
 1493 dispatch(9)
 1494
 1495
 1496macro putByIdTransition(additionalChecks)
 1497 traceExecution()
 1498 loadi 4[PC], t3
 1499 loadi 16[PC], t1
 1500 loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
 1501 loadi 12[PC], t2
 1502 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
 1503 additionalChecks(t1, t3, .opPutByIdSlow)
 1504 loadi 20[PC], t1
 1505 loadp JSObject::m_propertyStorage[t0], t3
 1506 addp t1, t3
 1507 loadConstantOrVariable2Reg(t2, t1, t2)
 1508 writeBarrier(t1, t2)
 1509 storei t1, TagOffset[t3]
 1510 loadi 24[PC], t1
 1511 storei t2, PayloadOffset[t3]
 1512 storep t1, JSCell::m_structure[t0]
 1513 dispatch(9)
 1514end
 1515
 1516_llint_op_put_by_id_transition_direct:
 1517 putByIdTransition(macro (oldStructure, scratch, slow) end)
 1518
 1519
 1520_llint_op_put_by_id_transition_normal:
 1521 putByIdTransition(
 1522 macro (oldStructure, scratch, slow)
 1523 const protoCell = oldStructure # Reusing the oldStructure register for the proto
 1524
 1525 loadp 28[PC], scratch
 1526 assert(macro (ok) btpnz scratch, ok end)
 1527 loadp StructureChain::m_vector[scratch], scratch
 1528 assert(macro (ok) btpnz scratch, ok end)
 1529 bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
 1530 .loop:
 1531 loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
 1532 loadp JSCell::m_structure[protoCell], oldStructure
 1533 bpneq oldStructure, [scratch], slow
 1534 addp 4, scratch
 1535 bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
 1536 .done:
 1537 end)
 1538
 1539
 1540_llint_op_del_by_id:
 1541 traceExecution()
 1542 callHelper(_llint_helper_del_by_id)
 1543 dispatch(4)
 1544
 1545
 1546_llint_op_get_by_val:
 1547 traceExecution()
 1548 loadp CodeBlock[cfr], t1
 1549 loadi 8[PC], t2
 1550 loadi 12[PC], t3
 1551 loadp CodeBlock::m_globalData[t1], t1
 1552 loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
 1553 loadp JSGlobalData::jsArrayClassInfo[t1], t2
 1554 loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
 1555 bpneq [t0], t2, .opGetByValSlow
 1556 loadp JSArray::m_storage[t0], t3
 1557 biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
 1558 loadi 4[PC], t0
 1559 loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
 1560 loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
 1561 bieq t2, EmptyValueTag, .opGetByValSlow
 1562 storei t2, TagOffset[cfr, t0, 8]
 1563 storei t1, PayloadOffset[cfr, t0, 8]
 1564 loadi 16[PC], t0
 1565 valueProfile(t2, t1, t0)
 1566 dispatch(5)
 1567
 1568.opGetByValSlow:
 1569 callHelper(_llint_helper_get_by_val)
 1570 dispatch(5)
 1571
 1572
 1573_llint_op_get_argument_by_val:
 1574 traceExecution()
 1575 loadi 8[PC], t0
 1576 loadi 12[PC], t1
 1577 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
 1578 loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
 1579 addi 1, t2
 1580 loadi ArgumentCount + PayloadOffset[cfr], t1
 1581 biaeq t2, t1, .opGetArgumentByValSlow
 1582 negi t2
 1583 loadi 4[PC], t3
 1584 loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
 1585 loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
 1586 storei t0, TagOffset[cfr, t3, 8]
 1587 storei t1, PayloadOffset[cfr, t3, 8]
 1588 dispatch(4)
 1589
 1590.opGetArgumentByValSlow:
 1591 callHelper(_llint_helper_get_argument_by_val)
 1592 dispatch(4)
 1593
 1594
 1595_llint_op_get_by_pname:
 1596 traceExecution()
 1597 loadi 12[PC], t0
 1598 loadConstantOrVariablePayload(t0, CellTag, t1, .opGetByPnameSlow)
 1599 loadi 16[PC], t0
 1600 bpneq t1, PayloadOffset[cfr, t0, 8], .opGetByPnameSlow
 1601 loadi 8[PC], t0
 1602 loadConstantOrVariablePayload(t0, CellTag, t2, .opGetByPnameSlow)
 1603 loadi 20[PC], t0
 1604 loadi PayloadOffset[cfr, t0, 8], t3
 1605 loadp JSCell::m_structure[t2], t0
 1606 bpneq t0, JSPropertyNameIterator::m_cachedStructure[t3], .opGetByPnameSlow
 1607 loadi 24[PC], t0
 1608 loadi [cfr, t0, 8], t0
 1609 subi 1, t0
 1610 biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
 1611 loadp JSObject::m_propertyStorage[t2], t2
 1612 loadi TagOffset[t2, t0, 8], t1
 1613 loadi PayloadOffset[t2, t0, 8], t3
 1614 loadi 4[PC], t0
 1615 storei t1, TagOffset[cfr, t0, 8]
 1616 storei t3, PayloadOffset[cfr, t0, 8]
 1617 dispatch(7)
 1618
 1619.opGetByPnameSlow:
 1620 callHelper(_llint_helper_get_by_pname)
 1621 dispatch(7)
 1622
 1623
 1624_llint_op_put_by_val:
 1625 traceExecution()
 1626 loadi 4[PC], t0
 1627 loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
 1628 loadi 8[PC], t0
 1629 loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
 1630 loadp CodeBlock[cfr], t0
 1631 loadp CodeBlock::m_globalData[t0], t0
 1632 loadp JSGlobalData::jsArrayClassInfo[t0], t0
 1633 bpneq [t1], t0, .opPutByValSlow
 1634 biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
 1635 loadp JSArray::m_storage[t1], t0
 1636 bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
 1637.opPutByValStoreResult:
 1638 loadi 12[PC], t3
 1639 loadConstantOrVariable2Reg(t3, t1, t3)
 1640 writeBarrier(t1, t3)
 1641 storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
 1642 storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
 1643 dispatch(4)
 1644
 1645.opPutByValEmpty:
 1646 addi 1, ArrayStorage::m_numValuesInVector[t0]
 1647 bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
 1648 addi 1, t2, t1
 1649 storei t1, ArrayStorage::m_length[t0]
 1650 jmp .opPutByValStoreResult
 1651
 1652.opPutByValSlow:
 1653 callHelper(_llint_helper_put_by_val)
 1654 dispatch(4)
 1655
 1656
 1657_llint_op_del_by_val:
 1658 traceExecution()
 1659 callHelper(_llint_helper_del_by_val)
 1660 dispatch(4)
 1661
 1662
 1663_llint_op_put_by_index:
 1664 traceExecution()
 1665 callHelper(_llint_helper_put_by_index)
 1666 dispatch(4)
 1667
 1668
 1669_llint_op_put_getter:
 1670 traceExecution()
 1671 callHelper(_llint_helper_put_getter)
 1672 dispatch(4)
 1673
 1674
 1675_llint_op_put_setter:
 1676 traceExecution()
 1677 callHelper(_llint_helper_put_setter)
 1678 dispatch(4)
 1679
 1680
 1681_llint_op_loop:
 1682 nop
 1683_llint_op_jmp:
 1684 traceExecution()
 1685 dispatchBranch(4[PC])
 1686
 1687
 1688_llint_op_jmp_scopes:
 1689 traceExecution()
 1690 callHelper(_llint_helper_jmp_scopes)
 1691 dispatch(0)
 1692
 1693
 1694macro jumpTrueOrFalse(conditionOp, slow)
 1695 loadi 4[PC], t1
 1696 loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
 1697 conditionOp(t0, .target)
 1698 dispatch(3)
 1699
 1700.target:
 1701 dispatchBranch(8[PC])
 1702
 1703.slow:
 1704 callHelper(slow)
 1705 dispatch(0)
 1706end
 1707
 1708_llint_op_loop_if_true:
 1709 nop
 1710_llint_op_jtrue:
 1711 traceExecution()
 1712 jumpTrueOrFalse(
 1713 macro (value, target) btinz value, target end,
 1714 _llint_helper_jtrue)
 1715
 1716
 1717_llint_op_loop_if_false:
 1718 nop
 1719_llint_op_jfalse:
 1720 traceExecution()
 1721 jumpTrueOrFalse(
 1722 macro (value, target) btiz value, target end,
 1723 _llint_helper_jfalse)
 1724
 1725
 1726macro equalNull(cellHandler, immediateHandler)
 1727 loadi 4[PC], t0
 1728 loadi TagOffset[cfr, t0, 8], t1
 1729 loadi PayloadOffset[cfr, t0, 8], t0
 1730 bineq t1, CellTag, .immediate
 1731 loadp JSCell::m_structure[t0], t2
 1732 cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
 1733 dispatch(3)
 1734
 1735.target:
 1736 dispatchBranch(8[PC])
 1737
 1738.immediate:
 1739 ori 1, t1
 1740 immediateHandler(t1, .target)
 1741 dispatch(3)
 1742end
 1743
 1744_llint_op_jeq_null:
 1745 traceExecution()
 1746 equalNull(
 1747 macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
 1748 macro (value, target) bieq value, NullTag, target end)
 1749
 1750
 1751_llint_op_jneq_null:
 1752 traceExecution()
 1753 equalNull(
 1754 macro (value, target) btbz value, MasqueradesAsUndefined, target end,
 1755 macro (value, target) bineq value, NullTag, target end)
 1756
 1757
 1758_llint_op_jneq_ptr:
 1759 traceExecution()
 1760 loadi 4[PC], t0
 1761 loadi 8[PC], t1
 1762 bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
 1763 bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
 1764.opJneqPtrBranch:
 1765 dispatchBranch(12[PC])
 1766.opJneqPtrFallThrough:
 1767 dispatch(4)
 1768
 1769
 1770macro compare(integerCompare, doubleCompare, helper)
 1771 loadi 4[PC], t2
 1772 loadi 8[PC], t3
 1773 loadConstantOrVariable(t2, t0, t1)
 1774 loadConstantOrVariable2Reg(t3, t2, t3)
 1775 bineq t0, Int32Tag, .op1NotInt
 1776 bineq t2, Int32Tag, .op2NotInt
 1777 integerCompare(t1, t3, .jumpTarget)
 1778 dispatch(4)
 1779
 1780.op1NotInt:
 1781 bia t0, LowestTag, .slow
 1782 bib t2, LowestTag, .op1NotIntOp2Double
 1783 bineq t2, Int32Tag, .slow
 1784 ci2d t3, ft1
 1785 jmp .op1NotIntReady
 1786.op1NotIntOp2Double:
 1787 fii2d t3, t2, ft1
 1788.op1NotIntReady:
 1789 fii2d t1, t0, ft0
 1790 doubleCompare(ft0, ft1, .jumpTarget)
 1791 dispatch(4)
 1792
 1793.op2NotInt:
 1794 ci2d t1, ft0
 1795 bia t2, LowestTag, .slow
 1796 fii2d t3, t2, ft1
 1797 doubleCompare(ft0, ft1, .jumpTarget)
 1798 dispatch(4)
 1799
 1800.jumpTarget:
 1801 dispatchBranch(12[PC])
 1802
 1803.slow:
 1804 callHelper(helper)
 1805 dispatch(0)
 1806end
 1807
 1808_llint_op_loop_if_less:
 1809 nop
 1810_llint_op_jless:
 1811 traceExecution()
 1812 compare(
 1813 macro (left, right, target) bilt left, right, target end,
 1814 macro (left, right, target) bdlt left, right, target end,
 1815 _llint_helper_jless)
 1816
 1817
 1818_llint_op_jnless:
 1819 traceExecution()
 1820 compare(
 1821 macro (left, right, target) bigteq left, right, target end,
 1822 macro (left, right, target) bdgtequn left, right, target end,
 1823 _llint_helper_jnless)
 1824
 1825
 1826_llint_op_loop_if_greater:
 1827 nop
 1828_llint_op_jgreater:
 1829 traceExecution()
 1830 compare(
 1831 macro (left, right, target) bigt left, right, target end,
 1832 macro (left, right, target) bdgt left, right, target end,
 1833 _llint_helper_jgreater)
 1834
 1835
 1836_llint_op_jngreater:
 1837 traceExecution()
 1838 compare(
 1839 macro (left, right, target) bilteq left, right, target end,
 1840 macro (left, right, target) bdltequn left, right, target end,
 1841 _llint_helper_jngreater)
 1842
 1843
 1844_llint_op_loop_if_lesseq:
 1845 nop
 1846_llint_op_jlesseq:
 1847 traceExecution()
 1848 compare(
 1849 macro (left, right, target) bilteq left, right, target end,
 1850 macro (left, right, target) bdlteq left, right, target end,
 1851 _llint_helper_jlesseq)
 1852
 1853
 1854_llint_op_jnlesseq:
 1855 traceExecution()
 1856 compare(
 1857 macro (left, right, target) bigt left, right, target end,
 1858 macro (left, right, target) bdgtun left, right, target end,
 1859 _llint_helper_jnlesseq)
 1860
 1861
 1862_llint_op_loop_if_greatereq:
 1863 nop
 1864_llint_op_jgreatereq:
 1865 traceExecution()
 1866 compare(
 1867 macro (left, right, target) bigteq left, right, target end,
 1868 macro (left, right, target) bdgteq left, right, target end,
 1869 _llint_helper_jgreatereq)
 1870
 1871
 1872_llint_op_jngreatereq:
 1873 traceExecution()
 1874 compare(
 1875 macro (left, right, target) bilt left, right, target end,
 1876 macro (left, right, target) bdltun left, right, target end,
 1877 _llint_helper_jngreatereq)
 1878
 1879
 1880_llint_op_loop_hint:
 1881 traceExecution()
 1882 checkSwitchToJITForLoop()
 1883 dispatch(1)
 1884
 1885
 1886_llint_op_switch_imm:
 1887 traceExecution()
 1888 loadi 12[PC], t2
 1889 loadi 4[PC], t3
 1890 loadConstantOrVariable(t2, t1, t0)
 1891 loadp CodeBlock[cfr], t2
 1892 loadp CodeBlock::m_rareData[t2], t2
 1893 muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
 1894 loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
 1895 addp t3, t2
 1896 bineq t1, Int32Tag, .opSwitchImmNotInt
 1897 subi SimpleJumpTable::min[t2], t0
 1898 biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
 1899 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
 1900 loadi [t3, t0, 4], t1
 1901 btiz t1, .opSwitchImmFallThrough
 1902 dispatchBranchWithOffset(t1)
 1903
 1904.opSwitchImmNotInt:
 1905 bib t1, LowestTag, .opSwitchImmSlow # Go to slow path if it's a double.
 1906.opSwitchImmFallThrough:
 1907 dispatchBranch(8[PC])
 1908
 1909.opSwitchImmSlow:
 1910 callHelper(_llint_helper_switch_imm)
 1911 dispatch(0)
 1912
 1913
 1914_llint_op_switch_char:
 1915 traceExecution()
 1916 loadi 12[PC], t2
 1917 loadi 4[PC], t3
 1918 loadConstantOrVariable(t2, t1, t0)
 1919 loadp CodeBlock[cfr], t2
 1920 loadp CodeBlock::m_rareData[t2], t2
 1921 muli sizeof SimpleJumpTable, t3
 1922 loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
 1923 addp t3, t2
 1924 bineq t1, CellTag, .opSwitchCharFallThrough
 1925 loadp JSCell::m_structure[t0], t1
 1926 bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
 1927 loadp JSString::m_value[t0], t0
 1928 bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
 1929 loadp StringImpl::m_data8[t0], t1
 1930 btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
 1931 loadh [t1], t0
 1932 jmp .opSwitchCharReady
 1933.opSwitchChar8Bit:
 1934 loadb [t1], t0
 1935.opSwitchCharReady:
 1936 subi SimpleJumpTable::min[t2], t0
 1937 biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
 1938 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
 1939 loadi [t2, t0, 4], t1
 1940 btiz t1, .opSwitchImmFallThrough
 1941 dispatchBranchWithOffset(t1)
 1942
 1943.opSwitchCharFallThrough:
 1944 dispatchBranch(8[PC])
 1945
 1946
 1947_llint_op_switch_string:
 1948 traceExecution()
 1949 callHelper(_llint_helper_switch_string)
 1950 dispatch(0)
 1951
 1952
 1953_llint_op_new_func:
 1954 traceExecution()
 1955 btiz 12[PC], .opNewFuncUnchecked
 1956 loadi 4[PC], t1
 1957 bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
 1958.opNewFuncUnchecked:
 1959 callHelper(_llint_helper_new_func)
 1960.opNewFuncDone:
 1961 dispatch(4)
 1962
 1963
 1964_llint_op_new_func_exp:
 1965 traceExecution()
 1966 callHelper(_llint_helper_new_func_exp)
 1967 dispatch(3)
 1968
 1969
 1970macro doCall(helper)
 1971 loadi 4[PC], t0
 1972 loadi 16[PC], t1
 1973 loadp LLIntCallLinkInfo::callee[t1], t2
 1974 loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
 1975 bineq t3, t2, .opCallSlow
 1976 loadi 12[PC], t3
 1977 addp 24, PC
 1978 lshifti 3, t3
 1979 addp cfr, t3 # t3 contains the new value of cfr
 1980 loadp JSFunction::m_scopeChain[t2], t0
 1981 storei t2, Callee + PayloadOffset[t3]
 1982 storei t0, ScopeChain + PayloadOffset[t3]
 1983 loadi 8 - 24[PC], t2
 1984 storei PC, ArgumentCount + TagOffset[cfr]
 1985 storep cfr, CallerFrame[t3]
 1986 storei t2, ArgumentCount + PayloadOffset[t3]
 1987 storei CellTag, Callee + TagOffset[t3]
 1988 storei CellTag, ScopeChain + TagOffset[t3]
 1989 move t3, cfr
 1990 call LLIntCallLinkInfo::machineCodeTarget[t1]
 1991 dispatchAfterCall()
 1992
 1993.opCallSlow:
 1994 slowPathForCall(6, helper)
 1995end
 1996
 1997_llint_op_call:
 1998 traceExecution()
 1999 doCall(_llint_helper_call)
 2000
 2001
 2002_llint_op_construct:
 2003 traceExecution()
 2004 doCall(_llint_helper_construct)
 2005
 2006
 2007_llint_op_call_varargs:
 2008 traceExecution()
 2009 slowPathForCall(6, _llint_helper_call_varargs)
 2010
 2011
 2012_llint_op_call_eval:
 2013 traceExecution()
 2014
 2015 # Eval is executed in one of two modes:
 2016 #
 2017 # 1) We find that we're really invoking eval() in which case the
 2018 # execution is perfomed entirely inside the helper, and it
 2019 # returns the PC of a function that just returns the return value
 2020 # that the eval returned.
 2021 #
 2022 # 2) We find that we're invoking something called eval() that is not
 2023 # the real eval. Then the helper returns the PC of the thing to
 2024 # call, and we call it.
 2025 #
 2026 # This allows us to handle two cases, which would require a total of
 2027 # up to four pieces of state that cannot be easily packed into two
 2028 # registers (C functions can return up to two registers, easily):
 2029 #
 2030 # - The call frame register. This may or may not have been modified
 2031 # by the helper, but the convention is that it returns it. It's not
 2032 # totally clear if that's necessary, since the cfr is callee save.
 2033 # But that's our style in this here interpreter so we stick with it.
 2034 #
 2035 # - A bit to say if the helper successfully executed the eval and has
 2036 # the return value, or did not execute the eval but has a PC for us
 2037 # to call.
 2038 #
 2039 # - Either:
 2040 # - The JS return value (two registers), or
 2041 #
 2042 # - The PC to call.
 2043 #
 2044 # It turns out to be easier to just always have this return the cfr
 2045 # and a PC to call, and that PC may be a dummy thunk that just
 2046 # returns the JS value that the eval returned.
 2047
 2048 slowPathForCall(4, _llint_helper_call_eval)
 2049
 2050
 2051_llint_generic_return_point:
 2052 dispatchAfterCall()
 2053
 2054
 2055_llint_op_tear_off_activation:
 2056 traceExecution()
 2057 loadi 4[PC], t0
 2058 loadi 8[PC], t1
 2059 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
 2060 bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
 2061.opTearOffActivationCreated:
 2062 callHelper(_llint_helper_tear_off_activation)
 2063.opTearOffActivationNotCreated:
 2064 dispatch(3)
 2065
 2066
 2067_llint_op_tear_off_arguments:
 2068 traceExecution()
 2069 loadi 4[PC], t0
 2070 subi 1, t0 # Get the unmodifiedArgumentsRegister
 2071 bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
 2072 callHelper(_llint_helper_tear_off_arguments)
 2073.opTearOffArgumentsNotCreated:
 2074 dispatch(2)
 2075
 2076
 2077macro doReturn()
 2078 loadp ReturnPC[cfr], t2
 2079 loadp CallerFrame[cfr], cfr
 2080 restoreReturnAddressBeforeReturn(t2)
 2081 ret
 2082end
 2083
 2084_llint_op_ret:
 2085 traceExecution()
 2086 checkSwitchToJITForEpilogue()
 2087 loadi 4[PC], t2
 2088 loadConstantOrVariable(t2, t1, t0)
 2089 doReturn()
 2090
 2091
 2092_llint_op_call_put_result:
 2093 loadi 4[PC], t2
 2094 loadi 8[PC], t3
 2095 storei t1, TagOffset[cfr, t2, 8]
 2096 storei t0, PayloadOffset[cfr, t2, 8]
 2097 valueProfile(t1, t0, t3)
 2098 traceExecution() # Needs to be here because it would clobber t1, t0
 2099 dispatch(3)
 2100
 2101
 2102_llint_op_ret_object_or_this:
 2103 traceExecution()
 2104 checkSwitchToJITForEpilogue()
 2105 loadi 4[PC], t2
 2106 loadConstantOrVariable(t2, t1, t0)
 2107 bineq t1, CellTag, .opRetObjectOrThisNotObject
 2108 loadp JSCell::m_structure[t0], t2
 2109 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
 2110 doReturn()
 2111
 2112.opRetObjectOrThisNotObject:
 2113 loadi 8[PC], t2
 2114 loadConstantOrVariable(t2, t1, t0)
 2115 doReturn()
 2116
 2117
 2118_llint_op_method_check:
 2119 traceExecution()
 2120 # We ignore method checks and use normal get_by_id optimizations.
 2121 dispatch(1)
 2122
 2123
 2124_llint_op_strcat:
 2125 traceExecution()
 2126 callHelper(_llint_helper_strcat)
 2127 dispatch(4)
 2128
 2129
 2130_llint_op_to_primitive:
 2131 traceExecution()
 2132 loadi 8[PC], t2
 2133 loadi 4[PC], t3
 2134 loadConstantOrVariable(t2, t1, t0)
 2135 bineq t1, CellTag, .opToPrimitiveIsImm
 2136 loadp JSCell::m_structure[t0], t2
 2137 bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
 2138.opToPrimitiveIsImm:
 2139 storei t1, TagOffset[cfr, t3, 8]
 2140 storei t0, PayloadOffset[cfr, t3, 8]
 2141 dispatch(3)
 2142
 2143.opToPrimitiveSlowCase:
 2144 callHelper(_llint_helper_to_primitive)
 2145 dispatch(3)
 2146
 2147
 2148_llint_op_get_pnames:
 2149 traceExecution()
 2150 callHelper(_llint_helper_get_pnames)
 2151 dispatch(0) # The helper either advances the PC or jumps us to somewhere else.
 2152
 2153
 2154_llint_op_next_pname:
 2155 traceExecution()
 2156 loadi 12[PC], t1
 2157 loadi 16[PC], t2
 2158 loadi PayloadOffset[cfr, t1, 8], t0
 2159 bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
 2160 loadi 20[PC], t2
 2161 loadi PayloadOffset[cfr, t2, 8], t2
 2162 loadp JSPropertyNameIterator::m_jsStrings[t2], t3
 2163 loadi [t3, t0, 8], t3
 2164 addi 1, t0
 2165 storei t0, PayloadOffset[cfr, t1, 8]
 2166 loadi 4[PC], t1
 2167 storei CellTag, TagOffset[cfr, t1, 8]
 2168 storei t3, PayloadOffset[cfr, t1, 8]
 2169 loadi 8[PC], t3
 2170 loadi PayloadOffset[cfr, t3, 8], t3
 2171 loadp JSCell::m_structure[t3], t1
 2172 bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
 2173 loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
 2174 loadp StructureChain::m_vector[t0], t0
 2175 btpz [t0], .opNextPnameTarget
 2176.opNextPnameCheckPrototypeLoop:
 2177 bieq Structure::m_prototype + TagOffset[t1], NullTag, .opNextPnameSlow
 2178 loadp Structure::m_prototype + PayloadOffset[t1], t2
 2179 loadp JSCell::m_structure[t2], t1
 2180 bpneq t1, [t0], .opNextPnameSlow
 2181 addp 4, t0
 2182 btpnz [t0], .opNextPnameCheckPrototypeLoop
 2183.opNextPnameTarget:
 2184 dispatchBranch(24[PC])
 2185
 2186.opNextPnameEnd:
 2187 dispatch(7)
 2188
 2189.opNextPnameSlow:
 2190 callHelper(_llint_helper_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
 2191 dispatch(0)
 2192
 2193
 2194_llint_op_push_scope:
 2195 traceExecution()
 2196 callHelper(_llint_helper_push_scope)
 2197 dispatch(2)
 2198
 2199
 2200_llint_op_pop_scope:
 2201 traceExecution()
 2202 callHelper(_llint_helper_pop_scope)
 2203 dispatch(1)
 2204
 2205
 2206_llint_op_push_new_scope:
 2207 traceExecution()
 2208 callHelper(_llint_helper_push_new_scope)
 2209 dispatch(4)
 2210
 2211
 2212_llint_op_catch:
 2213 # This is where we end up from the JIT's throw trampoline (because the
 2214 # machine code return address will be set to _llint_op_catch), and from
 2215 # the interpreter's throw trampoline (see _llint_throw_trampoline).
 2216 # The JIT throwing protocol calls for the cfr to be in t0. The throwing
 2217 # code must have known that we were throwing to the interpreter, and have
 2218 # set JSGlobalData::targetInterpreterPCForThrow.
 2219 move t0, cfr
 2220 loadp JITStackFrame::globalData[sp], t3
 2221 loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
 2222 loadi JSGlobalData::exception + PayloadOffset[t3], t0
 2223 loadi JSGlobalData::exception + TagOffset[t3], t1
 2224 storei 0, JSGlobalData::exception + PayloadOffset[t3]
 2225 storei EmptyValueTag, JSGlobalData::exception + TagOffset[t3]
 2226 loadi 4[PC], t2
 2227 storei t0, PayloadOffset[cfr, t2, 8]
 2228 storei t1, TagOffset[cfr, t2, 8]
 2229 traceExecution() # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
 2230 dispatch(2)
 2231
 2232
 2233_llint_op_throw:
 2234 traceExecution()
 2235 callHelper(_llint_helper_throw)
 2236 dispatch(2)
 2237
 2238
 2239_llint_op_throw_reference_error:
 2240 traceExecution()
 2241 callHelper(_llint_helper_throw_reference_error)
 2242 dispatch(2)
 2243
 2244
 2245_llint_op_jsr:
 2246 traceExecution()
 2247 loadi 4[PC], t0
 2248 addi 3 * 4, PC, t1
 2249 storei t1, [cfr, t0, 8]
 2250 dispatchBranch(8[PC])
 2251
 2252
 2253_llint_op_sret:
 2254 traceExecution()
 2255 loadi 4[PC], t0
 2256 loadp [cfr, t0, 8], PC
 2257 dispatch(0)
 2258
 2259
 2260_llint_op_debug:
 2261 traceExecution()
 2262 callHelper(_llint_helper_debug)
 2263 dispatch(4)
 2264
 2265
 2266_llint_op_profile_will_call:
 2267 traceExecution()
 2268 loadp JITStackFrame::enabledProfilerReference[sp], t0
 2269 btpz [t0], .opProfileWillCallDone
 2270 callHelper(_llint_helper_profile_will_call)
 2271.opProfileWillCallDone:
 2272 dispatch(2)
 2273
 2274
 2275_llint_op_profile_did_call:
 2276 traceExecution()
 2277 loadp JITStackFrame::enabledProfilerReference[sp], t0
 2278 btpz [t0], .opProfileWillCallDone
 2279 callHelper(_llint_helper_profile_did_call)
 2280.opProfileDidCallDone:
 2281 dispatch(2)
 2282
 2283
 2284_llint_op_end:
 2285 traceExecution()
 2286 checkSwitchToJITForEpilogue()
 2287 loadi 4[PC], t0
 2288 loadi TagOffset[cfr, t0, 8], t1
 2289 loadi PayloadOffset[cfr, t0, 8], t0
 2290 doReturn()
 2291
 2292
 2293_llint_throw_from_helper_trampoline:
 2294 # When throwing from the interpreter (i.e. throwing from LLIntHelpers), so
 2295 # the throw target is not necessarily interpreted code, we come to here.
 2296 # This essentially emulates the JIT's throwing protocol.
 2297 loadp JITStackFrame::globalData[sp], t1
 2298 loadp JSGlobalData::callFrameForThrow[t1], t0
 2299 jmp JSGlobalData::targetMachinePCForThrow[t1]
 2300
 2301
 2302_llint_throw_during_call_trampoline:
 2303 preserveReturnAddressAfterCall(t2)
 2304 loadp JITStackFrame::globalData[sp], t1
 2305 loadp JSGlobalData::callFrameForThrow[t1], t0
 2306 jmp JSGlobalData::targetMachinePCForThrow[t1]
 2307
 2308
 2309# Lastly, make sure that we can link even though we don't support all opcodes.
 2310# These opcodes should never arise when using LLInt or either JIT. We assert
 2311# as much.
 2312
 2313macro notSupported()
 2314 if ASSERT_ENABLED
 2315 crash()
 2316 else
 2317 # We should use whatever the smallest possible instruction is, just to
 2318 # ensure that there is a gap between instruction labels. If multiple
 2319 # smallest instructions exist, we should pick the one that is most
 2320 # likely result in execution being halted. Currently that is the break
 2321 # instruction on all architectures we're interested in. (Break is int3
 2322 # on Intel, which is 1 byte, and bkpt on ARMv7, which is 2 bytes.)
 2323 break
 2324 end
 2325end
 2326
 2327_llint_op_get_array_length:
 2328 notSupported()
 2329
 2330_llint_op_get_by_id_chain:
 2331 notSupported()
 2332
 2333_llint_op_get_by_id_custom_chain:
 2334 notSupported()
 2335
 2336_llint_op_get_by_id_custom_proto:
 2337 notSupported()
 2338
 2339_llint_op_get_by_id_custom_self:
 2340 notSupported()
 2341
 2342_llint_op_get_by_id_generic:
 2343 notSupported()
 2344
 2345_llint_op_get_by_id_getter_chain:
 2346 notSupported()
 2347
 2348_llint_op_get_by_id_getter_proto:
 2349 notSupported()
 2350
 2351_llint_op_get_by_id_getter_self:
 2352 notSupported()
 2353
 2354_llint_op_get_by_id_proto:
 2355 notSupported()
 2356
 2357_llint_op_get_by_id_self:
 2358 notSupported()
 2359
 2360_llint_op_get_string_length:
 2361 notSupported()
 2362
 2363_llint_op_put_by_id_generic:
 2364 notSupported()
 2365
 2366_llint_op_put_by_id_replace:
 2367 notSupported()
 2368
 2369_llint_op_put_by_id_transition:
 2370 notSupported()
 2371
 2372
 2373# Indicate the end of LLInt.
 2374_llint_end:
 2375 crash()
 2376
0

Source/JavaScriptCore/llint/LowLevelInterpreter.cpp

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "LowLevelInterpreter.h"
 28
 29#if ENABLE(LLINT)
 30
 31#include "LLIntOfflineAsmConfig.h"
 32
 33#include "LLIntAssembly.h"
 34
 35#endif // ENABLE(LLINT)
0

Source/JavaScriptCore/llint/LowLevelInterpreter.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef LowLevelInterpreter_h
 27#define LowLevelInterpreter_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(LLINT)
 32
 33#include "Opcode.h"
 34
 35#define LLINT_INSTRUCTION_DECL(opcode, length) extern "C" void llint_##opcode();
 36 FOR_EACH_OPCODE_ID(LLINT_INSTRUCTION_DECL);
 37#undef LLINT_INSTRUCTION_DECL
 38
 39extern "C" void llint_begin();
 40extern "C" void llint_end();
 41extern "C" void llint_program_prologue();
 42extern "C" void llint_eval_prologue();
 43extern "C" void llint_function_for_call_prologue();
 44extern "C" void llint_function_for_construct_prologue();
 45extern "C" void llint_function_for_call_arity_check();
 46extern "C" void llint_function_for_construct_arity_check();
 47extern "C" void llint_generic_return_point();
 48extern "C" void llint_throw_from_helper_trampoline();
 49extern "C" void llint_throw_during_call_trampoline();
 50
 51#endif // ENABLE(LLINT)
 52
 53#endif // LowLevelInterpreter_h
0

Source/JavaScriptCore/offlineasm/armv7.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24class SpecialRegister
 25 def initialize(name)
 26 @name = name
 27 end
 28
 29 def armV7Operand
 30 @name
 31 end
 32end
 33
 34ARMv7_DATA_REG = SpecialRegister.new("ip")
 35ARMv7_ADDR_REG = SpecialRegister.new("r3")
 36
 37def moveImmediate(value, register)
 38 # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
 39 if value >= 0 && value < 256
 40 $asm.puts "movw \##{value}, #{register.armV7Operand}"
 41 elsif (~value) >= 0 && (~value) < 256
 42 $asm.puts "mvnw \##{~value}, #{register.armV7Operand}"
 43 else
 44 $asm.puts "movw \##{value & 0xffff}, #{register.armV7Operand}"
 45 if (value & 0xffff0000) != 0
 46 $asm.puts "movt \##{value >> 16}, #{register.armV7Operand}"
 47 end
 48 end
 49end
 50
 51class RegisterID
 52 def armV7Operand
 53 case name
 54 when "t0", "a0", "r0"
 55 "r0"
 56 when "t1", "a1", "r1"
 57 "r1"
 58 when "t2", "a2"
 59 "r2"
 60 when "a3"
 61 "r3"
 62 when "t3"
 63 "r4"
 64 when "t4"
 65 "r7"
 66 when "cfr"
 67 "r5"
 68 else
 69 raise
 70 end
 71 end
 72
 73 def armV7PreparePossibleMemoryOperand
 74 end
 75
 76 def armV7PossibleMemoryOperand
 77 armV7Operand
 78 end
 79
 80 def armV7LoadStoreWrap
 81 yield
 82 end
 83end
 84
 85class FPRegisterID
 86 def armV7Operand
 87 case name
 88 when "ft0", "fr"
 89 "d0"
 90 when "fr1",
 91 "d1"
 92 when "fr2"
 93 "d2"
 94 when "fr3"
 95 "d3"
 96 when "fr4"
 97 "d4"
 98 when "fr5"
 99 "d5"
 100 else
 101 raise
 102 end
 103 end
 104
 105 def armV7PreparePossibleMemoryOperand
 106 end
 107
 108 def armV7PossibleMemoryOperand
 109 armV7Operand
 110 end
 111
 112 def armV7LoadStoreWrap
 113 yield self
 114 end
 115end
 116
 117class Immediate
 118 def armV7Operand
 119 raise "Invalid immediate #{value}" if value < 0 or value > 255
 120 "#${value}"
 121 end
 122
 123 def armV7PreparePossibleMemoryOperand
 124 end
 125
 126 def armV7PossibleMemoryOperand
 127 armV7Operand
 128 end
 129
 130 def armV7LoadStoreWrap
 131 yield self
 132 end
 133end
 134
 135module ARMv7AddressUtilities
 136 def armV7LoadStoreWrap
 137 self.armV7PreparePossibleMemoryOperand
 138 $asm.puts "\tldr #{self.armV7PossiblyMemoryOperand}, #{ARMv7_DATA_REG.armV7Operand}"
 139 yield ARMv7_DATA_REG
 140 $asm.puts "\tstr #{ARMv7_DATA_REG.armV7Operand}, #{self.armV7PossiblyMemoryOperand}"
 141 end
 142end
 143
 144class Address
 145 include ARMv7AddressUtilities
 146
 147 def armV7PreparePossibleMemoryOperand
 148 if offset.value < -0xff || offset.value > 0xfff
 149 moveImmediate(offset.value, ARMv7_ADDR_REG)
 150 end
 151 end
 152
 153 def armV7PossibleMemoryOperand
 154 if offset.value < -0xff || offset.value > 0xfff
 155 "[#{base.armV7Operand}, #{ARMv7_ADDR_REG.armV7Operand}]"
 156 else
 157 "[#{base.armV7Operand}, #{offset.armV7Operand}]"
 158 end
 159 end
 160end
 161
 162class BaseIndex
 163 include ARMv7AddressUtilities
 164
 165 def armV7PreparePossibleMemoryOperand
 166 if offset.value != 0
 167 moveImmediate(offset.value, ARMv7_ADDR_REG)
 168 $asm.puts "addw #{ARMv7_ADDR_REG.armV7Operand}, #{base.armV7Operand}"
 169 end
 170 end
 171
 172 def armV7PossibleMemoryOperand
 173 if offset.value != 0
 174 "[#{ARMv7_ADDR_REG.armV7Operand}, #{index.armV7Operand}, lsl \##{scale}]"
 175 else
 176 "[#{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scale}]"
 177 end
 178 end
 179end
 180
 181class AbsoluteAddress
 182 include ARMv7AddressUtilities
 183
 184 def armV7PreparePossibleMemoryOperand
 185 moveImmediate(address.value, ARMv7_ADDR_REG)
 186 end
 187
 188 def armV7PossibleMemoryOperand
 189 "[#{ARMv7_ADDR_REG.armV7Operand}]"
 190 end
 191end
 192
 193
0

Source/JavaScriptCore/offlineasm/asm.rb

 1#!/usr/bin/env ruby
 2
 3# Copyright (C) 2011 Apple Inc. All rights reserved.
 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# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24# THE POSSIBILITY OF SUCH DAMAGE.
 25
 26$: << File.dirname(__FILE__)
 27
 28require "backends"
 29require "digest/sha1"
 30require "offsets"
 31require "parser"
 32require "settings"
 33require "transform"
 34
 35class Assembler
 36 def initialize(outp)
 37 @outp = outp
 38 @state = :cpp
 39 end
 40
 41 def enterAsm
 42 @outp.puts "asm ("
 43 @state = :asm
 44 end
 45
 46 def leaveAsm
 47 @outp.puts ");"
 48 @state = :cpp
 49 end
 50
 51 def inAsm
 52 enterAsm
 53 yield
 54 leaveAsm
 55 end
 56
 57 def puts(line)
 58 raise unless @state == :asm
 59 @outp.puts((line + "\n").inspect)
 60 end
 61
 62 def comment(text)
 63 @outp.puts "// #{text}"
 64 end
 65end
 66
 67asmFile = ARGV.shift
 68offsetsFile = ARGV.shift
 69outputFlnm = ARGV.shift
 70
 71offsetsList, configIndex = offsetsAndConfigurationIndex(offsetsFile)
 72inputData = IO::read(asmFile)
 73
 74inputHash =
 75 "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
 76 " " + Digest::SHA1.hexdigest((offsetsList + [configIndex]).join(' '))
 77
 78if FileTest.exist? outputFlnm
 79 File.open(outputFlnm, "r") {
 80 | inp |
 81 firstLine = inp.gets
 82 if firstLine and firstLine.chomp == inputHash
 83 $stderr.puts "Nothing changed."
 84 exit 0
 85 end
 86 }
 87end
 88
 89File.open(outputFlnm, "w") {
 90 | outp |
 91 $output = outp
 92 $output.puts inputHash
 93
 94 $asm = Assembler.new($output)
 95
 96 ast = parse(lex(inputData))
 97
 98 forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
 99 | concreteSettings, lowLevelAST, backend |
 100 assertConfiguration(concreteSettings)
 101 lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
 102 emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
 103 $asm.inAsm {
 104 lowLevelAST.lower(backend)
 105 }
 106 }
 107 }
 108}
0

Source/JavaScriptCore/offlineasm/ast.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24########################################################################
 25# #
 26# Base utility types for the AST. #
 27# #
 28########################################################################
 29
 30# Valid methods for Node:
 31#
 32# node.children -> Returns an array of immediate children.
 33#
 34# node.descendents -> Returns an array of all strict descendants (children
 35# and children of children, transitively).
 36#
 37# node.flatten -> Returns an array containing the strict descendants and
 38# the node itself.
 39#
 40# node.filter(type) -> Returns an array containing those elements in
 41# node.flatten that are of the given type (is_a? type returns true).
 42#
 43# node.mapChildren{|v| ...} -> Returns a new node with all children
 44# replaced according to the given block.
 45#
 46# Examples:
 47#
 48# node.filter(Setting).uniq -> Returns all of the settings that the AST's
 49# IfThenElse blocks depend on.
 50#
 51# node.filter(StructOffset).uniq -> Returns all of the structure offsets
 52# that the AST depends on.
 53
 54class Node
 55 attr_reader :codeOrigin
 56
 57 def initialize(codeOrigin)
 58 @codeOrigin = codeOrigin
 59 end
 60
 61 def codeOriginString
 62 "line number #{@codeOrigin}"
 63 end
 64
 65 def descendants
 66 children.collect{|v| v.flatten}.flatten
 67 end
 68
 69 def flatten
 70 [self] + descendants
 71 end
 72
 73 def filter(type)
 74 flatten.select{|v| v.is_a? type}
 75 end
 76end
 77
 78class NoChildren < Node
 79 def initialize(codeOrigin)
 80 super(codeOrigin)
 81 end
 82
 83 def children
 84 []
 85 end
 86
 87 def mapChildren
 88 self
 89 end
 90end
 91
 92class StructOffsetKey
 93 attr_reader :struct, :field
 94
 95 def initialize(struct, field)
 96 @struct = struct
 97 @field = field
 98 end
 99
 100 def hash
 101 @struct.hash + @field.hash * 3
 102 end
 103
 104 def eql?(other)
 105 @struct == other.struct and @field == other.field
 106 end
 107end
 108
 109########################################################################
 110# #
 111# AST nodes. #
 112# #
 113########################################################################
 114
 115class StructOffset < NoChildren
 116 attr_reader :struct, :field
 117
 118 def initialize(codeOrigin, struct, field)
 119 super(codeOrigin)
 120 @struct = struct
 121 @field = field
 122 end
 123
 124 @@mapping = {}
 125
 126 def self.forField(codeOrigin, struct, field)
 127 key = StructOffsetKey.new(struct, field)
 128
 129 unless @@mapping[key]
 130 @@mapping[key] = StructOffset.new(codeOrigin, struct, field)
 131 end
 132 @@mapping[key]
 133 end
 134
 135 def dump
 136 "#{struct}::#{field}"
 137 end
 138
 139 def <=>(other)
 140 if @struct != other.struct
 141 return @struct <=> other.struct
 142 end
 143 @field <=> other.field
 144 end
 145end
 146
 147class Sizeof < NoChildren
 148 attr_reader :struct
 149
 150 def initialize(codeOrigin, struct)
 151 super(codeOrigin)
 152 @struct = struct
 153 end
 154
 155 @@mapping = {}
 156
 157 def self.forName(codeOrigin, struct)
 158 unless @@mapping[struct]
 159 @@mapping[struct] = Sizeof.new(codeOrigin, struct)
 160 end
 161 @@mapping[struct]
 162 end
 163
 164 def dump
 165 "sizeof #{@struct}"
 166 end
 167
 168 def <=>(other)
 169 @struct <=> other.struct
 170 end
 171end
 172
 173class Immediate < NoChildren
 174 attr_reader :value
 175
 176 def initialize(codeOrigin, value)
 177 super(codeOrigin)
 178 @value = value
 179 end
 180
 181 def dump
 182 "#{value}"
 183 end
 184
 185 def ==(other)
 186 other.is_a? Immediate and other.value == @value
 187 end
 188end
 189
 190class AddImmediates < Node
 191 attr_reader :left, :right
 192
 193 def initialize(codeOrigin, left, right)
 194 super(codeOrigin)
 195 @left = left
 196 @right = right
 197 end
 198
 199 def children
 200 [@left, @right]
 201 end
 202
 203 def mapChildren
 204 AddImmediates.new(codeOrigin, (yield @left), (yield @right))
 205 end
 206
 207 def dump
 208 "(#{left.dump} + #{right.dump})"
 209 end
 210end
 211
 212class SubImmediates < Node
 213 attr_reader :left, :right
 214
 215 def initialize(codeOrigin, left, right)
 216 super(codeOrigin)
 217 @left = left
 218 @right = right
 219 end
 220
 221 def children
 222 [@left, @right]
 223 end
 224
 225 def mapChildren
 226 SubImmediates.new(codeOrigin, (yield @left), (yield @right))
 227 end
 228
 229 def dump
 230 "(#{left.dump} - #{right.dump})"
 231 end
 232end
 233
 234class MulImmediates < Node
 235 attr_reader :left, :right
 236
 237 def initialize(codeOrigin, left, right)
 238 super(codeOrigin)
 239 @left = left
 240 @right = right
 241 end
 242
 243 def children
 244 [@left, @right]
 245 end
 246
 247 def mapChildren
 248 MulImmediates.new(codeOrigin, (yield @left), (yield @right))
 249 end
 250
 251 def dump
 252 "(#{left.dump} * #{right.dump})"
 253 end
 254end
 255
 256class NegImmediate < Node
 257 attr_reader :child
 258
 259 def initialize(codeOrigin, child)
 260 super(codeOrigin)
 261 @child = child
 262 end
 263
 264 def children
 265 [@child]
 266 end
 267
 268 def mapChildren
 269 NegImmediate.new(codeOrigin, (yield @child))
 270 end
 271
 272 def dump
 273 "(-#{@child.dump})"
 274 end
 275end
 276
 277class RegisterID < NoChildren
 278 attr_reader :name
 279
 280 def initialize(codeOrigin, name)
 281 super(codeOrigin)
 282 @name = name
 283 end
 284
 285 @@mapping = {}
 286
 287 def self.forName(codeOrigin, name)
 288 unless @@mapping[name]
 289 @@mapping[name] = RegisterID.new(codeOrigin, name)
 290 end
 291 @@mapping[name]
 292 end
 293
 294 def dump
 295 name
 296 end
 297end
 298
 299class FPRegisterID < NoChildren
 300 attr_reader :name
 301
 302 def initialize(codeOrigin, name)
 303 super(codeOrigin)
 304 @name = name
 305 end
 306
 307 @@mapping = {}
 308
 309 def self.forName(codeOrigin, name)
 310 unless @@mapping[name]
 311 @@mapping[name] = FPRegisterID.new(codeOrigin, name)
 312 end
 313 @@mapping[name]
 314 end
 315
 316 def dump
 317 name
 318 end
 319end
 320
 321class Variable < NoChildren
 322 attr_reader :name
 323
 324 def initialize(codeOrigin, name)
 325 super(codeOrigin)
 326 @name = name
 327 end
 328
 329 @@mapping = {}
 330
 331 def self.forName(codeOrigin, name)
 332 unless @@mapping[name]
 333 @@mapping[name] = Variable.new(codeOrigin, name)
 334 end
 335 @@mapping[name]
 336 end
 337
 338 def dump
 339 name
 340 end
 341end
 342
 343class Address < Node
 344 attr_reader :base, :offset
 345
 346 def initialize(codeOrigin, base, offset)
 347 super(codeOrigin)
 348 @base = base
 349 @offset = offset
 350 end
 351
 352 def children
 353 [@base, @offset]
 354 end
 355
 356 def mapChildren
 357 Address.new(codeOrigin, (yield @base), (yield @offset))
 358 end
 359
 360 def dump
 361 "#{offset.dump}[#{base.dump}]"
 362 end
 363end
 364
 365class BaseIndex < Node
 366 attr_reader :base, :index, :scale, :offset
 367
 368 def initialize(codeOrigin, base, index, scale, offset)
 369 super(codeOrigin)
 370 @base = base
 371 @index = index
 372 @scale = scale
 373 raise unless [1, 2, 4, 8].member? @scale
 374 @offset = offset
 375 end
 376
 377 def children
 378 [@base, @index, @offset]
 379 end
 380
 381 def mapChildren
 382 BaseIndex.new(codeOrigin, (yield @base), (yield @index), @scale, (yield @offset))
 383 end
 384
 385 def dump
 386 "#{offset.dump}[#{base.dump}, #{index.dump}, #{scale}]"
 387 end
 388end
 389
 390class AbsoluteAddress < NoChildren
 391 attr_reader :address
 392
 393 def initialize(codeOrigin, address)
 394 super(codeOrigin)
 395 @address = address
 396 end
 397
 398 def dump
 399 "#{address.dump}[]"
 400 end
 401end
 402
 403class Instruction < Node
 404 attr_reader :opcode, :operands
 405
 406 def initialize(codeOrigin, opcode, operands)
 407 super(codeOrigin)
 408 @opcode = opcode
 409 @operands = operands
 410 end
 411
 412 def children
 413 operands
 414 end
 415
 416 def mapChildren(&proc)
 417 Instruction.new(codeOrigin, @opcode, @operands.map(&proc))
 418 end
 419
 420 def dump
 421 "\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
 422 end
 423end
 424
 425class Error < NoChildren
 426 def initialize(codeOrigin)
 427 super(codeOrigin)
 428 end
 429
 430 def dump
 431 "\terror"
 432 end
 433end
 434
 435class ConstDecl < Node
 436 attr_reader :variable, :value
 437
 438 def initialize(codeOrigin, variable, value)
 439 super(codeOrigin)
 440 @variable = variable
 441 @value = value
 442 end
 443
 444 def children
 445 [@variable, @value]
 446 end
 447
 448 def mapChildren
 449 ConstDecl.new(codeOrigin, (yield @variable), (yield @value))
 450 end
 451
 452 def dump
 453 "const #{@variable.dump} = #{@value.dump}"
 454 end
 455end
 456
 457$labelMapping = {}
 458
 459class Label < NoChildren
 460 attr_reader :name
 461
 462 def initialize(codeOrigin, name)
 463 super(codeOrigin)
 464 @name = name
 465 end
 466
 467 def self.forName(codeOrigin, name)
 468 if $labelMapping[name]
 469 raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
 470 else
 471 $labelMapping[name] = Label.new(codeOrigin, name)
 472 end
 473 $labelMapping[name]
 474 end
 475
 476 def dump
 477 "#{name}:"
 478 end
 479end
 480
 481class LocalLabel < NoChildren
 482 attr_reader :name
 483
 484 def initialize(codeOrigin, name)
 485 super(codeOrigin)
 486 @name = name
 487 end
 488
 489 @@uniqueNameCounter = 0
 490
 491 def self.forName(codeOrigin, name)
 492 if $labelMapping[name]
 493 raise "Label name collision: #{name}" unless $labelMapping[name].is_a? LocalLabel
 494 else
 495 $labelMapping[name] = LocalLabel.new(codeOrigin, name)
 496 end
 497 $labelMapping[name]
 498 end
 499
 500 def self.unique(comment)
 501 newName = "_#{comment}"
 502 if $labelMapping[newName]
 503 while $labelMapping[newName = "_#{@@uniqueNameCounter}_#{comment}"]
 504 @@uniqueNameCounter += 1
 505 end
 506 end
 507 forName(nil, newName)
 508 end
 509
 510 def cleanName
 511 if name =~ /^\./
 512 "_" + name[1..-1]
 513 else
 514 name
 515 end
 516 end
 517
 518 def dump
 519 "#{name}:"
 520 end
 521end
 522
 523class LabelReference < Node
 524 attr_reader :label
 525
 526 def initialize(codeOrigin, label)
 527 super(codeOrigin)
 528 @label = label
 529 end
 530
 531 def children
 532 [@label]
 533 end
 534
 535 def mapChildren
 536 LabelReference.new(codeOrigin, (yield @label))
 537 end
 538
 539 def name
 540 label.name
 541 end
 542
 543 def dump
 544 label.name
 545 end
 546end
 547
 548class LocalLabelReference < NoChildren
 549 attr_reader :label
 550
 551 def initialize(codeOrigin, label)
 552 super(codeOrigin)
 553 @label = label
 554 end
 555
 556 def children
 557 [@label]
 558 end
 559
 560 def mapChildren
 561 LocalLabelReference.new(codeOrigin, (yield @label))
 562 end
 563
 564 def name
 565 label.name
 566 end
 567
 568 def dump
 569 label.name
 570 end
 571end
 572
 573class Sequence < Node
 574 attr_reader :list
 575
 576 def initialize(codeOrigin, list)
 577 super(codeOrigin)
 578 @list = list
 579 end
 580
 581 def children
 582 list
 583 end
 584
 585 def mapChildren(&proc)
 586 Sequence.new(codeOrigin, @list.map(&proc))
 587 end
 588
 589 def dump
 590 list.collect{|v| v.dump}.join("\n")
 591 end
 592end
 593
 594class True < NoChildren
 595 def initialize
 596 super(nil)
 597 end
 598
 599 @@instance = True.new
 600
 601 def self.instance
 602 @@instance
 603 end
 604
 605 def value
 606 true
 607 end
 608
 609 def dump
 610 "true"
 611 end
 612end
 613
 614class False < NoChildren
 615 def initialize
 616 super(nil)
 617 end
 618
 619 @@instance = False.new
 620
 621 def self.instance
 622 @@instance
 623 end
 624
 625 def value
 626 false
 627 end
 628
 629 def dump
 630 "false"
 631 end
 632end
 633
 634class TrueClass
 635 def asNode
 636 True.instance
 637 end
 638end
 639
 640class FalseClass
 641 def asNode
 642 False.instance
 643 end
 644end
 645
 646class Setting < NoChildren
 647 attr_reader :name
 648
 649 def initialize(codeOrigin, name)
 650 super(codeOrigin)
 651 @name = name
 652 end
 653
 654 @@mapping = {}
 655
 656 def self.forName(codeOrigin, name)
 657 unless @@mapping[name]
 658 @@mapping[name] = Setting.new(codeOrigin, name)
 659 end
 660 @@mapping[name]
 661 end
 662
 663 def dump
 664 name
 665 end
 666end
 667
 668class And < Node
 669 attr_reader :left, :right
 670
 671 def initialize(codeOrigin, left, right)
 672 super(codeOrigin)
 673 @left = left
 674 @right = right
 675 end
 676
 677 def children
 678 [@left, @right]
 679 end
 680
 681 def mapChildren
 682 And.new(codeOrigin, (yield @left), (yield @right))
 683 end
 684
 685 def dump
 686 "(#{left.dump} and #{right.dump})"
 687 end
 688end
 689
 690class Or < Node
 691 attr_reader :left, :right
 692
 693 def initialize(codeOrigin, left, right)
 694 super(codeOrigin)
 695 @left = left
 696 @right = right
 697 end
 698
 699 def children
 700 [@left, @right]
 701 end
 702
 703 def mapChildren
 704 Or.new(codeOrigin, (yield @left), (yield @right))
 705 end
 706
 707 def dump
 708 "(#{left.dump} or #{right.dump})"
 709 end
 710end
 711
 712class Not < Node
 713 attr_reader :child
 714
 715 def initialize(codeOrigin, child)
 716 super(codeOrigin)
 717 @child = child
 718 end
 719
 720 def children
 721 [@left, @right]
 722 end
 723
 724 def mapChildren
 725 Not.new(codeOrigin, (yield @child))
 726 end
 727
 728 def dump
 729 "(not #{child.dump})"
 730 end
 731end
 732
 733class Skip < NoChildren
 734 def initialize(codeOrigin)
 735 super(codeOrigin)
 736 end
 737
 738 def dump
 739 "\tskip"
 740 end
 741end
 742
 743class IfThenElse < Node
 744 attr_reader :predicate, :thenCase
 745 attr_accessor :elseCase
 746
 747 def initialize(codeOrigin, predicate, thenCase)
 748 super(codeOrigin)
 749 @predicate = predicate
 750 @thenCase = thenCase
 751 @elseCase = Skip.new(codeOrigin)
 752 end
 753
 754 def children
 755 if @elseCase
 756 [@predicate, @thenCase, @elseCase]
 757 else
 758 [@predicate, @thenCase]
 759 end
 760 end
 761
 762 def mapChildren
 763 IfThenElse.new(codeOrigin, (yield @predicate), (yield @thenCase), (yield @elseCase))
 764 end
 765
 766 def dump
 767 "if #{predicate.dump}\n" + thenCase.dump + "\nelse\n" + elseCase.dump + "\nend"
 768 end
 769end
 770
 771class Macro < Node
 772 attr_reader :name, :variables, :body
 773
 774 def initialize(codeOrigin, name, variables, body)
 775 super(codeOrigin)
 776 @name = name
 777 @variables = variables
 778 @body = body
 779 end
 780
 781 def children
 782 @variables + [@body]
 783 end
 784
 785 def mapChildren
 786 Macro.new(codeOrigin, @name, @variables.map{|v| yield v}, (yield @body))
 787 end
 788
 789 def dump
 790 "macro #{name}(" + variables.collect{|v| v.dump}.join(", ") + ")\n" + body.dump + "\nend"
 791 end
 792end
 793
 794class MacroCall < Node
 795 attr_reader :name, :operands
 796
 797 def initialize(codeOrigin, name, operands)
 798 super(codeOrigin)
 799 @name = name
 800 @operands = operands
 801 raise unless @operands
 802 @operands.each{|v| raise unless v}
 803 end
 804
 805 def children
 806 @operands
 807 end
 808
 809 def mapChildren(&proc)
 810 MacroCall.new(codeOrigin, @name, @operands.map(&proc))
 811 end
 812
 813 def dump
 814 "\t#{name}(" + operands.collect{|v| v.dump}.join(", ") + ")"
 815 end
 816end
 817
0

Source/JavaScriptCore/offlineasm/backends.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24require "ast"
 25require "x86"
 26
 27BACKENDS =
 28 [
 29 "X86",
 30 "ARMv7"
 31 ]
 32
 33WORKING_BACKENDS =
 34 [
 35 "X86"
 36 ]
 37
 38BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
 39
 40class Node
 41 def lower(name)
 42 send("lower" + name)
 43 end
 44end
 45
 46# Overrides for lower() for those nodes that are backend-agnostic
 47
 48def sanitizeLabelName(name)
 49 # Some platforms don't want the leading "_". If we ever want to do something
 50 # about that, it would be here.
 51 name
 52end
 53
 54class Label
 55 def lower(name)
 56 $asm.puts ".globl #{sanitizeLabelName(self.name)}"
 57 $asm.puts "#{sanitizeLabelName(self.name)}:"
 58 end
 59end
 60
 61class LocalLabel
 62 def lower(name)
 63 $asm.puts "L_offlineasm_#{self.name[1..-1]}:"
 64 end
 65end
 66
 67class Skip
 68 def lower(name)
 69 end
 70end
 71
 72class Sequence
 73 def lower(name)
 74 @list.each {
 75 | node |
 76 node.lower(name)
 77 }
 78 end
 79end
 80
0

Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb

 1#!/usr/bin/env ruby
 2
 3# Copyright (C) 2011 Apple Inc. All rights reserved.
 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# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24# THE POSSIBILITY OF SUCH DAMAGE.
 25
 26$: << File.dirname(__FILE__)
 27
 28require "backends"
 29require "digest/sha1"
 30require "offsets"
 31require "parser"
 32require "settings"
 33require "transform"
 34
 35inputFlnm = ARGV.shift
 36outputFlnm = ARGV.shift
 37
 38def emitMagicNumber
 39 OFFSET_MAGIC_NUMBERS.each {
 40 | number |
 41 $output.puts "#{number},"
 42 }
 43end
 44
 45inputData = IO::read(inputFlnm)
 46inputHash = Digest::SHA1.hexdigest(inputData)
 47
 48if FileTest.exist? outputFlnm
 49 File.open(outputFlnm, "r") {
 50 | inp |
 51 firstLine = inp.gets
 52 if firstLine and firstLine.chomp == "// offlineasm input hash: #{inputHash}"
 53 $stderr.puts "Nothing changed."
 54 exit 0
 55 end
 56 }
 57end
 58
 59originalAST = parse(lex(inputData))
 60
 61File.open(outputFlnm, "w") {
 62 | outp |
 63 $output = outp
 64 outp.puts "// offlineasm input hash: #{inputHash}"
 65 emitCodeInAllConfigurations(originalAST) {
 66 | settings, ast, backend, index |
 67 offsetsList = ast.filter(StructOffset).uniq.sort
 68 sizesList = ast.filter(Sizeof).uniq.sort
 69
 70 length = (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
 71
 72 outp.puts "static const unsigned extractorTable[#{length}] = {"
 73 emitMagicNumber
 74 outp.puts "#{index},"
 75 offsetsList.each {
 76 | offset |
 77 emitMagicNumber
 78 outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
 79 }
 80 sizesList.each {
 81 | offset |
 82 emitMagicNumber
 83 outp.puts "sizeof(#{offset.struct}),"
 84 }
 85 outp.puts "};"
 86 }
 87}
0

Source/JavaScriptCore/offlineasm/instructions.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24MACRO_INSTRUCTIONS =
 25 [
 26 "addi",
 27 "andi",
 28 "lshifti",
 29 "muli",
 30 "negi",
 31 "noti",
 32 "ori",
 33 "rshifti",
 34 "urshifti",
 35 "subi",
 36 "xori",
 37 "loadi",
 38 "loadb",
 39 "loadh",
 40 "storei",
 41 "storeb",
 42 "loadd",
 43 "moved",
 44 "stored",
 45 "addd",
 46 "divd",
 47 "subd",
 48 "muld",
 49 "sqrtd",
 50 "ci2d",
 51 "fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
 52 "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
 53 "bdeq",
 54 "bdneq",
 55 "bdgt",
 56 "bdgteq",
 57 "bdlt",
 58 "bdlteq",
 59 "bdequn",
 60 "bdnequn",
 61 "bdgtun",
 62 "bdgtequn",
 63 "bdltun",
 64 "bdltequn",
 65 "btd2i",
 66 "td2i",
 67 "bcd2i",
 68 "movdz",
 69 "pop",
 70 "push",
 71 "move",
 72 "sxi2p",
 73 "zxi2p",
 74 "nop",
 75 "bieq",
 76 "bineq",
 77 "bia",
 78 "biaeq",
 79 "bib",
 80 "bibeq",
 81 "bigt",
 82 "bigteq",
 83 "bilt",
 84 "bilteq",
 85 "bbeq",
 86 "bbneq",
 87 "bba",
 88 "bbaeq",
 89 "bbb",
 90 "bbbeq",
 91 "bbgt",
 92 "bbgteq",
 93 "bblt",
 94 "bblteq",
 95 "btio",
 96 "btis",
 97 "btiz",
 98 "btinz",
 99 "btbo",
 100 "btbs",
 101 "btbz",
 102 "btbnz",
 103 "jmp",
 104 "baddio",
 105 "baddis",
 106 "baddiz",
 107 "baddinz",
 108 "bsubio",
 109 "bsubis",
 110 "bsubiz",
 111 "bsubinz",
 112 "bmulio",
 113 "bmulis",
 114 "bmuliz",
 115 "bmulinz",
 116 "borio",
 117 "boris",
 118 "boriz",
 119 "borinz",
 120 "break",
 121 "call",
 122 "ret",
 123 "cieq",
 124 "cineq",
 125 "cia",
 126 "ciaeq",
 127 "cib",
 128 "cibeq",
 129 "cigt",
 130 "cigteq",
 131 "cilt",
 132 "cilteq",
 133 "tio",
 134 "tis",
 135 "tiz",
 136 "tinz",
 137 "tbo",
 138 "tbs",
 139 "tbz",
 140 "tbnz",
 141 "peek",
 142 "poke",
 143 "bpeq",
 144 "bpneq",
 145 "bpa",
 146 "bpaeq",
 147 "bpb",
 148 "bpbeq",
 149 "bpgt",
 150 "bpgteq",
 151 "bplt",
 152 "bplteq",
 153 "addp",
 154 "andp",
 155 "orp",
 156 "subp",
 157 "xorp",
 158 "loadp",
 159 "cpeq",
 160 "cpneq",
 161 "cpa",
 162 "cpaeq",
 163 "cpb",
 164 "cpbeq",
 165 "cpgt",
 166 "cpgteq",
 167 "cplt",
 168 "cplteq",
 169 "storep",
 170 "btpo",
 171 "btps",
 172 "btpz",
 173 "btpnz",
 174 "baddpo",
 175 "baddps",
 176 "baddpz",
 177 "baddpnz"
 178 ]
 179
 180X86_INSTRUCTIONS =
 181 [
 182 "cdqi",
 183 "idivi"
 184 ]
 185
 186INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS
 187
 188INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
0

Source/JavaScriptCore/offlineasm/offset_extractor_constants.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
 25
 26
0

Source/JavaScriptCore/offlineasm/offsets.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24require "ast"
 25require "offset_extractor_constants"
 26
 27OFFSET_MAGIC_NUMBERS = [ 0xec577ac7, 0x0ff5e755 ]
 28
 29########################################################################
 30# #
 31# offsetsList(ast) #
 32# sizesList(ast) #
 33# #
 34# Returns a list of offsets and sizes used by the AST. #
 35# #
 36########################################################################
 37
 38def offsetsList(ast)
 39 ast.filter(StructOffset).uniq.sort
 40end
 41
 42def sizesList(ast)
 43 ast.filter(Sizeof).uniq.sort
 44end
 45
 46########################################################################
 47# #
 48# offsetsAndConfigurationIndex(ast, file) -> #
 49# [offsets, index] #
 50# #
 51# Parses the offsets from a file and returns a list of offsets and the #
 52# index of the configuration that is valid in this build target. #
 53# #
 54########################################################################
 55
 56def offsetsAndConfigurationIndex(file)
 57 index = nil
 58 offsets = []
 59 endiannessMarkerBytes = nil
 60
 61 def readInt(endianness, inp)
 62 bytes = []
 63 4.times {
 64 bytes << inp.getbyte
 65 }
 66
 67 if endianness == :little
 68 # Little endian
 69 (bytes[0] << 0 |
 70 bytes[1] << 8 |
 71 bytes[2] << 16 |
 72 bytes[3] << 24)
 73 else
 74 # Big endian
 75 (bytes[0] << 24 |
 76 bytes[1] << 16 |
 77 bytes[2] << 8 |
 78 bytes[3] << 0)
 79 end
 80 end
 81
 82 [:little, :big].each {
 83 | endianness |
 84 magicBytes = []
 85 MAGIC_NUMBERS.each {
 86 | number |
 87 currentBytes = []
 88 4.times {
 89 currentBytes << (number & 0xff)
 90 number >>= 8
 91 }
 92 if endianness == :big
 93 currentBytes.reverse!
 94 end
 95 magicBytes += currentBytes
 96 }
 97
 98 File.open(file, "r") {
 99 | inp |
 100 whereInMarker = 0
 101 loop {
 102 byte = inp.getbyte
 103 break unless byte
 104 if byte == magicBytes[whereInMarker]
 105 whereInMarker += 1
 106 if whereInMarker == magicBytes.size
 107 # We have a match! If we have not yet read the endianness marker and index,
 108 # then read those now; otherwise read an offset.
 109
 110 if not index
 111 index = readInt(endianness, inp)
 112 else
 113 offsets << readInt(endianness, inp)
 114 end
 115
 116 whereInMarker = 0
 117 end
 118 else
 119 whereInMarker = 0
 120 end
 121 }
 122 }
 123
 124 break if index
 125 }
 126
 127 raise unless index
 128
 129 [offsets, index]
 130end
 131
 132########################################################################
 133# #
 134# buildOffsetsMap(ast, offsetsList) -> [offsets, sizes] #
 135# #
 136# Builds a mapping between StructOffset nodes and their values. #
 137# #
 138########################################################################
 139
 140def buildOffsetsMap(ast, offsetsList)
 141 offsetsMap = {}
 142 sizesMap = {}
 143 astOffsetsList = offsetsList(ast)
 144 astSizesList = sizesList(ast)
 145 raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
 146 offsetsList(ast).each_with_index {
 147 | structOffset, index |
 148 offsetsMap[structOffset] = offsetsList.shift
 149 }
 150 sizesList(ast).each_with_index {
 151 | sizeof, index |
 152 sizesMap[sizeof] = offsetsList.shift
 153 }
 154 [offsetsMap, sizesMap]
 155end
 156
0

Source/JavaScriptCore/offlineasm/parser.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24require "ast"
 25require "instructions"
 26require "registers"
 27
 28class Token
 29 attr_reader :codeOrigin, :string
 30
 31 def initialize(codeOrigin, string)
 32 @codeOrigin = codeOrigin
 33 @string = string
 34 end
 35
 36 def ==(other)
 37 if other.is_a? Token
 38 @string == other.string
 39 else
 40 @string == other
 41 end
 42 end
 43
 44 def =~(other)
 45 @string =~ other
 46 end
 47
 48 def to_s
 49 "#{@string.inspect} at line #{codeOrigin}"
 50 end
 51
 52 def parseError(*comment)
 53 if comment.empty?
 54 raise "Parse error: #{to_s}"
 55 else
 56 raise "Parse error: #{to_s}: #{comment[0]}"
 57 end
 58 end
 59end
 60
 61########################################################################
 62# #
 63# The lexer. Takes a string and returns an array of tokens. #
 64# #
 65########################################################################
 66
 67def lex(str)
 68 result = []
 69 lineNumber = 1
 70 while not str.empty?
 71 case str
 72 when /\A\#([^\n]*)/
 73 # comment, ignore
 74 when /\A\n/
 75 result << Token.new(lineNumber, $&)
 76 lineNumber += 1
 77 when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
 78 result << Token.new(lineNumber, $&)
 79 when /\A\.([a-zA-Z0-9_]*)/
 80 result << Token.new(lineNumber, $&)
 81 when /\A_([a-zA-Z0-9_]*)/
 82 result << Token.new(lineNumber, $&)
 83 when /\A([ \t]+)/
 84 # whitespace, ignore
 85 when /\A0x([0-9a-fA-F]+)/
 86 result << Token.new(lineNumber, $&.hex.to_s)
 87 when /\A0([0-7]+)/
 88 result << Token.new(lineNumber, $&.oct.to_s)
 89 when /\A([0-9]+)/
 90 result << Token.new(lineNumber, $&)
 91 when /\A::/
 92 result << Token.new(lineNumber, $&)
 93 when /\A[:,\(\)\[\]=\+\-*]/
 94 result << Token.new(lineNumber, $&)
 95 else
 96 raise "Lexer error at line number #{lineNumber}, unexpected sequence #{str[0..20].inspect}"
 97 end
 98 str = $~.post_match
 99 end
 100 result
 101end
 102
 103########################################################################
 104# #
 105# Token identification. #
 106# #
 107########################################################################
 108
 109def isRegister(token)
 110 token =~ REGISTER_PATTERN
 111end
 112
 113def isInstruction(token)
 114 token =~ INSTRUCTION_PATTERN
 115end
 116
 117def isKeyword(token)
 118 token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error))\Z/ or
 119 token =~ REGISTER_PATTERN or
 120 token =~ INSTRUCTION_PATTERN
 121end
 122
 123def isIdentifier(token)
 124 token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
 125end
 126
 127def isLabel(token)
 128 token =~ /\A_([a-zA-Z0-9_]*)\Z/
 129end
 130
 131def isLocalLabel(token)
 132 token =~ /\A\.([a-zA-Z0-9_]*)\Z/
 133end
 134
 135def isVariable(token)
 136 isIdentifier(token) or isRegister(token)
 137end
 138
 139def isInteger(token)
 140 token =~ /\A[0-9]/
 141end
 142
 143########################################################################
 144# #
 145# The parser. Takes an array of tokens and returns an AST. Methods #
 146# other than parse(tokens) are not for public consumption. #
 147# #
 148########################################################################
 149
 150class Parser
 151 def initialize(tokens)
 152 @tokens = tokens
 153 @idx = 0
 154 end
 155
 156 def parseError(*comment)
 157 if @tokens[@idx]
 158 @tokens[@idx].parseError(*comment)
 159 else
 160 if comment.empty?
 161 raise "Parse error at end of file"
 162 else
 163 raise "Parse error at end of file: #{comment[0]}"
 164 end
 165 end
 166 end
 167
 168 def consume(regexp)
 169 if regexp
 170 parseError unless @tokens[@idx] =~ regexp
 171 else
 172 parseError unless @idx == @tokens.length
 173 end
 174 @idx += 1
 175 end
 176
 177 def skipNewLine
 178 while @tokens[@idx] == "\n"
 179 @idx += 1
 180 end
 181 end
 182
 183 def parsePredicateAtom
 184 if @tokens[@idx] == "not"
 185 @idx += 1
 186 parsePredicateAtom
 187 elsif @tokens[@idx] == "("
 188 @idx += 1
 189 skipNewLine
 190 result = parsePredicate
 191 parseError unless @tokens[@idx] == ")"
 192 @idx += 1
 193 result
 194 elsif @tokens[@idx] == "true"
 195 result = True.instance
 196 @idx += 1
 197 result
 198 elsif @tokens[@idx] == "false"
 199 result = False.instance
 200 @idx += 1
 201 result
 202 elsif isIdentifier @tokens[@idx]
 203 result = Setting.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 204 @idx += 1
 205 result
 206 else
 207 parseError
 208 end
 209 end
 210
 211 def parsePredicateAnd
 212 result = parsePredicateAtom
 213 while @tokens[@idx] == "and"
 214 codeOrigin = @tokens[@idx].codeOrigin
 215 @idx += 1
 216 skipNewLine
 217 right = parsePredicateAtom
 218 result = And.new(codeOrigin, result, right)
 219 end
 220 result
 221 end
 222
 223 def parsePredicate
 224 # some examples of precedence:
 225 # not a and b -> (not a) and b
 226 # a and b or c -> (a and b) or c
 227 # a or b and c -> a or (b and c)
 228
 229 result = parsePredicateAnd
 230 while @tokens[@idx] == "or"
 231 codeOrigin = @tokens[@idx].codeOrigin
 232 @idx += 1
 233 skipNewLine
 234 right = parsePredicateAnd
 235 result = Or.new(codeOrigin, result, right)
 236 end
 237 result
 238 end
 239
 240 def parseVariable
 241 if isRegister(@tokens[@idx])
 242 if @tokens[@idx] =~ FPR_PATTERN
 243 result = FPRegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 244 else
 245 result = RegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 246 end
 247 elsif isIdentifier(@tokens[@idx])
 248 result = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 249 else
 250 parseError
 251 end
 252 @idx += 1
 253 result
 254 end
 255
 256 def parseAddress(offset)
 257 parseError unless @tokens[@idx] == "["
 258 codeOrigin = @tokens[@idx].codeOrigin
 259
 260 # Three possibilities:
 261 # [] -> AbsoluteAddress
 262 # [a] -> Address
 263 # [a,b] -> BaseIndex with scale = 1
 264 # [a,b,c] -> BaseIndex
 265
 266 @idx += 1
 267 if @tokens[@idx] == "]"
 268 @idx += 1
 269 return AbsoluteAddress.new(codeOrigin, offset)
 270 end
 271 a = parseVariable
 272 if @tokens[@idx] == "]"
 273 result = Address.new(codeOrigin, a, offset)
 274 else
 275 parseError unless @tokens[@idx] == ","
 276 @idx += 1
 277 b = parseVariable
 278 if @tokens[@idx] == "]"
 279 result = BaseIndex.new(codeOrigin, a, b, 1, offset)
 280 else
 281 parseError unless @tokens[@idx] == ","
 282 @idx += 1
 283 parseError unless ["1", "2", "4", "8"].member? @tokens[@idx].string
 284 c = @tokens[@idx].string.to_i
 285 @idx += 1
 286 parseError unless @tokens[@idx] == "]"
 287 result = BaseIndex.new(codeOrigin, a, b, c, offset)
 288 end
 289 end
 290 @idx += 1
 291 result
 292 end
 293
 294 def parseColonColon
 295 skipNewLine
 296 codeOrigin = @tokens[@idx].codeOrigin
 297 parseError unless isIdentifier @tokens[@idx]
 298 names = [@tokens[@idx].string]
 299 @idx += 1
 300 while @tokens[@idx] == "::"
 301 @idx += 1
 302 parseError unless isIdentifier @tokens[@idx]
 303 names << @tokens[@idx].string
 304 @idx += 1
 305 end
 306 raise if names.empty?
 307 [codeOrigin, names]
 308 end
 309
 310 def parseExpressionAtom
 311 skipNewLine
 312 if @tokens[@idx] == "-"
 313 @idx += 1
 314 NegImmediate.new(@tokens[@idx - 1].codeOrigin, parseExpressionAtom)
 315 elsif @tokens[@idx] == "("
 316 @idx += 1
 317 result = parseExpression
 318 parseError unless @tokens[@idx] == ")"
 319 @idx += 1
 320 result
 321 elsif isInteger @tokens[@idx]
 322 result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
 323 @idx += 1
 324 result
 325 elsif isIdentifier @tokens[@idx]
 326 codeOrigin, names = parseColonColon
 327 if names.size > 1
 328 StructOffset.forField(codeOrigin, names[0..-2].join('::'), names[-1])
 329 else
 330 Variable.forName(codeOrigin, names[0])
 331 end
 332 elsif isRegister @tokens[@idx]
 333 parseVariable
 334 elsif @tokens[@idx] == "sizeof"
 335 @idx += 1
 336 codeOrigin, names = parseColonColon
 337 Sizeof.forName(codeOrigin, names.join('::'))
 338 else
 339 parseError
 340 end
 341 end
 342
 343 def parseExpressionMul
 344 skipNewLine
 345 result = parseExpressionAtom
 346 while @tokens[@idx] == "*"
 347 if @tokens[@idx] == "*"
 348 @idx += 1
 349 result = MulImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAtom)
 350 else
 351 raise
 352 end
 353 end
 354 result
 355 end
 356
 357 def couldBeExpression
 358 @tokens[@idx] == "-" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
 359 end
 360
 361 def parseExpression
 362 skipNewLine
 363 result = parseExpressionMul
 364 while @tokens[@idx] == "+" or @tokens[@idx] == "-"
 365 if @tokens[@idx] == "+"
 366 @idx += 1
 367 result = AddImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
 368 elsif @tokens[@idx] == "-"
 369 @idx += 1
 370 result = SubImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
 371 else
 372 raise
 373 end
 374 end
 375 result
 376 end
 377
 378 def parseOperand(comment)
 379 if couldBeExpression
 380 expr = parseExpression
 381 if @tokens[@idx] == "["
 382 parseAddress(expr)
 383 else
 384 expr
 385 end
 386 elsif @tokens[@idx] == "["
 387 parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
 388 elsif isLabel @tokens[@idx]
 389 result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
 390 @idx += 1
 391 result
 392 elsif isLocalLabel @tokens[@idx]
 393 result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
 394 @idx += 1
 395 result
 396 else
 397 parseError(comment)
 398 end
 399 end
 400
 401 def parseMacroVariables
 402 skipNewLine
 403 consume(/\A\(\Z/)
 404 variables = []
 405 loop {
 406 skipNewLine
 407 if @tokens[@idx] == ")"
 408 @idx += 1
 409 break
 410 elsif isIdentifier(@tokens[@idx])
 411 variables << Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 412 @idx += 1
 413 skipNewLine
 414 if @tokens[@idx] == ")"
 415 @idx += 1
 416 break
 417 elsif @tokens[@idx] == ","
 418 @idx += 1
 419 else
 420 parseError
 421 end
 422 else
 423 parseError
 424 end
 425 }
 426 variables
 427 end
 428
 429 def parseSequence(final, comment)
 430 firstCodeOrigin = @tokens[@idx].codeOrigin
 431 list = []
 432 loop {
 433 if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
 434 break
 435 elsif @tokens[@idx] == "\n"
 436 # ignore
 437 @idx += 1
 438 elsif @tokens[@idx] == "const"
 439 @idx += 1
 440 parseError unless isVariable @tokens[@idx]
 441 variable = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 442 @idx += 1
 443 parseError unless @tokens[@idx] == "="
 444 @idx += 1
 445 value = parseOperand("while inside of const #{variable.name}")
 446 list << ConstDecl.new(@tokens[@idx].codeOrigin, variable, value)
 447 elsif @tokens[@idx] == "error"
 448 list << Error.new(@tokens[@idx].codeOrigin)
 449 @idx += 1
 450 elsif @tokens[@idx] == "if"
 451 codeOrigin = @tokens[@idx].codeOrigin
 452 @idx += 1
 453 skipNewLine
 454 predicate = parsePredicate
 455 consume(/\A((then)|(\n))\Z/)
 456 skipNewLine
 457 ifThenElse = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
 458 list << ifThenElse
 459 while @tokens[@idx] == "elsif"
 460 codeOrigin = @tokens[@idx].codeOrigin
 461 @idx += 1
 462 skipNewLine
 463 predicate = parsePredicate
 464 consume(/\A((then)|(\n))\Z/)
 465 skipNewLine
 466 elseCase = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
 467 ifThenElse.elseCase = elseCase
 468 ifThenElse = elseCase
 469 end
 470 if @tokens[@idx] == "else"
 471 @idx += 1
 472 ifThenElse.elseCase = parseSequence(/\Aend\Z/, "while inside of else case for \"if #{predicate.dump}\"")
 473 @idx += 1
 474 else
 475 parseError unless @tokens[@idx] == "end"
 476 @idx += 1
 477 end
 478 elsif @tokens[@idx] == "macro"
 479 codeOrigin = @tokens[@idx].codeOrigin
 480 @idx += 1
 481 skipNewLine
 482 parseError unless isIdentifier(@tokens[@idx])
 483 name = @tokens[@idx].string
 484 @idx += 1
 485 variables = parseMacroVariables
 486 body = parseSequence(/\Aend\Z/, "while inside of macro #{name}")
 487 @idx += 1
 488 list << Macro.new(codeOrigin, name, variables, body)
 489 elsif isInstruction @tokens[@idx]
 490 codeOrigin = @tokens[@idx].codeOrigin
 491 name = @tokens[@idx].string
 492 @idx += 1
 493 if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
 494 # Zero operand instruction, and it's the last one.
 495 list << Instruction.new(codeOrigin, name, [])
 496 break
 497 elsif @tokens[@idx] == "\n"
 498 # Zero operand instruction.
 499 list << Instruction.new(codeOrigin, name, [])
 500 @idx += 1
 501 else
 502 # It's definitely an instruction, and it has at least one operand.
 503 operands = []
 504 endOfSequence = false
 505 loop {
 506 operands << parseOperand("while inside of instruction #{name}")
 507 if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
 508 # The end of the instruction and of the sequence.
 509 endOfSequence = true
 510 break
 511 elsif @tokens[@idx] == ","
 512 # Has another operand.
 513 @idx += 1
 514 elsif @tokens[@idx] == "\n"
 515 # The end of the instruction.
 516 @idx += 1
 517 break
 518 else
 519 parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
 520 end
 521 }
 522 list << Instruction.new(codeOrigin, name, operands)
 523 if endOfSequence
 524 break
 525 end
 526 end
 527 elsif isIdentifier @tokens[@idx]
 528 codeOrigin = @tokens[@idx].codeOrigin
 529 name = @tokens[@idx].string
 530 @idx += 1
 531 if @tokens[@idx] == "("
 532 # Macro invocation.
 533 @idx += 1
 534 operands = []
 535 skipNewLine
 536 if @tokens[@idx] == ")"
 537 @idx += 1
 538 else
 539 loop {
 540 skipNewLine
 541 if @tokens[@idx] == "macro"
 542 # It's a macro lambda!
 543 codeOriginInner = @tokens[@idx].codeOrigin
 544 @idx += 1
 545 variables = parseMacroVariables
 546 body = parseSequence(/\Aend\Z/, "while inside of anonymous macro passed as argument to #{name}")
 547 @idx += 1
 548 operands << Macro.new(codeOriginInner, nil, variables, body)
 549 else
 550 operands << parseOperand("while inside of macro call to #{name}")
 551 end
 552 skipNewLine
 553 if @tokens[@idx] == ")"
 554 @idx += 1
 555 break
 556 elsif @tokens[@idx] == ","
 557 @idx += 1
 558 else
 559 parseError "Unexpected #{@tokens[@idx].string.inspect} while parsing invocation of macro #{name}"
 560 end
 561 }
 562 end
 563 list << MacroCall.new(codeOrigin, name, operands)
 564 else
 565 parseError "Expected \"(\" after #{name}"
 566 end
 567 elsif isLabel @tokens[@idx] or isLocalLabel @tokens[@idx]
 568 codeOrigin = @tokens[@idx].codeOrigin
 569 name = @tokens[@idx].string
 570 @idx += 1
 571 parseError unless @tokens[@idx] == ":"
 572 # It's a label.
 573 if isLabel name
 574 list << Label.forName(codeOrigin, name)
 575 else
 576 list << LocalLabel.forName(codeOrigin, name)
 577 end
 578 @idx += 1
 579 else
 580 parseError "Expecting terminal #{final} #{comment}"
 581 end
 582 }
 583 Sequence.new(firstCodeOrigin, list)
 584 end
 585end
 586
 587def parse(tokens)
 588 parser = Parser.new(tokens)
 589 parser.parseSequence(nil, "")
 590end
 591
0

Source/JavaScriptCore/offlineasm/registers.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24GPRS =
 25 [
 26 "t0",
 27 "t1",
 28 "t2",
 29 "t3",
 30 "t4",
 31 "cfr",
 32 "a0",
 33 "a1",
 34 "r0",
 35 "r1",
 36 "sp"
 37 ]
 38
 39FPRS =
 40 [
 41 "ft0",
 42 "ft1",
 43 "ft2",
 44 "ft3",
 45 "ft4",
 46 "ft5",
 47 "fa0",
 48 "fa1",
 49 "fa2",
 50 "fa3",
 51 "fr"
 52 ]
 53
 54REGISTERS = GPRS + FPRS
 55
 56GPR_PATTERN = Regexp.new('\\A((' + GPRS.join(')|(') + '))\\Z')
 57FPR_PATTERN = Regexp.new('\\A((' + FPRS.join(')|(') + '))\\Z')
 58
 59REGISTER_PATTERN = Regexp.new('\\A((' + REGISTERS.join(')|(') + '))\\Z')
0

Source/JavaScriptCore/offlineasm/settings.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24require "ast"
 25require "backends"
 26require "parser"
 27require "transform"
 28
 29########################################################################
 30# #
 31# computeSettingsCombinations(ast) -> settingsCombiations #
 32# #
 33# Computes an array of settings maps, where a settings map constitutes #
 34# a configuration for the assembly code being generated. The map #
 35# contains key value pairs where keys are settings names (strings) and #
 36# the values are booleans (true for enabled, false for disabled). #
 37# #
 38########################################################################
 39
 40def computeSettingsCombinations(ast)
 41 settingsCombinations = []
 42
 43 def settingsCombinator(settingsCombinations, mapSoFar, remaining)
 44 if remaining.empty?
 45 settingsCombinations << mapSoFar
 46 return
 47 end
 48
 49 newMap = mapSoFar.dup
 50 newMap[remaining[0]] = true
 51 settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
 52
 53 newMap = mapSoFar.dup
 54 newMap[remaining[0]] = false
 55 settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
 56 end
 57
 58 settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + ["X86", "ARMv7"]).uniq)
 59
 60 settingsCombinations
 61end
 62
 63########################################################################
 64# #
 65# forSettings(concreteSettings, ast) { #
 66# | concreteSettings, lowLevelAST, backend | ... } #
 67# #
 68# Determines if the settings combination is valid, and if so, calls #
 69# the block with the information you need to generate code. #
 70# #
 71########################################################################
 72
 73def forSettings(concreteSettings, ast)
 74 # Check which architectures this combinator claims to support.
 75 numClaimedBackends = 0
 76 selectedBackend = nil
 77 BACKENDS.each {
 78 | backend |
 79 isSupported = concreteSettings[backend]
 80 raise unless isSupported != nil
 81 numClaimedBackends += if isSupported then 1 else 0 end
 82 if isSupported
 83 selectedBackend = backend
 84 end
 85 }
 86
 87 return if numClaimedBackends > 1
 88
 89 # Resolve the AST down to a low-level form (no macros or conditionals).
 90 lowLevelAST = ast.resolveSettings(concreteSettings)
 91
 92 yield concreteSettings, lowLevelAST, selectedBackend
 93end
 94
 95########################################################################
 96# #
 97# forEachValidSettingsCombination(ast) { #
 98# | concreteSettings, ast, backend, index | ... } #
 99# #
 100# forEachValidSettingsCombination(ast, settingsCombinations) { #
 101# | concreteSettings, ast, backend, index | ... } #
 102# #
 103# Executes the given block for each valid settings combination in the #
 104# settings map. The ast passed into the block is resolved #
 105# (ast.resolve) against the settings. #
 106# #
 107# The first form will call computeSettingsCombinations(ast) for you. #
 108# #
 109########################################################################
 110
 111def forEachValidSettingsCombination(ast, *optionalSettingsCombinations)
 112 raise if optionalSettingsCombinations.size > 1
 113
 114 if optionalSettingsCombinations.empty?
 115 settingsCombinations = computeSettingsCombinations(ast)
 116 else
 117 settingsCombinations = optionalSettingsCombiations[0]
 118 end
 119
 120 settingsCombinations.each_with_index {
 121 | concreteSettings, index |
 122 forSettings(concreteSettings, ast) {
 123 | concreteSettings_, lowLevelAST, backend |
 124 yield concreteSettings, lowLevelAST, backend, index
 125 }
 126 }
 127end
 128
 129########################################################################
 130# #
 131# cppSettingsTest(concreteSettings) #
 132# #
 133# Returns the C++ code used to test if we are in a configuration that #
 134# corresponds to the given concrete settings. #
 135# #
 136########################################################################
 137
 138def cppSettingsTest(concreteSettings)
 139 "#if " + concreteSettings.to_a.collect{
 140 | pair |
 141 (if pair[1]
 142 ""
 143 else
 144 "!"
 145 end) + "OFFLINE_ASM_" + pair[0]
 146 }.join(" && ")
 147end
 148
 149########################################################################
 150# #
 151# isASTErroneous(ast) #
 152# #
 153# Tests to see if the AST claims that there is an error - i.e. if the #
 154# user's code, after settings resolution, has Error nodes. #
 155# #
 156########################################################################
 157
 158def isASTErroneous(ast)
 159 not ast.filter(Error).empty?
 160end
 161
 162########################################################################
 163# #
 164# assertConfiguration(concreteSettings) #
 165# #
 166# Emits a check that asserts that we're using the given configuration. #
 167# #
 168########################################################################
 169
 170def assertConfiguration(concreteSettings)
 171 $output.puts cppSettingsTest(concreteSettings)
 172 $output.puts "#else"
 173 $output.puts "#error \"Configuration mismatch.\""
 174 $output.puts "#endif"
 175end
 176
 177########################################################################
 178# #
 179# emitCodeInConfiguration(concreteSettings, ast, backend) { #
 180# | concreteSettings, ast, backend | ... } #
 181# #
 182# Emits all relevant guards to see if the configuration holds and #
 183# calls the block if the configuration is not erroneous. #
 184# #
 185########################################################################
 186
 187def emitCodeInConfiguration(concreteSettings, ast, backend)
 188 $output.puts cppSettingsTest(concreteSettings)
 189
 190 if isASTErroneous(ast)
 191 $output.puts "#error \"Invalid configuration.\""
 192 elsif not WORKING_BACKENDS.include? backend
 193 $output.puts "#error \"This backend is not supported yet.\""
 194 else
 195 yield concreteSettings, ast, backend
 196 end
 197
 198 $output.puts "#endif"
 199end
 200
 201########################################################################
 202# #
 203# emitCodeInAllConfigurations(ast) { #
 204# | concreteSettings, ast, backend, index | ... } #
 205# #
 206# Emits guard codes for all valid configurations, and calls the block #
 207# for those configurations that are valid and not erroneous. #
 208# #
 209########################################################################
 210
 211def emitCodeInAllConfigurations(ast)
 212 forEachValidSettingsCombination(ast) {
 213 | concreteSettings, lowLevelAST, backend, index |
 214 $output.puts cppSettingsTest(concreteSettings)
 215 yield concreteSettings, lowLevelAST, backend, index
 216 $output.puts "#endif"
 217 }
 218end
 219
 220
 221
0

Source/JavaScriptCore/offlineasm/transform.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24require "ast"
 25
 26########################################################################
 27# #
 28# node.resolveSettings(settings) #
 29# #
 30# Construct a new AST that does not have any IfThenElse nodes by #
 31# substituting concrete boolean values for each Setting. #
 32# #
 33########################################################################
 34
 35class Node
 36 def resolveSettings(settings)
 37 mapChildren {
 38 | child |
 39 child.resolveSettings(settings)
 40 }
 41 end
 42end
 43
 44class True
 45 def resolveSettings(settings)
 46 self
 47 end
 48end
 49
 50class False
 51 def resolveSettings(settings)
 52 self
 53 end
 54end
 55
 56class Setting
 57 def resolveSettings(settings)
 58 settings[@name].asNode
 59 end
 60end
 61
 62class And
 63 def resolveSettings(settings)
 64 (@left.resolveSettings(settings).value and @right.resolveSettings(settings).value).asNode
 65 end
 66end
 67
 68class Or
 69 def resolveSettings(settings)
 70 (@left.resolveSettings(settings).value or @right.resolveSettings(settings).value).asNode
 71 end
 72end
 73
 74class Not
 75 def resolveSettings(settings)
 76 (not @child.resolveSettings(settings).value).asNode
 77 end
 78end
 79
 80class IfThenElse
 81 def resolveSettings(settings)
 82 if @predicate.resolveSettings(settings).value
 83 @thenCase.resolveSettings(settings)
 84 else
 85 @elseCase.resolveSettings(settings)
 86 end
 87 end
 88end
 89
 90class Sequence
 91 def resolveSettings(settings)
 92 newList = []
 93 @list.each {
 94 | item |
 95 item = item.resolveSettings(settings)
 96 if item.is_a? Sequence
 97 newList += item.list
 98 else
 99 newList << item
 100 end
 101 }
 102 Sequence.new(codeOrigin, newList)
 103 end
 104end
 105
 106########################################################################
 107# #
 108# node.demacroify(macros) #
 109# node.substitute(mapping) #
 110# #
 111# demacroify() constructs a new AST that does not have any Macro #
 112# nodes, while substitute() replaces Variable nodes with the given #
 113# nodes in the mapping. #
 114# #
 115########################################################################
 116
 117class Node
 118 def demacroify(macros)
 119 mapChildren {
 120 | child |
 121 child.demacroify(macros)
 122 }
 123 end
 124
 125 def substitute(mapping)
 126 mapChildren {
 127 | child |
 128 child.substitute(mapping)
 129 }
 130 end
 131
 132 def substituteLabels(mapping)
 133 mapChildren {
 134 | child |
 135 child.substituteLabels(mapping)
 136 }
 137 end
 138end
 139
 140class Macro
 141 def substitute(mapping)
 142 myMapping = {}
 143 mapping.each_pair {
 144 | key, value |
 145 unless @variables.include? key
 146 myMapping[key] = value
 147 end
 148 }
 149 mapChildren {
 150 | child |
 151 child.substitute(myMapping)
 152 }
 153 end
 154end
 155
 156class Variable
 157 def substitute(mapping)
 158 if mapping[self]
 159 mapping[self]
 160 else
 161 self
 162 end
 163 end
 164end
 165
 166class LocalLabel
 167 def substituteLabels(mapping)
 168 if mapping[self]
 169 mapping[self]
 170 else
 171 self
 172 end
 173 end
 174end
 175
 176class Sequence
 177 def substitute(constants)
 178 newList = []
 179 myConstants = constants.dup
 180 @list.each {
 181 | item |
 182 if item.is_a? ConstDecl
 183 myConstants[item.variable] = item.value.substitute(myConstants)
 184 else
 185 newList << item.substitute(myConstants)
 186 end
 187 }
 188 Sequence.new(codeOrigin, newList)
 189 end
 190
 191 def renameLabels(comment)
 192 mapping = {}
 193
 194 @list.each {
 195 | item |
 196 if item.is_a? LocalLabel
 197 mapping[item] = LocalLabel.unique(if comment then comment + "_" else "" end + item.cleanName)
 198 end
 199 }
 200
 201 substituteLabels(mapping)
 202 end
 203
 204 def demacroify(macros)
 205 myMacros = macros.dup
 206 @list.each {
 207 | item |
 208 if item.is_a? Macro
 209 myMacros[item.name] = item
 210 end
 211 }
 212 newList = []
 213 @list.each {
 214 | item |
 215 if item.is_a? Macro
 216 # Ignore.
 217 elsif item.is_a? MacroCall
 218 mapping = {}
 219 myMyMacros = myMacros.dup
 220 raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros[item.name]
 221 raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
 222 item.operands.size.times {
 223 | idx |
 224 if item.operands[idx].is_a? Variable and myMacros[item.operands[idx].name]
 225 myMyMacros[myMacros[item.name].variables[idx].name] = myMacros[item.operands[idx].name]
 226 mapping[myMacros[item.name].variables[idx].name] = nil
 227 elsif item.operands[idx].is_a? Macro
 228 myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx]
 229 mapping[myMacros[item.name].variables[idx].name] = nil
 230 else
 231 myMyMacros[myMacros[item.name].variables[idx]] = nil
 232 mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
 233 end
 234 }
 235 newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
 236 else
 237 newList << item.demacroify(myMacros)
 238 end
 239 }
 240 Sequence.new(codeOrigin, newList).substitute({})
 241 end
 242end
 243
 244########################################################################
 245# #
 246# node.resolveOffsets(offsets, sizes) #
 247# #
 248# Construct a new AST that has offset values instead of symbolic #
 249# offsets. #
 250# #
 251########################################################################
 252
 253class Node
 254 def resolveOffsets(offsets, sizes)
 255 mapChildren {
 256 | child |
 257 child.resolveOffsets(offsets, sizes)
 258 }
 259 end
 260end
 261
 262class StructOffset
 263 def resolveOffsets(offsets, sizes)
 264 if offsets[self]
 265 Immediate.new(codeOrigin, offsets[self])
 266 else
 267 self
 268 end
 269 end
 270end
 271
 272class Sizeof
 273 def resolveOffsets(offsets, sizes)
 274 if sizes[self]
 275 Immediate.new(codeOrigin, sizes[self])
 276 else
 277 puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
 278 puts "sizes = #{sizes.inspect}"
 279 self
 280 end
 281 end
 282end
 283
 284########################################################################
 285# #
 286# node.fold #
 287# #
 288# Resolve constant references and compute arithmetic expressions. #
 289# #
 290########################################################################
 291
 292class Node
 293 def fold
 294 mapChildren {
 295 | child |
 296 child.fold
 297 }
 298 end
 299end
 300
 301class AddImmediates
 302 def fold
 303 @left = @left.fold
 304 @right = @right.fold
 305 return self unless @left.is_a? Immediate
 306 return self unless @right.is_a? Immediate
 307 Immediate.new(codeOrigin, @left.value + @right.value)
 308 end
 309end
 310
 311class SubImmediates
 312 def fold
 313 @left = @left.fold
 314 @right = @right.fold
 315 return self unless @left.is_a? Immediate
 316 return self unless @right.is_a? Immediate
 317 Immediate.new(codeOrigin, @left.value - @right.value)
 318 end
 319end
 320
 321class MulImmediates
 322 def fold
 323 @left = @left.fold
 324 @right = @right.fold
 325 return self unless @left.is_a? Immediate
 326 return self unless @right.is_a? Immediate
 327 Immediate.new(codeOrigin, @left.value * @right.value)
 328 end
 329end
 330
 331class NegImmediate
 332 def fold
 333 @child = @child.fold
 334 return self unless @child.is_a? Immediate
 335 Immediate.new(codeOrigin, -@child.value)
 336 end
 337end
 338
 339########################################################################
 340# #
 341# node.resolveAfterSettings(offsets, sizes) #
 342# #
 343# Compile assembly against a set of offsets. #
 344# #
 345########################################################################
 346
 347class Node
 348 def resolve(offsets, sizes)
 349 demacroify({}).resolveOffsets(offsets, sizes).fold
 350 end
 351end
 352
0

Source/JavaScriptCore/offlineasm/x86.rb

 1# Copyright (C) 2011 Apple Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions
 5# are met:
 6# 1. Redistributions of source code must retain the above copyright
 7# notice, this list of conditions and the following disclaimer.
 8# 2. Redistributions in binary form must reproduce the above copyright
 9# notice, this list of conditions and the following disclaimer in the
 10# documentation and/or other materials provided with the distribution.
 11#
 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 22# THE POSSIBILITY OF SUCH DAMAGE.
 23
 24class RegisterID
 25 def supports8BitOnX86
 26 case name
 27 when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3"
 28 true
 29 when "t4", "cfr"
 30 false
 31 else
 32 raise
 33 end
 34 end
 35
 36 def x86Operand(kind)
 37 case name
 38 when "t0", "a0", "r0"
 39 case kind
 40 when :byte
 41 "%al"
 42 when :half
 43 "%ax"
 44 when :int
 45 "%eax"
 46 else
 47 raise
 48 end
 49 when "t1", "a1", "r1"
 50 case kind
 51 when :byte
 52 "%dl"
 53 when :half
 54 "%dx"
 55 when :int
 56 "%edx"
 57 else
 58 raise
 59 end
 60 when "t2"
 61 case kind
 62 when :byte
 63 "%cl"
 64 when :half
 65 "%cx"
 66 when :int
 67 "%ecx"
 68 else
 69 raise
 70 end
 71 when "t3"
 72 case kind
 73 when :byte
 74 "%bl"
 75 when :half
 76 "%bx"
 77 when :int
 78 "%ebx"
 79 else
 80 raise
 81 end
 82 when "t4"
 83 case kind
 84 when :byte
 85 "%sil"
 86 when :half
 87 "%si"
 88 when :int
 89 "%esi"
 90 else
 91 raise
 92 end
 93 when "cfr"
 94 case kind
 95 when :byte
 96 "%dil"
 97 when :half
 98 "%di"
 99 when :int
 100 "%edi"
 101 else
 102 raise
 103 end
 104 when "sp"
 105 case kind
 106 when :byte
 107 "%spl"
 108 when :half
 109 "%sp"
 110 when :int
 111 "%esp"
 112 else
 113 raise
 114 end
 115 else
 116 raise
 117 end
 118 end
 119 def x86CallOperand(kind)
 120 "*#{x86Operand(kind)}"
 121 end
 122end
 123
 124class FPRegisterID
 125 def x86Operand(kind)
 126 raise unless kind == :double
 127 case name
 128 when "ft0", "fa0", "fr"
 129 "%xmm0"
 130 when "ft1", "fa1"
 131 "%xmm1"
 132 when "ft2", "fa2"
 133 "%xmm2"
 134 when "ft3", "fa3"
 135 "%xmm3"
 136 when "ft4"
 137 "%xmm4"
 138 when "ft5"
 139 "%xmm5"
 140 else
 141 raise
 142 end
 143 end
 144 def x86CallOperand(kind)
 145 "*#{x86Operand(kind)}"
 146 end
 147end
 148
 149class Immediate
 150 def x86Operand(kind)
 151 "$#{value}"
 152 end
 153 def x86CallOperand(kind)
 154 "#{value}"
 155 end
 156end
 157
 158class Address
 159 def supports8BitOnX86
 160 true
 161 end
 162
 163 def x86Operand(kind)
 164 "#{offset.value}(#{base.x86Operand(:int)})"
 165 end
 166 def x86CallOperand(kind)
 167 "*#{x86Operand(kind)}"
 168 end
 169end
 170
 171class BaseIndex
 172 def supports8BitOnX86
 173 true
 174 end
 175
 176 def x86Operand(kind)
 177 "#{offset.value}(#{base.x86Operand(:int)}, #{index.x86Operand(:int)}, #{scale})"
 178 end
 179
 180 def x86CallOperand(kind)
 181 "*#{x86operand(kind)}"
 182 end
 183end
 184
 185class AbsoluteAddress
 186 def supports8BitOnX86
 187 true
 188 end
 189
 190 def x86Operand(kind)
 191 "#{address.value}"
 192 end
 193
 194 def x86CallOperand(kind)
 195 "*#{address.value}"
 196 end
 197end
 198
 199class LabelReference
 200 def x86Label
 201 sanitizeLabelName(name)
 202 end
 203 def x86CallOperand(kind)
 204 x86Label
 205 end
 206end
 207
 208class LocalLabelReference
 209 def x86Label
 210 "L_offlineasm_"+name[1..-1]
 211 end
 212 def x86CallOperand(kind)
 213 x86Label
 214 end
 215end
 216
 217class Instruction
 218 def x86Operands(*kinds)
 219 raise unless kinds.size == operands.size
 220 result = []
 221 kinds.size.times {
 222 | idx |
 223 result << operands[idx].x86Operand(kinds[idx])
 224 }
 225 result.join(", ")
 226 end
 227
 228 def x86Suffix(kind)
 229 case kind
 230 when :byte
 231 "b"
 232 when :half
 233 "w"
 234 when :int
 235 "l"
 236 when :double
 237 "sd"
 238 else
 239 raise
 240 end
 241 end
 242
 243 def handleX86OpWithNumOperands(opcode, kind, numOperands)
 244 if numOperands == 3
 245 if operands[0] == operands[2]
 246 $asm.puts "\t#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 247 elsif operands[1] == operands[2]
 248 $asm.puts "\t#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 249 else
 250 $asm.puts "\tmov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 251 $asm.puts "\t#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 252 end
 253 else
 254 $asm.puts "\t#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
 255 end
 256 end
 257
 258 def handleX86Op(opcode, kind)
 259 handleX86OpWithNumOperands(opcode, kind, operands.size)
 260 end
 261
 262 def handleX86Shift(opcode, kind)
 263 if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
 264 $asm.puts "\t#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
 265 else
 266 $asm.puts "\txchgl #{operands[0].x86Operand(:int)}, %ecx"
 267 $asm.puts "\t#{opcode} %cl, #{operands[1].x86Operand(kind)}"
 268 $asm.puts "\txchgl #{operands[0].x86Operand(:int)}, %ecx"
 269 end
 270 end
 271
 272 def handleX86DoubleBranch(branchOpcode, mode)
 273 case mode
 274 when :normal
 275 $asm.puts "\tucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
 276 when :reverse
 277 $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 278 else
 279 raise mode.inspect
 280 end
 281 $asm.puts "\t#{branchOpcode} #{operands[2].x86Label}"
 282 end
 283
 284 def handleX86IntCompare(opcodeSuffix, kind)
 285 if operands[0].is_a? Immediate and operands[0].value == 0 and operands[1].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
 286 $asm.puts "\ttest#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}"
 287 elsif operands[1].is_a? Immediate and operands[1].value == 0 and operands[0].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
 288 $asm.puts "\ttest#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}"
 289 else
 290 $asm.puts "\tcmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
 291 end
 292 end
 293
 294 def handleX86IntBranch(branchOpcode, kind)
 295 handleX86IntCompare(branchOpcode[1..-1], kind)
 296 $asm.puts "\t#{branchOpcode} #{operands[2].x86Label}"
 297 end
 298
 299 def handleX86Set(setOpcode, operand)
 300 if operand.supports8BitOnX86
 301 $asm.puts "\t#{setOpcode} #{operand.x86Operand(:byte)}"
 302 $asm.puts "\tmovzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
 303 else
 304 $asm.puts "\txchgl #{operand.x86Operand(:int)}, %eax"
 305 $asm.puts "\t#{setOpcode} %al"
 306 $asm.puts "\tmovzbl %al, %eax"
 307 $asm.puts "\txchgl #{operand.x86Operand(:int)}, %eax"
 308 end
 309 end
 310
 311 def handleX86IntCompareSet(setOpcode, kind)
 312 handleX86IntCompare(setOpcode[3..-1], kind)
 313 handleX86Set(setOpcode, operands[2])
 314 end
 315
 316 def handleX86Test(kind)
 317 value = operands[0]
 318 case operands.size
 319 when 2
 320 mask = Immediate.new(codeOrigin, -1)
 321 when 3
 322 mask = operands[1]
 323 else
 324 raise "Expected 2 or 3 operands, but got #{operands.size} at #{codeOriginString}"
 325 end
 326
 327 if mask.is_a? Immediate and mask.value == -1
 328 if value.is_a? RegisterID
 329 $asm.puts "\ttest#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
 330 else
 331 $asm.puts "\tcmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
 332 end
 333 else
 334 $asm.puts "\ttest#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
 335 end
 336 end
 337
 338 def handleX86BranchTest(branchOpcode, kind)
 339 handleX86Test(kind)
 340 $asm.puts "\t#{branchOpcode} #{operands.last.x86Label}"
 341 end
 342
 343 def handleX86SetTest(setOpcode, kind)
 344 handleX86Test(kind)
 345 handleX86Set(setOpcode, operands.last)
 346 end
 347
 348 def handleX86OpBranch(opcode, branchOpcode, kind)
 349 handleX86OpWithNumOperands(opcode, kind, operands.size - 1)
 350 case operands.size
 351 when 4
 352 jumpTarget = operands[3]
 353 when 3
 354 jumpTarget = operands[2]
 355 else
 356 raise self.inspect
 357 end
 358 $asm.puts "\t#{branchOpcode} #{jumpTarget.x86Label}"
 359 end
 360
 361 def handleX86SubBranch(branchOpcode, kind)
 362 if operands.size == 4 and operands[1] == operands[2]
 363 $asm.puts "\tnegl #{operands[2].x86Operand(:int)}"
 364 $asm.puts "\taddl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 365 else
 366 handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
 367 end
 368 case operands.size
 369 when 4
 370 jumpTarget = operands[3]
 371 when 3
 372 jumpTarget = operands[2]
 373 else
 374 raise self.inspect
 375 end
 376 $asm.puts "\t#{branchOpcode} #{jumpTarget.x86Label}"
 377 end
 378
 379 def lowerX86
 380 $asm.comment codeOriginString
 381 case opcode
 382 when "addi", "addp"
 383 if operands.size == 3 and operands[0].is_a? Immediate
 384 raise unless operands[1].is_a? RegisterID
 385 raise unless operands[2].is_a? RegisterID
 386 if operands[0].value == 0
 387 unless operands[1] == operands[2]
 388 $asm.puts "\tmovl #{operands[1].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 389 end
 390 else
 391 $asm.puts "\tleal #{operands[0].value}(#{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
 392 end
 393 elsif operands.size == 3 and operands[0].is_a? RegisterID
 394 raise unless operands[1].is_a? RegisterID
 395 raise unless operands[2].is_a? RegisterID
 396 $asm.puts "\tleal (#{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
 397 else
 398 unless Immediate.new(nil, 0) == operands[0]
 399 $asm.puts "\taddl #{x86Operands(:int, :int)}"
 400 end
 401 end
 402 when "andi", "andp"
 403 handleX86Op("andl", :int)
 404 when "lshifti"
 405 handleX86Shift("sall", :int)
 406 when "muli"
 407 if operands.size == 3 and operands[0].is_a? Immediate
 408 $asm.puts "\timull #{x86Operands(:int, :int, :int)}"
 409 else
 410 # FIXME: could do some peephole in case the left operand is immediate and it's
 411 # a power of two.
 412 handleX86Op("imull", :int)
 413 end
 414 when "negi"
 415 $asm.puts "\tnegl #{x86Operands(:int)}"
 416 when "noti"
 417 $asm.puts "\tnotl #{x86Operands(:int)}"
 418 when "ori", "orp"
 419 handleX86Op("orl", :int)
 420 when "rshifti"
 421 handleX86Shift("sarl", :int)
 422 when "urshifti"
 423 handleX86Shift("shrl", :int)
 424 when "subi", "subp"
 425 if operands.size == 3 and operands[1] == operands[2]
 426 $asm.puts "\tnegl #{operands[2].x86Operand(:int)}"
 427 $asm.puts "\taddl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 428 else
 429 handleX86Op("subl", :int)
 430 end
 431 when "xori", "xorp"
 432 handleX86Op("xorl", :int)
 433 when "loadi", "storei", "loadp", "storep"
 434 $asm.puts "\tmovl #{x86Operands(:int, :int)}"
 435 when "loadb"
 436 $asm.puts "\tmovzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
 437 when "loadh"
 438 $asm.puts "\tmovzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
 439 when "storeb"
 440 $asm.puts "\tmovb #{x86Operands(:byte, :byte)}"
 441 when "loadd", "moved", "stored"
 442 $asm.puts "\tmovsd #{x86Operands(:double, :double)}"
 443 when "addd"
 444 $asm.puts "\taddsd #{x86Operands(:double, :double)}"
 445 when "divd"
 446 $asm.puts "\tdivsd #{x86Operands(:double, :double)}"
 447 when "subd"
 448 $asm.puts "\tsubsd #{x86Operands(:double, :double)}"
 449 when "muld"
 450 $asm.puts "\tmulsd #{x86Operands(:double, :double)}"
 451 when "sqrtd"
 452 $asm.puts "\tsqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 453 when "ci2d"
 454 $asm.puts "\tcvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
 455 when "bdeq"
 456 isUnordered = LocalLabel.unique("bdeq")
 457 $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 458 $asm.puts "\tjp #{LabelReference.new(codeOrigin, isUnordered).x86Label}"
 459 $asm.puts "\tje #{LabelReference.new(codeOrigin, operands[2]).x86Label}"
 460 isUnordered.lower("X86")
 461 when "bdneq"
 462 handleX86DoubleBranch("jne", :normal)
 463 when "bdgt"
 464 handleX86DoubleBranch("ja", :normal)
 465 when "bdgteq"
 466 handleX86DoubleBranch("jae", :normal)
 467 when "bdlt"
 468 handleX86DoubleBranch("ja", :reverse)
 469 when "bdlteq"
 470 handleX86DoubleBranch("jae", :reverse)
 471 when "bdequn"
 472 handleX86DoubleBranch("je", :normal)
 473 when "bdnequn"
 474 isUnordered = LocalLabel.unique("bdnequn")
 475 isEqual = LocalLabel.unique("bdnequn")
 476 $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 477 $asm.puts "\tjp #{LabelReference.new(codeOrigin, isUnordered).x86Label}"
 478 $asm.puts "\tje #{LabelReference.new(codeOrigin, isEqual).x86Label}"
 479 isUnordered.lower("X86")
 480 $asm.puts "\tjmp #{operands[2].x86Label}"
 481 isEqual.lower("X86")
 482 when "bdgtun"
 483 handleX86DoubleBranch("jb", :reverse)
 484 when "bdgtequn"
 485 handleX86DoubleBranch("jbe", :reverse)
 486 when "bdltun"
 487 handleX86DoubleBranch("jb", :normal)
 488 when "bdltequn"
 489 handleX86DoubleBranch("jbe", :normal)
 490 when "btd2i"
 491 $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 492 $asm.puts "\tcmpl $0x80000000 #{operands[1].x86Operand(:int)}"
 493 $asm.puts "\tje #{operands[2].x86Label}"
 494 when "td2i"
 495 $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 496 when "bcd2i"
 497 $asm.puts "\tcvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 498 $asm.puts "\ttestl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
 499 $asm.puts "\tje #{operands[2].x86Label}"
 500 $asm.puts "\tcvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
 501 $asm.puts "\tucomisd #{operands[0].x86Operand(:double)}, %xmm7"
 502 $asm.puts "\tjp #{operands[2].x86Label}"
 503 $asm.puts "\tjne #{operands[2].x86Label}"
 504 when "movdz"
 505 $asm.puts "\txorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
 506 when "pop"
 507 $asm.puts "\tpop #{operands[0].x86Operand(:int)}"
 508 when "push"
 509 $asm.puts "\tpush #{operands[0].x86Operand(:int)}"
 510 when "move", "sxi2p", "zxi2p"
 511 if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
 512 $asm.puts "\txorl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
 513 elsif operands[0] != operands[1]
 514 $asm.puts "\tmovl #{x86Operands(:int, :int)}"
 515 end
 516 when "nop"
 517 $asm.puts "\tnop"
 518 when "bieq", "bpeq"
 519 handleX86IntBranch("je", :int)
 520 when "bineq", "bpneq"
 521 handleX86IntBranch("jne", :int)
 522 when "bia", "bpa"
 523 handleX86IntBranch("ja", :int)
 524 when "biaeq", "bpaeq"
 525 handleX86IntBranch("jae", :int)
 526 when "bib", "bpb"
 527 handleX86IntBranch("jb", :int)
 528 when "bibeq", "bpbeq"
 529 handleX86IntBranch("jbe", :int)
 530 when "bigt", "bpgt"
 531 handleX86IntBranch("jg", :int)
 532 when "bigteq", "bpgteq"
 533 handleX86IntBranch("jge", :int)
 534 when "bilt", "bplt"
 535 handleX86IntBranch("jl", :int)
 536 when "bilteq", "bplteq"
 537 handleX86IntBranch("jle", :int)
 538 when "bbeq"
 539 handleX86IntBranch("je", :byte)
 540 when "bbneq"
 541 handleX86IntBranch("jne", :byte)
 542 when "bba"
 543 handleX86IntBranch("ja", :byte)
 544 when "bbaeq"
 545 handleX86IntBranch("jae", :byte)
 546 when "bbb"
 547 handleX86IntBranch("jb", :byte)
 548 when "bbbeq"
 549 handleX86IntBranch("jbe", :byte)
 550 when "bbgt"
 551 handleX86IntBranch("jg", :byte)
 552 when "bbgteq"
 553 handleX86IntBranch("jge", :byte)
 554 when "bblt"
 555 handleX86IntBranch("jl", :byte)
 556 when "bblteq"
 557 handleX86IntBranch("jlteq", :byte)
 558 when "btio", "btpo"
 559 handleX86BranchTest("jo", :int)
 560 when "btis", "btps"
 561 handleX86BranchTest("js", :int)
 562 when "btiz", "btpz"
 563 handleX86BranchTest("jz", :int)
 564 when "btinz", "btpnz"
 565 handleX86BranchTest("jnz", :int)
 566 when "btbo"
 567 handleX86BranchTest("jo", :byte)
 568 when "btbs"
 569 handleX86BranchTest("js", :byte)
 570 when "btbz"
 571 handleX86BranchTest("jz", :byte)
 572 when "btbnz"
 573 handleX86BranchTest("jnz", :byte)
 574 when "jmp"
 575 $asm.puts "\tjmp #{operands[0].x86CallOperand(:int)}"
 576 when "baddio", "baddpo"
 577 handleX86OpBranch("addl", "jo", :int)
 578 when "baddis", "baddps"
 579 handleX86OpBranch("addl", "js", :int)
 580 when "baddiz", "baddpz"
 581 handleX86OpBranch("addl", "jz", :int)
 582 when "baddinz", "baddpnz"
 583 handleX86OpBranch("addl", "jnz", :int)
 584 when "bsubio"
 585 handleX86SubBranch("jo", :int)
 586 when "bsubis"
 587 handleX86SubBranch("js", :int)
 588 when "bsubiz"
 589 handleX86SubBranch("jz", :int)
 590 when "bsubinz"
 591 handleX86SubBranch("jnz", :int)
 592 when "bmulio"
 593 handleX86OpBranch("imull", "jo", :int)
 594 when "bmulis"
 595 handleX86OpBranch("imull", "js", :int)
 596 when "bmuliz"
 597 handleX86OpBranch("imull", "jz", :int)
 598 when "bmulinz"
 599 handleX86OpBranch("imull", "jnz", :int)
 600 when "borio"
 601 handleX86OpBranch("orl", "jo", :int)
 602 when "boris"
 603 handleX86OpBranch("orl", "js", :int)
 604 when "boriz"
 605 handleX86OpBranch("orl", "jz", :int)
 606 when "borinz"
 607 handleX86OpBranch("orl", "jnz", :int)
 608 when "break"
 609 $asm.puts "\tint $3"
 610 when "call"
 611 $asm.puts "\tcall #{operands[0].x86CallOperand(:int)}"
 612 when "ret"
 613 $asm.puts "\tret"
 614 when "cieq", "cpeq"
 615 handleX86IntCompareSet("sete", :int)
 616 when "cineq", "cpneq"
 617 handleX86IntCompareSet("setne", :int)
 618 when "cia", "cpa"
 619 handleX86IntCompareSet("seta", :int)
 620 when "ciaeq", "cpaeq"
 621 handleX86IntCompareSet("setae", :int)
 622 when "cib", "cpb"
 623 handleX86IntCompareSet("setb", :int)
 624 when "cibeq", "cpbeq"
 625 handleX86IntCompareSet("setbe", :int)
 626 when "cigt", "cpgt"
 627 handleX86IntCompareSet("setg", :int)
 628 when "cigteq", "cpgteq"
 629 handleX86IntCompareSet("setge", :int)
 630 when "cilt", "cplt"
 631 handleX86IntCompareSet("setl", :int)
 632 when "cilteq", "cplteq"
 633 handleX86IntCompareSet("setle", :int)
 634 when "tio"
 635 handleX86SetTest("seto", :int)
 636 when "tis"
 637 handleX86SetTest("sets", :int)
 638 when "tiz"
 639 handleX86SetTest("setz", :int)
 640 when "tinz"
 641 handleX86SetTest("setnz", :int)
 642 when "tbo"
 643 handleX86SetTest("seto", :byte)
 644 when "tbs"
 645 handleX86SetTest("sets", :byte)
 646 when "tbz"
 647 handleX86SetTest("setz", :byte)
 648 when "tbnz"
 649 handleX86SetTest("setnz", :byte)
 650 when "peek"
 651 $asm.puts "\tmovl #{operands[0].value * 4}(%esp), #{operands[1].x86Operand(:int)}"
 652 when "poke"
 653 $asm.puts "\tmovl #{operands[0].x86Operand(:int)}, #{operands[1].value * 4}(%esp)"
 654 when "cdqi"
 655 $asm.puts "\tcdq"
 656 when "idivi"
 657 $asm.puts "\tidivl #{operands[0].x86Operand(:int)}"
 658 when "fii2d"
 659 $asm.puts "\tmovd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
 660 $asm.puts "\tmovd #{operands[1].x86Operand(:int)}, %xmm7"
 661 $asm.puts "\tpsllq $32, %xmm7"
 662 $asm.puts "\tpor %xmm7, #{operands[2].x86Operand(:double)}"
 663 when "fd2ii"
 664 $asm.puts "\tmovd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 665 $asm.puts "\tmovsd #{operands[0].x86Operand(:double)}, %xmm7"
 666 $asm.puts "\tpsrlq $32, %xmm7"
 667 $asm.puts "\tmovsd %xmm7, #{operands[2].x86Operand(:int)}"
 668 else
 669 raise "Bad opcode: #{opcode}"
 670 end
 671 end
 672end
 673
0

Source/JavaScriptCore/runtime/CodeSpecializationKind.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef CodeSpecializationKind_h
 27#define CodeSpecializationKind_h
 28
 29namespace JSC {
 30
 31enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
 32
 33} // namespace JSC
 34
 35#endif // CodeSpecializationKind_h
 36
0

Source/JavaScriptCore/runtime/CommonSlowPaths.h

2727#define CommonSlowPaths_h
2828
2929#include "CodeBlock.h"
 30#include "CodeSpecializationKind.h"
3031#include "ExceptionHelpers.h"
3132#include "JSArray.h"
3233

@@namespace JSC {
4142
4243namespace CommonSlowPaths {
4344
 45ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFile, CodeSpecializationKind kind)
 46{
 47 JSFunction* callee = asFunction(exec->callee());
 48 ASSERT(!callee->isHostFunction());
 49 CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
 50 int argumentCountIncludingThis = exec->argumentCountIncludingThis();
 51
 52 // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
 53 if (!registerFile->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
 54 return 0;
 55
 56 ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
 57
 58 // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
 59 size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
 60 Register* src = exec->registers();
 61 Register* dst = exec->registers() + delta;
 62
 63 int i;
 64 int end = -ExecState::offsetFor(argumentCountIncludingThis);
 65 for (i = -1; i >= end; --i)
 66 dst[i] = src[i];
 67
 68 end -= delta;
 69 for ( ; i >= end; --i)
 70 dst[i] = jsUndefined();
 71
 72 ExecState* newExec = ExecState::create(dst);
 73 ASSERT((void*)newExec <= registerFile->end());
 74 return newExec;
 75}
 76
4477ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)
4578{
4679 ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
105770

Source/JavaScriptCore/runtime/Executable.cpp

2929#include "BytecodeGenerator.h"
3030#include "CodeBlock.h"
3131#include "DFGDriver.h"
 32#include "ExecutionHarness.h"
3233#include "JIT.h"
3334#include "JITDriver.h"
3435#include "Parser.h"

@@Intrinsic NativeExecutable::intrinsic()
8485template<typename T>
8586static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
8687{
87  ASSERT(codeBlock->getJITType() != JITCode::BaselineJIT);
 88 ASSERT(JITCode::isOptimizingJIT(codeBlock->getJITType()));
8889 ASSERT(codeBlock->alternative());
8990 OwnPtr<T> codeBlockToJettison = codeBlock.release();
9091 codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());

@@JSObject* EvalExecutable::compileOptimiz
167168 return error;
168169}
169170
 171void EvalExecutable::jitCompile(JSGlobalData& globalData)
 172{
 173 bool result = jitCompileIfAppropriate(globalData, m_evalCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
 174 ASSERT_UNUSED(result, result);
 175}
 176
 177inline const char* samplingDescription(JITCode::JITType jitType)
 178{
 179 switch (jitType) {
 180 case JITCode::InterpreterThunk:
 181 return "Interpreter Compilation (TOTAL)";
 182 case JITCode::BaselineJIT:
 183 return "Baseline Compilation (TOTAL)";
 184 case JITCode::DFGJIT:
 185 return "DFG Compilation (TOTAL)";
 186 default:
 187 ASSERT_NOT_REACHED();
 188 return 0;
 189 }
 190}
 191
170192JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
171193{
172  SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
 194 SamplingRegion samplingRegion(samplingDescription(jitType));
173195
174196#if !ENABLE(JIT)
175197 UNUSED_PARAM(jitType);

@@JSObject* EvalExecutable::compileInterna
210232 }
211233
212234#if ENABLE(JIT)
213  if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
 235 if (!prepareForExecution(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
214236 return 0;
215237#endif
216238

@@JSObject* ProgramExecutable::compileOpti
295317 return error;
296318}
297319
 320void ProgramExecutable::jitCompile(JSGlobalData& globalData)
 321{
 322 bool result = jitCompileIfAppropriate(globalData, m_programCodeBlock, m_jitCodeForCall, JITCode::bottomTierJIT());
 323 ASSERT_UNUSED(result, result);
 324}
 325
298326JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
299327{
300  SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
 328 SamplingRegion samplingRegion(samplingDescription(jitType));
301329
302330#if !ENABLE(JIT)
303331 UNUSED_PARAM(jitType);

@@JSObject* ProgramExecutable::compileInte
336364 }
337365
338366#if ENABLE(JIT)
339  if (!jitCompileIfAppropriate(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
 367 if (!prepareForExecution(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
340368 return 0;
341369#endif
342370

@@FunctionCodeBlock* FunctionExecutable::b
412440 while (result->alternative())
413441 result = static_cast<FunctionCodeBlock*>(result->alternative());
414442 ASSERT(result);
415  ASSERT(result->getJITType() == JITCode::BaselineJIT);
 443 ASSERT(JITCode::isBaselineCode(result->getJITType()));
416444 return result;
417445}
418446

@@JSObject* FunctionExecutable::compileOpt
438466 return error;
439467}
440468
 469void FunctionExecutable::jitCompileForCall(JSGlobalData& globalData)
 470{
 471 bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
 472 ASSERT_UNUSED(result, result);
 473}
 474
 475void FunctionExecutable::jitCompileForConstruct(JSGlobalData& globalData)
 476{
 477 bool result = jitCompileFunctionIfAppropriate(globalData, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
 478 ASSERT_UNUSED(result, result);
 479}
 480
441481FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
442482{
443483 FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);

@@PassOwnPtr<FunctionCodeBlock> FunctionEx
482522
483523JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
484524{
485  SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
 525 SamplingRegion samplingRegion(samplingDescription(jitType));
486526
487527#if !ENABLE(JIT)
488528 UNUSED_PARAM(exec);

@@JSObject* FunctionExecutable::compileFor
504544 m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
505545
506546#if ENABLE(JIT)
507  if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType))
 547 if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, CodeForCall))
508548 return 0;
509549#endif
510550

@@JSObject* FunctionExecutable::compileFor
524564
525565JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
526566{
527  SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
 567 SamplingRegion samplingRegion(samplingDescription(jitType));
528568
529569#if !ENABLE(JIT)
530570 UNUSED_PARAM(jitType);

@@JSObject* FunctionExecutable::compileFor
546586 m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
547587
548588#if ENABLE(JIT)
549  if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType))
 589 if (!prepareFunctionForExecution(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, CodeForConstruct))
550590 return 0;
551591#endif
552592
105770

Source/JavaScriptCore/runtime/Executable.h

2727#define Executable_h
2828
2929#include "CallData.h"
 30#include "CodeSpecializationKind.h"
3031#include "JSFunction.h"
3132#include "Interpreter.h"
3233#include "Nodes.h"

@@namespace JSC {
3940 class Debugger;
4041 class EvalCodeBlock;
4142 class FunctionCodeBlock;
 43 class LLIntOffsetsExtractor;
4244 class ProgramCodeBlock;
4345 class ScopeChainNode;
4446
4547 struct ExceptionInfo;
4648
47  enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
4849 enum CompilationKind { FirstCompilation, OptimizingCompilation };
4950
5051 inline bool isCall(CodeSpecializationKind kind)

@@namespace JSC {
319320 };
320321
321322 class EvalExecutable : public ScriptExecutable {
 323 friend class LLIntOffsetsExtractor;
322324 public:
323325 typedef ScriptExecutable Base;
324326

@@namespace JSC {
338340
339341#if ENABLE(JIT)
340342 void jettisonOptimizedCode(JSGlobalData&);
 343 void jitCompile(JSGlobalData&);
341344#endif
342345
343346 EvalCodeBlock& generatedBytecode()

@@namespace JSC {
384387 };
385388
386389 class ProgramExecutable : public ScriptExecutable {
 390 friend class LLIntOffsetsExtractor;
387391 public:
388392 typedef ScriptExecutable Base;
389393

@@namespace JSC {
411415
412416#if ENABLE(JIT)
413417 void jettisonOptimizedCode(JSGlobalData&);
 418 void jitCompile(JSGlobalData&);
414419#endif
415420
416421 ProgramCodeBlock& generatedBytecode()

@@namespace JSC {
453458
454459 class FunctionExecutable : public ScriptExecutable {
455460 friend class JIT;
 461 friend class LLIntOffsetsExtractor;
456462 public:
457463 typedef ScriptExecutable Base;
458464

@@namespace JSC {
508514
509515#if ENABLE(JIT)
510516 void jettisonOptimizedCodeForCall(JSGlobalData&);
 517 void jitCompileForCall(JSGlobalData&);
511518#endif
512519
513520 bool isGeneratedForCall() const

@@namespace JSC {
535542
536543#if ENABLE(JIT)
537544 void jettisonOptimizedCodeForConstruct(JSGlobalData&);
 545 void jitCompileForConstruct(JSGlobalData&);
538546#endif
539547
540548 bool isGeneratedForConstruct() const

@@namespace JSC {
582590 jettisonOptimizedCodeForConstruct(globalData);
583591 }
584592 }
 593
 594 void jitCompileFor(JSGlobalData& globalData, CodeSpecializationKind kind)
 595 {
 596 if (kind == CodeForCall) {
 597 jitCompileForCall(globalData);
 598 return;
 599 }
 600 ASSERT(kind == CodeForConstruct);
 601 jitCompileForConstruct(globalData);
 602 }
585603#endif
586604
587605 bool isGeneratedFor(CodeSpecializationKind kind)
105770

Source/JavaScriptCore/runtime/ExecutionHarness.h

 1/*
 2 * Copyright (C) 2012 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef ExecutionHarness_h
 27#define ExecutionHarness_h
 28
 29#include <wtf/Platform.h>
 30
 31#if ENABLE(JIT)
 32
 33#include "JITDriver.h"
 34#include "LLIntEntrypoints.h"
 35
 36namespace JSC {
 37
 38template<typename CodeBlockType>
 39inline bool prepareForExecution(JSGlobalData& globalData, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
 40{
 41#if ENABLE(LLINT)
 42 if (JITCode::isBaselineCode(jitType)) {
 43 // Start off in the low level interpreter.
 44 LLInt::getEntrypoint(globalData, codeBlock.get(), jitCode);
 45 codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
 46 return true;
 47 }
 48#endif // ENABLE(LLINT)
 49 return jitCompileIfAppropriate(globalData, codeBlock, jitCode, jitType);
 50}
 51
 52inline bool prepareFunctionForExecution(JSGlobalData& globalData, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, CodeSpecializationKind kind)
 53{
 54#if ENABLE(LLINT)
 55 if (JITCode::isBaselineCode(jitType)) {
 56 // Start off in the low level interpreter.
 57 LLInt::getFunctionEntrypoint(globalData, kind, jitCode, jitCodeWithArityCheck);
 58 codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
 59 return true;
 60 }
 61#else
 62 UNUSED_PARAM(kind);
 63#endif // ENABLE(LLINT)
 64 return jitCompileFunctionIfAppropriate(globalData, codeBlock, jitCode, jitCodeWithArityCheck, symbolTable, jitType);
 65}
 66
 67} // namespace JSC
 68
 69#endif // ENABLE(JIT)
 70
 71#endif // ExecutionHarness_h
 72
0

Source/JavaScriptCore/runtime/JSActivation.h

@@namespace JSC {
124124
125125 OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]);
126126 WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset;
127 
 127
128128 // Copy all arguments that can be captured by name or by the arguments object.
129129 for (int i = 0; i < m_numCapturedArgs; ++i) {
130130 int index = CallFrame::argumentOffset(i);
105770

Source/JavaScriptCore/runtime/JSArray.h

2828namespace JSC {
2929
3030 class JSArray;
 31 class LLIntOffsetsExtractor;
3132
3233 struct SparseArrayEntry : public WriteBarrier<Unknown> {
3334 typedef WriteBarrier<Unknown> Base;

@@namespace JSC {
122123 };
123124
124125 class JSArray : public JSNonFinalObject {
 126 friend class LLIntOffsetsExtractor;
125127 friend class Walker;
126128
127129 protected:
105770

Source/JavaScriptCore/runtime/JSCell.h

3636namespace JSC {
3737
3838 class JSGlobalObject;
39  class Structure;
 39 class LLIntOffsetsExtractor;
4040 class PropertyDescriptor;
4141 class PropertyNameArray;
 42 class Structure;
4243
4344 enum EnumerationMode {
4445 ExcludeDontEnumProperties,

@@namespace JSC {
164165 static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
165166
166167 private:
 168 friend class LLIntOffsetsExtractor;
 169
167170 const ClassInfo* m_classInfo;
168171 WriteBarrier<Structure> m_structure;
169172 };
105770

Source/JavaScriptCore/runtime/JSFunction.h

@@namespace JSC {
3333 class FunctionPrototype;
3434 class JSActivation;
3535 class JSGlobalObject;
 36 class LLIntOffsetsExtractor;
3637 class NativeExecutable;
3738 class SourceCode;
3839 namespace DFG {

@@namespace JSC {
140141 static void visitChildren(JSCell*, SlotVisitor&);
141142
142143 private:
 144 friend class LLIntOffsetsExtractor;
 145
143146 JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
144147
145148 static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
105770

Source/JavaScriptCore/runtime/JSGlobalData.cpp

@@JSGlobalData::JSGlobalData(GlobalDataTyp
141141 , keywords(adoptPtr(new Keywords(this)))
142142 , interpreter(0)
143143 , heap(this, heapSize)
 144 , jsArrayClassInfo(&JSArray::s_info)
 145 , jsFinalObjectClassInfo(&JSFinalObject::s_info)
144146#if ENABLE(DFG_JIT)
145147 , sizeOfLastScratchBuffer(0)
146148#endif

@@JSGlobalData::JSGlobalData(GlobalDataTyp
216218 jitStubs = adoptPtr(new JITThunks(this));
217219#endif
218220
219  interpreter->initialize(this->canUseJIT());
 221 interpreter->initialize(&llintData, this->canUseJIT());
220222
221223 heap.notifyIsSafeToCollect();
222224}
105770

Source/JavaScriptCore/runtime/JSGlobalData.h

3030#define JSGlobalData_h
3131
3232#include "CachedTranscendentalFunction.h"
33 #include "Intrinsic.h"
3433#include "DateInstanceCache.h"
3534#include "ExecutableAllocator.h"
3635#include "Heap.h"
37 #include "Strong.h"
 36#include "Intrinsic.h"
3837#include "JITStubs.h"
3938#include "JSValue.h"
 39#include "LLIntData.h"
4040#include "NumericStrings.h"
4141#include "SmallStrings.h"
 42#include "Strong.h"
4243#include "Terminator.h"
4344#include "TimeoutChecker.h"
4445#include "WeakRandom.h"

@@namespace JSC {
6566 class JSGlobalObject;
6667 class JSObject;
6768 class Keywords;
 69 class LLIntOffsetsExtractor;
6870 class NativeExecutable;
6971 class ParserArena;
7072 class RegExpCache;

@@namespace JSC {
241243 Heap heap;
242244
243245 JSValue exception;
 246
 247 const ClassInfo* const jsArrayClassInfo;
 248 const ClassInfo* const jsFinalObjectClassInfo;
 249
 250 LLInt::Data llintData;
 251
244252#if ENABLE(JIT)
245253 ReturnAddressPtr exceptionLocation;
246254 JSValue hostCallReturnValue;

@@namespace JSC {
346354#undef registerTypedArrayFunction
347355
348356 private:
 357 friend class LLIntOffsetsExtractor;
 358
349359 JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
350360 static JSGlobalData*& sharedInstanceInternal();
351361 void createNativeThunk();
105770

Source/JavaScriptCore/runtime/JSGlobalObject.h

@@namespace JSC {
4444 class FunctionPrototype;
4545 class GetterSetter;
4646 class GlobalCodeBlock;
 47 class LLIntOffsetsExtractor;
4748 class NativeErrorConstructor;
4849 class ProgramCodeBlock;
4950 class RegExpConstructor;

@@namespace JSC {
335336 JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
336337
337338 private:
 339 friend class LLIntOffsetsExtractor;
 340
338341 // FIXME: Fold reset into init.
339342 JS_EXPORT_PRIVATE void init(JSObject* thisValue);
340343 void reset(JSValue prototype);
105770

Source/JavaScriptCore/runtime/JSObject.h

@@namespace JSC {
4949 class GetterSetter;
5050 class HashEntry;
5151 class InternalFunction;
 52 class LLIntOffsetsExtractor;
5253 class MarkedBlock;
5354 class PropertyDescriptor;
5455 class PropertyNameArray;

@@namespace JSC {
271272 JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
272273
273274 private:
 275 friend class LLIntOffsetsExtractor;
 276
274277 // Nobody should ever ask any of these questions on something already known to be a JSObject.
275278 using JSCell::isAPIValueWrapper;
276279 using JSCell::isGetterSetter;

@@COMPILE_ASSERT((JSFinalObject_inlineStor
383386 static void destroy(JSCell*);
384387
385388 private:
 389 friend class LLIntOffsetsExtractor;
 390
386391 explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
387392 : JSObject(globalData, structure, m_inlineStorage)
388393 {
105770

Source/JavaScriptCore/runtime/JSPropertyNameIterator.h

@@namespace JSC {
3838
3939 class Identifier;
4040 class JSObject;
 41 class LLIntOffsetsExtractor;
4142
4243 class JSPropertyNameIterator : public JSCell {
4344 friend class JIT;

@@namespace JSC {
9697 }
9798
9899 private:
 100 friend class LLIntOffsetsExtractor;
 101
99102 JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
100103
101104 WriteBarrier<Structure> m_cachedStructure;
105770

Source/JavaScriptCore/runtime/JSString.h

3232namespace JSC {
3333
3434 class JSString;
 35 class LLIntOffsetsExtractor;
3536
3637 JSString* jsEmptyString(JSGlobalData*);
3738 JSString* jsEmptyString(ExecState*);

@@namespace JSC {
240241 static void visitChildren(JSCell*, SlotVisitor&);
241242
242243 private:
 244 friend class LLIntOffsetsExtractor;
 245
243246 JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
244247 void resolveRopeSlowCase8(LChar*) const;
245248 void resolveRopeSlowCase(UChar*) const;
105770

Source/JavaScriptCore/runtime/JSTypeInfo.h

3434
3535namespace JSC {
3636
 37 class LLIntOffsetsExtractor;
 38
3739 static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
3840 static const unsigned ImplementsHasInstance = 1 << 1;
3941 static const unsigned OverridesHasInstance = 1 << 2;

@@namespace JSC {
8789 }
8890
8991 private:
 92 friend class LLIntOffsetsExtractor;
 93
9094 bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
9195 bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
9296
105770

Source/JavaScriptCore/runtime/JSValue.cpp

@@JSObject* JSValue::synthesizePrototype(E
116116 return JSNotAnObject::create(exec);
117117}
118118
119 #ifndef NDEBUG
120119char* JSValue::description()
121120{
122  static const size_t size = 64;
 121 static const size_t size = 128;
123122 static char description[size];
124123
125124 if (!*this)

@@char* JSValue::description()
128127 snprintf(description, size, "Int32: %d", asInt32());
129128 else if (isDouble()) {
130129#if USE(JSVALUE64)
131  snprintf(description, size, "Double: %lf, %lx", asDouble(), reinterpretDoubleToIntptr(asDouble()));
 130 snprintf(description, size, "Double: %lx, %lf", reinterpretDoubleToIntptr(asDouble()), asDouble());
132131#else
133132 union {
134133 double asDouble;
135134 uint32_t asTwoInt32s[2];
136135 } u;
137136 u.asDouble = asDouble();
138  snprintf(description, size, "Double: %lf, %08x:%08x", asDouble(), u.asTwoInt32s[1], u.asTwoInt32s[0]);
 137 snprintf(description, size, "Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
139138#endif
140139 } else if (isCell())
141140 snprintf(description, size, "Cell: %p", asCell());

@@char* JSValue::description()
152151
153152 return description;
154153}
155 #endif
156154
157155// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
158156// Note that this operation is identical to ToUInt32 other than to interpretation
105770

Source/JavaScriptCore/runtime/JSValue.h

@@namespace JSC {
232232 JSCell* asCell() const;
233233 JS_EXPORT_PRIVATE bool isValidCallee();
234234
235 #ifndef NDEBUG
236235 char* description();
237 #endif
238236
239237 private:
240238 template <class T> JSValue(WriteBarrierBase<T>);
105770

Source/JavaScriptCore/runtime/JSVariableObject.h

3838
3939namespace JSC {
4040
 41 class LLIntOffsetsExtractor;
4142 class Register;
4243
4344 class JSVariableObject : public JSNonFinalObject {
4445 friend class JIT;
 46 friend class LLIntOffsetsExtractor;
4547
4648 public:
4749 typedef JSNonFinalObject Base;
105770

Source/JavaScriptCore/runtime/Options.cpp

@@unsigned maximumFunctionForConstructInli
5252
5353unsigned maximumInliningDepth;
5454
 55int32_t executionCounterValueForJITAfterWarmUp;
 56int32_t executionCounterValueForDontJITAnytimeSoon;
 57int32_t executionCounterValueForJITSoon;
 58
5559int32_t executionCounterValueForOptimizeAfterWarmUp;
5660int32_t executionCounterValueForOptimizeAfterLongWarmUp;
5761int32_t executionCounterValueForDontOptimizeAnytimeSoon;

@@void initializeOptions()
137141
138142 SET(maximumInliningDepth, 5);
139143
 144 SET(executionCounterValueForJITAfterWarmUp, -100);
 145 SET(executionCounterValueForDontJITAnytimeSoon, std::numeric_limits<int32_t>::min());
 146 SET(executionCounterValueForJITSoon, -100);
 147
140148 SET(executionCounterValueForOptimizeAfterWarmUp, -1000);
141149 SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
142150 SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());

@@void initializeOptions()
185193 if (cpusToUse < 1)
186194 cpusToUse = 1;
187195
 196 cpusToUse = 1;
 197
188198 SET(numberOfGCMarkers, cpusToUse);
189199
190200 ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
105770

Source/JavaScriptCore/runtime/Options.h

@@extern unsigned maximumFunctionForConstr
3737
3838extern unsigned maximumInliningDepth; // Depth of inline stack, so 1 = no inlining, 2 = one level, etc.
3939
 40extern int32_t executionCounterValueForJITAfterWarmUp;
 41extern int32_t executionCounterValueForDontJITAnytimeSoon;
 42extern int32_t executionCounterValueForJITSoon;
 43
4044extern int32_t executionCounterValueForOptimizeAfterWarmUp;
4145extern int32_t executionCounterValueForOptimizeAfterLongWarmUp;
4246extern int32_t executionCounterValueForDontOptimizeAnytimeSoon;
105770

Source/JavaScriptCore/runtime/ScopeChain.h

@@namespace JSC {
3030 class JSGlobalData;
3131 class JSGlobalObject;
3232 class JSObject;
 33 class LLIntOffsetsExtractor;
3334 class ScopeChainIterator;
3435 class SlotVisitor;
3536

@@namespace JSC {
9192 static JS_EXPORTDATA const ClassInfo s_info;
9293
9394 private:
 95 friend class LLIntOffsetsExtractor;
 96
9497 static const unsigned StructureFlags = OverridesVisitChildren;
9598 };
9699
105770

Source/JavaScriptCore/runtime/Structure.h

4545
4646namespace JSC {
4747
 48 class LLIntOffsetsExtractor;
4849 class PropertyNameArray;
4950 class PropertyNameArrayData;
5051 class StructureChain;

@@namespace JSC {
196197 static JS_EXPORTDATA const ClassInfo s_info;
197198
198199 private:
 200 friend class LLIntOffsetsExtractor;
 201
199202 JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
200203 Structure(JSGlobalData&);
201204 Structure(JSGlobalData&, const Structure*);
105770

Source/JavaScriptCore/runtime/StructureChain.h

3737
3838namespace JSC {
3939
 40 class LLIntOffsetsExtractor;
4041 class Structure;
4142
4243 class StructureChain : public JSCell {

@@namespace JSC {
7475 }
7576
7677 private:
 78 friend class LLIntOffsetsExtractor;
 79
7780 StructureChain(JSGlobalData&, Structure*);
7881 static void destroy(JSCell*);
7982 OwnArrayPtr<WriteBarrier<Structure> > m_vector;
105770

Source/JavaScriptCore/wtf/Platform.h

918918#define ENABLE_JIT 1
919919#endif
920920
 921/* On some of the platforms where we have a JIT, we want to also have the
 922 low-level interpreter. */
 923#if !defined(ENABLE_LLINT) && ENABLE(JIT) && PLATFORM(MAC) && USE(JSVALUE32_64)
 924#define ENABLE_LLINT 1
 925#endif
 926
 927/* If we have LLInt enabled and the JIT enabled, we also enable OSRing from
 928 LLInt to the JIT. */
 929#if !defined(ENABLE_LLINT_OSR_TO_JIT) && ENABLE(JIT) && ENABLE(LLINT)
 930#define ENABLE_LLINT_OSR_TO_JIT 1
 931#endif
 932
921933#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
922934/* Enable the DFG JIT on X86 and X86_64. Only tested on Mac and GNU/Linux. */
923935#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
105770

Source/JavaScriptCore/wtf/SentinelLinkedList.h

@@public:
8686
8787 iterator begin();
8888 iterator end();
 89
 90 bool isEmpty() { return begin() == end(); }
8991
9092private:
9193 RawNode m_headSentinel;
105770

Source/JavaScriptCore/wtf/text/StringImpl.h

@@typedef const struct __CFString * CFStri
4343// Landing the file moves in one patch, will follow on with patches to change the namespaces.
4444namespace JSC {
4545struct IdentifierCStringTranslator;
 46class LLIntOffsetsExtractor;
4647template <typename T> struct IdentifierCharBufferTranslator;
4748struct IdentifierLCharFromUCharTranslator;
4849}

@@class StringImpl {
7273 friend struct WTF::SubstringTranslator;
7374 friend struct WTF::UCharBufferTranslator;
7475 friend class AtomicStringImpl;
75 
 76 friend class JSC::LLIntOffsetsExtractor;
 77
7678private:
7779 enum BufferOwnership {
7880 BufferInternal,
105770