Source/JavaScriptCore/ChangeLog

 12012-01-30 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.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
 41 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
 42 * JavaScriptCore.xcodeproj/project.pbxproj:
 43 * Target.pri:
 44 * assembler/LinkBuffer.h:
 45 * bytecode/BytecodeConventions.h: Added.
 46 * bytecode/CallLinkStatus.cpp:
 47 (JSC::CallLinkStatus::computeFromLLInt):
 48 (JSC):
 49 (JSC::CallLinkStatus::computeFor):
 50 * bytecode/CallLinkStatus.h:
 51 (JSC::CallLinkStatus::isSet):
 52 (JSC::CallLinkStatus::operator!):
 53 (CallLinkStatus):
 54 * bytecode/CodeBlock.cpp:
 55 (JSC):
 56 (JSC::escapeQuotes):
 57 (JSC::CodeBlock::dump):
 58 (JSC::CodeBlock::CodeBlock):
 59 (JSC::CodeBlock::~CodeBlock):
 60 (JSC::CodeBlock::finalizeUnconditionally):
 61 (JSC::CodeBlock::stronglyVisitStrongReferences):
 62 (JSC::CodeBlock::unlinkCalls):
 63 (JSC::CodeBlock::unlinkIncomingCalls):
 64 (JSC::CodeBlock::bytecodeOffset):
 65 (JSC::ProgramCodeBlock::jettison):
 66 (JSC::EvalCodeBlock::jettison):
 67 (JSC::FunctionCodeBlock::jettison):
 68 (JSC::ProgramCodeBlock::jitCompileImpl):
 69 (JSC::EvalCodeBlock::jitCompileImpl):
 70 (JSC::FunctionCodeBlock::jitCompileImpl):
 71 (JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
 72 (JSC::CodeBlock::usesOpcode):
 73 * bytecode/CodeBlock.h:
 74 (JSC):
 75 (CodeBlock):
 76 ():
 77 (JSC::CodeBlock::baselineVersion):
 78 (JSC::CodeBlock::linkIncomingCall):
 79 (JSC::CodeBlock::bytecodeOffset):
 80 (JSC::CodeBlock::jitCompile):
 81 (JSC::CodeBlock::hasOptimizedReplacement):
 82 (JSC::CodeBlock::addPropertyAccessInstruction):
 83 (JSC::CodeBlock::addGlobalResolveInstruction):
 84 (JSC::CodeBlock::addLLIntCallLinkInfo):
 85 (JSC::CodeBlock::addGlobalResolveInfo):
 86 (JSC::CodeBlock::numberOfMethodCallLinkInfos):
 87 (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
 88 (JSC::CodeBlock::likelyToTakeSlowCase):
 89 (JSC::CodeBlock::couldTakeSlowCase):
 90 (JSC::CodeBlock::likelyToTakeSpecialFastCase):
 91 (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
 92 (JSC::CodeBlock::likelyToTakeAnySlowCase):
 93 (JSC::CodeBlock::addFrequentExitSite):
 94 (JSC::CodeBlock::dontJITAnytimeSoon):
 95 (JSC::CodeBlock::jitAfterWarmUp):
 96 (JSC::CodeBlock::jitSoon):
 97 (JSC::CodeBlock::llintExecuteCounter):
 98 (ProgramCodeBlock):
 99 (EvalCodeBlock):
 100 (FunctionCodeBlock):
 101 * bytecode/GetByIdStatus.cpp:
 102 (JSC::GetByIdStatus::computeFromLLInt):
 103 (JSC):
 104 (JSC::GetByIdStatus::computeFor):
 105 * bytecode/GetByIdStatus.h:
 106 (JSC::GetByIdStatus::GetByIdStatus):
 107 (JSC::GetByIdStatus::wasSeenInJIT):
 108 (GetByIdStatus):
 109 * bytecode/Instruction.h:
 110 (JSC):
 111 (JSC::Instruction::Instruction):
 112 (Instruction):
 113 ():
 114 * bytecode/LLIntCallLinkInfo.h: Added.
 115 (JSC):
 116 (JSC::LLIntCallLinkInfo::LLIntCallLinkInfo):
 117 (LLIntCallLinkInfo):
 118 (JSC::LLIntCallLinkInfo::~LLIntCallLinkInfo):
 119 (JSC::LLIntCallLinkInfo::isLinked):
 120 (JSC::LLIntCallLinkInfo::unlink):
 121 * bytecode/MethodCallLinkStatus.cpp:
 122 (JSC::MethodCallLinkStatus::computeFor):
 123 * bytecode/Opcode.h:
 124 (JSC):
 125 ():
 126 * bytecode/PutByIdStatus.cpp:
 127 (JSC::PutByIdStatus::computeFromLLInt):
 128 (JSC):
 129 (JSC::PutByIdStatus::computeFor):
 130 * bytecode/PutByIdStatus.h:
 131 (PutByIdStatus):
 132 * bytecompiler/BytecodeGenerator.cpp:
 133 (JSC):
 134 (JSC::BytecodeGenerator::setDumpsGeneratedCode):
 135 (JSC::BytecodeGenerator::dumpsGeneratedCode):
 136 (JSC::BytecodeGenerator::generate):
 137 (JSC::BytecodeGenerator::emitResolve):
 138 (JSC::BytecodeGenerator::emitResolveWithBase):
 139 (JSC::BytecodeGenerator::emitResolveWithThis):
 140 (JSC::BytecodeGenerator::emitGetById):
 141 (JSC::BytecodeGenerator::emitPutById):
 142 (JSC::BytecodeGenerator::emitDirectPutById):
 143 (JSC::BytecodeGenerator::emitCall):
 144 (JSC::BytecodeGenerator::emitConstruct):
 145 (JSC::BytecodeGenerator::emitCatch):
 146 * dfg/DFGByteCodeParser.cpp:
 147 (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
 148 (JSC::DFG::ByteCodeParser::handleInlining):
 149 (JSC::DFG::ByteCodeParser::parseBlock):
 150 * dfg/DFGCapabilities.h:
 151 (JSC::DFG::canCompileOpcode):
 152 * dfg/DFGOSRExitCompiler.cpp:
 153 ():
 154 * dfg/DFGOperations.cpp:
 155 ():
 156 * heap/AllocationSpace.h:
 157 (JSC):
 158 (AllocationSpace):
 159 ():
 160 * heap/Heap.cpp:
 161 (JSC::Heap::collect):
 162 * heap/Heap.h:
 163 (JSC):
 164 ():
 165 (Heap):
 166 * heap/MarkStack.cpp:
 167 (JSC::visitChildren):
 168 * heap/MarkedSpace.h:
 169 (JSC):
 170 (MarkedSpace):
 171 * interpreter/CallFrame.h:
 172 (ExecState):
 173 (JSC::ExecState::currentVPC):
 174 * interpreter/Interpreter.cpp:
 175 (JSC::Interpreter::~Interpreter):
 176 (JSC):
 177 (JSC::Interpreter::initialize):
 178 (JSC::Interpreter::isOpcode):
 179 (JSC::Interpreter::unwindCallFrame):
 180 (JSC::Interpreter::retrieveLastCaller):
 181 * interpreter/Interpreter.h:
 182 (JSC):
 183 ():
 184 (Interpreter):
 185 (JSC::Interpreter::getOpcode):
 186 (JSC::Interpreter::getOpcodeID):
 187 (JSC::Interpreter::enabled):
 188 * interpreter/RegisterFile.h:
 189 (JSC):
 190 (RegisterFile):
 191 * jit/HostCallReturnValue.cpp: Added.
 192 (JSC):
 193 (JSC::getHostCallReturnValueWithExecState):
 194 * jit/HostCallReturnValue.h: Added.
 195 (JSC):
 196 * jit/JIT.cpp:
 197 (JSC::JIT::privateCompileMainPass):
 198 (JSC::JIT::privateCompileSlowCases):
 199 (JSC::JIT::privateCompile):
 200 * jit/JITCode.h:
 201 ():
 202 (JSC::JITCode::isOptimizingJIT):
 203 (JITCode):
 204 (JSC::JITCode::isBaselineCode):
 205 (JSC::JITCode::JITCode):
 206 * jit/JITDriver.h:
 207 (JSC::jitCompileIfAppropriate):
 208 (JSC::jitCompileFunctionIfAppropriate):
 209 * jit/JITExceptions.cpp:
 210 (JSC::jitThrow):
 211 * jit/JITStubs.cpp:
 212 (JSC::DEFINE_STUB_FUNCTION):
 213 (JSC):
 214 * jit/JSInterfaceJIT.h:
 215 * llint: Added.
 216 * llint/LLIntCommon.h: Added.
 217 * llint/LLIntData.cpp: Added.
 218 (LLInt):
 219 (JSC::LLInt::Data::Data):
 220 (JSC::LLInt::Data::~Data):
 221 * llint/LLIntData.h: Added.
 222 (JSC):
 223 (LLInt):
 224 (Data):
 225 (JSC::LLInt::Data::exceptionInstructions):
 226 (JSC::LLInt::Data::opcodeMap):
 227 * llint/LLIntEntrypoints.cpp: Added.
 228 (LLInt):
 229 (JSC::LLInt::getFunctionEntrypoint):
 230 (JSC::LLInt::getEvalEntrypoint):
 231 (JSC::LLInt::getProgramEntrypoint):
 232 * llint/LLIntEntrypoints.h: Added.
 233 (JSC):
 234 (LLInt):
 235 (JSC::LLInt::getEntrypoint):
 236 * llint/LLIntExceptions.cpp: Added.
 237 (LLInt):
 238 (JSC::LLInt::interpreterThrowInCaller):
 239 (JSC::LLInt::returnToThrowForThrownException):
 240 (JSC::LLInt::returnToThrow):
 241 (JSC::LLInt::callToThrow):
 242 * llint/LLIntExceptions.h: Added.
 243 (JSC):
 244 (LLInt):
 245 * llint/LLIntHelpers.cpp: Added.
 246 (LLInt):
 247 (JSC::LLInt::llint_trace_operand):
 248 (JSC::LLInt::llint_trace_value):
 249 (JSC::LLInt::LLINT_HELPER_DECL):
 250 (JSC::LLInt::traceFunctionPrologue):
 251 (JSC::LLInt::shouldJIT):
 252 ():
 253 (JSC::LLInt::entryOSR):
 254 (JSC::LLInt::resolveGlobal):
 255 (JSC::LLInt::getByVal):
 256 (JSC::LLInt::handleHostCall):
 257 (JSC::LLInt::setUpCall):
 258 (JSC::LLInt::genericCall):
 259 * llint/LLIntHelpers.h: Added.
 260 (JSC):
 261 (LLInt):
 262 * llint/LLIntOfflineAsmConfig.h: Added.
 263 * llint/LLIntOffsetsExtractor.cpp: Added.
 264 (JSC):
 265 (LLIntOffsetsExtractor):
 266 (JSC::LLIntOffsetsExtractor::dummy):
 267 (main):
 268 * llint/LLIntThunks.cpp: Added.
 269 (LLInt):
 270 (JSC::LLInt::generateThunkWithJumpTo):
 271 (JSC::LLInt::functionForCallEntryThunkGenerator):
 272 (JSC::LLInt::functionForConstructEntryThunkGenerator):
 273 (JSC::LLInt::functionForCallArityCheckThunkGenerator):
 274 (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
 275 (JSC::LLInt::evalEntryThunkGenerator):
 276 (JSC::LLInt::programEntryThunkGenerator):
 277 * llint/LLIntThunks.h: Added.
 278 (JSC):
 279 (LLInt):
 280 * llint/LowLevelInterpreter.asm: Added.
 281 * llint/LowLevelInterpreter.cpp: Added.
 282 * llint/LowLevelInterpreter.h: Added.
 283 * offlineasm: Added.
 284 * offlineasm/armv7.rb: Added.
 285 * offlineasm/asm.rb: Added.
 286 * offlineasm/ast.rb: Added.
 287 * offlineasm/backends.rb: Added.
 288 * offlineasm/generate_offset_extractor.rb: Added.
 289 * offlineasm/instructions.rb: Added.
 290 * offlineasm/offset_extractor_constants.rb: Added.
 291 * offlineasm/offsets.rb: Added.
 292 * offlineasm/opt.rb: Added.
 293 * offlineasm/parser.rb: Added.
 294 * offlineasm/registers.rb: Added.
 295 * offlineasm/self_hash.rb: Added.
 296 * offlineasm/settings.rb: Added.
 297 * offlineasm/transform.rb: Added.
 298 * offlineasm/x86.rb: Added.
 299 * runtime/CodeSpecializationKind.h: Added.
 300 (JSC):
 301 ():
 302 * runtime/CommonSlowPaths.h:
 303 (JSC::CommonSlowPaths::arityCheckFor):
 304 (CommonSlowPaths):
 305 (JSC::CommonSlowPaths::opInstanceOfSlow):
 306 * runtime/Executable.cpp:
 307 (JSC::jettisonCodeBlock):
 308 (JSC::EvalExecutable::jitCompile):
 309 (JSC):
 310 (JSC::samplingDescription):
 311 (JSC::EvalExecutable::compileInternal):
 312 (JSC::ProgramExecutable::jitCompile):
 313 (JSC::ProgramExecutable::compileInternal):
 314 (JSC::FunctionExecutable::baselineCodeBlockFor):
 315 (JSC::FunctionExecutable::jitCompileForCall):
 316 (JSC::FunctionExecutable::jitCompileForConstruct):
 317 (JSC::FunctionExecutable::compileForCallInternal):
 318 (JSC::FunctionExecutable::compileForConstructInternal):
 319 * runtime/Executable.h:
 320 (JSC):
 321 ():
 322 (EvalExecutable):
 323 (ProgramExecutable):
 324 (FunctionExecutable):
 325 (JSC::FunctionExecutable::jitCompileFor):
 326 * runtime/ExecutionHarness.h: Added.
 327 (JSC):
 328 (JSC::prepareForExecution):
 329 (JSC::prepareFunctionForExecution):
 330 * runtime/JSActivation.h:
 331 (JSC::JSActivation::tearOff):
 332 * runtime/JSArray.h:
 333 (JSC):
 334 (JSArray):
 335 * runtime/JSCell.h:
 336 (JSC):
 337 ():
 338 (JSCell):
 339 * runtime/JSFunction.h:
 340 (JSC):
 341 (JSFunction):
 342 * runtime/JSGlobalData.cpp:
 343 (JSC::JSGlobalData::JSGlobalData):
 344 * runtime/JSGlobalData.h:
 345 (JSC):
 346 (JSGlobalData):
 347 (JSC::JSGlobalData::scratchBufferForSize):
 348 * runtime/JSGlobalObject.h:
 349 (JSC):
 350 (JSGlobalObject):
 351 * runtime/JSObject.h:
 352 (JSC):
 353 ():
 354 (JSObject):
 355 (JSFinalObject):
 356 * runtime/JSPropertyNameIterator.h:
 357 (JSC):
 358 (JSPropertyNameIterator):
 359 * runtime/JSString.h:
 360 (JSC):
 361 (JSString):
 362 * runtime/JSTypeInfo.h:
 363 (JSC):
 364 (TypeInfo):
 365 * runtime/JSValue.cpp:
 366 (JSC):
 367 (JSC::JSValue::description):
 368 * runtime/JSValue.h:
 369 (JSValue):
 370 ():
 371 * runtime/JSVariableObject.h:
 372 (JSC):
 373 (JSVariableObject):
 374 * runtime/Options.cpp:
 375 (Options):
 376 (JSC::Options::initializeOptions):
 377 * runtime/Options.h:
 378 (Options):
 379 * runtime/ScopeChain.h:
 380 (JSC):
 381 (ScopeChainNode):
 382 * runtime/Structure.h:
 383 (JSC):
 384 (Structure):
 385 * runtime/StructureChain.h:
 386 (JSC):
 387 (StructureChain):
 388 * wtf/InlineASM.h:
 389 * wtf/Platform.h:
 390 * wtf/SentinelLinkedList.h:
 391 (SentinelLinkedList):
 392 (WTF::SentinelLinkedList::isEmpty):
 393 * wtf/text/StringImpl.h:
 394 (JSC):
 395 (StringImpl):
 396 ():
 397
13982012-01-30 Oliver Hunt <oliver@apple.com>
2399
3400 Unexpected syntax error
106297

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
9596 interpreter/RegisterFile.cpp
9697
9798 jit/ExecutableAllocator.cpp
 99 jit/HostCallReturnValue.cpp
98100 jit/JITArithmetic32_64.cpp
99101 jit/JITArithmetic.cpp
100102 jit/JITCall32_64.cpp
106297

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 \
106297

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 \
106297

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 \
106297

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 \
106297

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

17581758 >
17591759 </File>
17601760 <File
 1761 RelativePath="..\..\jit\HostCallReturnValue.cpp"
 1762 >
 1763 </File>
 1764 <File
17611765 RelativePath="..\..\jit\JIT.cpp"
17621766 >
17631767 </File>

18431847 </File>
18441848 </Filter>
18451849 <Filter
 1850 Name="llint"
 1851 >
 1852 <File
 1853 RelativePath="..\..\llint\LLIntData.h"
 1854 >
 1855 </File>
 1856 </Filter>
 1857 <Filter
18461858 Name="interpreter"
18471859 >
18481860 <File
106297

Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops

66 >
77 <Tool
88 Name="VCCLCompilerTool"
9  AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../parser/;../../bytecompiler/;../../dfg/;../../jit/;../../runtime/;../../tools/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../heap/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
 9 AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../parser/;../../bytecompiler/;../../dfg/;../../jit/;../../llint/;../../runtime/;../../tools/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../heap/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
1010 PreprocessorDefinitions="__STD_C"
1111 ForcedIncludeFiles="ICUVersion.h"
1212 />
106297

Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd

@@for %%d in (
4343 debugger
4444 interpreter
4545 jit
 46 llint
4647 parser
4748 profiler
4849 runtime
106297

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 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; };
75108 0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; };
76109 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };

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

754787/* End PBXBuildFile section */
755788
756789/* Begin PBXContainerItemProxy section */
 790 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */ = {
 791 isa = PBXContainerItemProxy;
 792 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 793 proxyType = 1;
 794 remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
 795 remoteInfo = "LLInt Offsets";
 796 };
 797 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */ = {
 798 isa = PBXContainerItemProxy;
 799 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 800 proxyType = 1;
 801 remoteGlobalIDString = 0F46808E14BA7E5E00BFE272;
 802 remoteInfo = JSCLLIntOffsetsExtractor;
 803 };
757804 141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
758805 isa = PBXContainerItemProxy;
759806 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;

799846/* End PBXContainerItemProxy section */
800847
801848/* Begin PBXCopyFilesBuildPhase section */
 849 0F46808D14BA7E5E00BFE272 /* CopyFiles */ = {
 850 isa = PBXCopyFilesBuildPhase;
 851 buildActionMask = 2147483647;
 852 dstPath = /usr/share/man/man1/;
 853 dstSubfolderSpec = 0;
 854 files = (
 855 );
 856 runOnlyForDeploymentPostprocessing = 1;
 857 };
802858 5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
803859 isa = PBXCopyFilesBuildPhase;
804860 buildActionMask = 12;

839895 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
840896 0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
841897 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
 898 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
 899 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
 900 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
 901 0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
842902 0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
843903 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
844904 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };

849909 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
850910 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
851911 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
 912 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
852913 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
853914 0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
854915 0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
 916 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
 917 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
 918 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
855919 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
856920 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
857921 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };

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

15871665/* End PBXFileReference section */
15881666
15891667/* Begin PBXFrameworksBuildPhase section */
 1668 0F46808C14BA7E5E00BFE272 /* Frameworks */ = {
 1669 isa = PBXFrameworksBuildPhase;
 1670 buildActionMask = 2147483647;
 1671 files = (
 1672 );
 1673 runOnlyForDeploymentPostprocessing = 0;
 1674 };
15901675 1412111E0A48793C00480255 /* Frameworks */ = {
15911676 isa = PBXFrameworksBuildPhase;
15921677 buildActionMask = 2147483647;

16451730 141211200A48793C00480255 /* minidom */,
16461731 14BD59BF0A3E8F9000BAF59C /* testapi */,
16471732 6511230514046A4C002B101D /* testRegExp */,
 1733 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
16481734 );
16491735 name = Products;
16501736 sourceTree = "<group>";

16751761 F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
16761762 45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
16771763 F68EBB8C0255D4C601FF60F7 /* config.h */,
 1764 0F46809C14BA7F4D00BFE272 /* llint */,
16781765 1432EBD70A34CAD400717B9F /* API */,
16791766 9688CB120ED12B4E001D649F /* assembler */,
16801767 969A078F0ED1D3AE00F1F681 /* bytecode */,

17141801 tabWidth = 4;
17151802 usesTabs = 0;
17161803 };
 1804 0F46809C14BA7F4D00BFE272 /* llint */ = {
 1805 isa = PBXGroup;
 1806 children = (
 1807 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
 1808 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
 1809 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
 1810 0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
 1811 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
 1812 0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
 1813 0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
 1814 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
 1815 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
 1816 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
 1817 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
 1818 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
 1819 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */,
 1820 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */,
 1821 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
 1822 );
 1823 name = llint;
 1824 sourceTree = "<group>";
 1825 };
17171826 141211000A48772600480255 /* tests */ = {
17181827 isa = PBXGroup;
17191828 children = (

17481857 1429D92C0ED22D7000B89619 /* jit */ = {
17491858 isa = PBXGroup;
17501859 children = (
 1860 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
 1861 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
17511862 0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
17521863 0F46808014BA572700BFE272 /* JITExceptions.h */,
17531864 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,

21752286 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
21762287 isa = PBXGroup;
21772288 children = (
 2289 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
 2290 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
21782291 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
21792292 BCF605110E203EF800B9A64D /* ArgList.cpp */,
21802293 BCF605120E203EF800B9A64D /* ArgList.h */,

25472660 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
25482661 isa = PBXGroup;
25492662 children = (
 2663 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
 2664 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
25502665 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
25512666 0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
25522667 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,

30973212 86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
30983213 86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
30993214 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
 3215 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
 3216 0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */,
31003217 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
 3218 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
 3219 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
 3220 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
 3221 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
 3222 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
 3223 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
 3224 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
31013225 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
31023226 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
31033227 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,

31063230 0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
31073231 0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
31083232 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
 3233 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
31093234 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
 3235 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
 3236 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
 3237 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
31103238 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
31113239 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
31123240 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,

31253253/* End PBXHeadersBuildPhase section */
31263254
31273255/* Begin PBXNativeTarget section */
 3256 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {
 3257 isa = PBXNativeTarget;
 3258 buildConfigurationList = 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */;
 3259 buildPhases = (
 3260 0F46808B14BA7E5E00BFE272 /* Sources */,
 3261 0F46808C14BA7E5E00BFE272 /* Frameworks */,
 3262 0F46808D14BA7E5E00BFE272 /* CopyFiles */,
 3263 );
 3264 buildRules = (
 3265 );
 3266 dependencies = (
 3267 0F4680B214BA811500BFE272 /* PBXTargetDependency */,
 3268 );
 3269 name = JSCLLIntOffsetsExtractor;
 3270 productName = JSCLLIntOffsetsExtractor;
 3271 productReference = 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3272 productType = "com.apple.product-type.tool";
 3273 };
31283274 1412111F0A48793C00480255 /* minidom */ = {
31293275 isa = PBXNativeTarget;
31303276 buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;

32513397 14BD59BE0A3E8F9000BAF59C /* testapi */,
32523398 932F5BDA0822A1C700736975 /* jsc */,
32533399 651122F714046A4C002B101D /* testRegExp */,
 3400 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
 3401 0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
32543402 );
32553403 };
32563404/* End PBXProject section */
32573405
32583406/* Begin PBXShellScriptBuildPhase section */
 3407 0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */ = {
 3408 isa = PBXShellScriptBuildPhase;
 3409 buildActionMask = 2147483647;
 3410 files = (
 3411 );
 3412 inputPaths = (
 3413 "$(SRCROOT)/llint/LowLevelAssembler.asm",
 3414 );
 3415 name = "Generate Derived Sources";
 3416 outputPaths = (
 3417 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
 3418 );
 3419 runOnlyForDeploymentPostprocessing = 0;
 3420 shellPath = /bin/sh;
 3421 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";
 3422 };
32593423 3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
32603424 isa = PBXShellScriptBuildPhase;
32613425 buildActionMask = 2147483647;

33613525 );
33623526 runOnlyForDeploymentPostprocessing = 0;
33633527 shellPath = /bin/sh;
3364  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";
 3528 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";
33653529 };
33663530 9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
33673531 isa = PBXShellScriptBuildPhase;

33963560/* End PBXShellScriptBuildPhase section */
33973561
33983562/* Begin PBXSourcesBuildPhase section */
 3563 0F46808B14BA7E5E00BFE272 /* Sources */ = {
 3564 isa = PBXSourcesBuildPhase;
 3565 buildActionMask = 2147483647;
 3566 files = (
 3567 0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */,
 3568 );
 3569 runOnlyForDeploymentPostprocessing = 0;
 3570 };
33993571 1412111D0A48793C00480255 /* Sources */ = {
34003572 isa = PBXSourcesBuildPhase;
34013573 buildActionMask = 2147483647;

36533825 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
36543826 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
36553827 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
 3828 0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */,
 3829 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
36563830 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
 3831 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
 3832 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
 3833 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
 3834 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
 3835 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
36573836 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
36583837 0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
36593838 F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,

36783857/* End PBXSourcesBuildPhase section */
36793858
36803859/* Begin PBXTargetDependency section */
 3860 0F4680B214BA811500BFE272 /* PBXTargetDependency */ = {
 3861 isa = PBXTargetDependency;
 3862 target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
 3863 targetProxy = 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */;
 3864 };
 3865 0F4680B414BA821400BFE272 /* PBXTargetDependency */ = {
 3866 isa = PBXTargetDependency;
 3867 target = 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3868 targetProxy = 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */;
 3869 };
36813870 141214BF0A49190E00480255 /* PBXTargetDependency */ = {
36823871 isa = PBXTargetDependency;
36833872 target = 1412111F0A48793C00480255 /* minidom */;

37113900/* End PBXTargetDependency section */
37123901
37133902/* Begin XCBuildConfiguration section */
 3903 0F46809614BA7E5E00BFE272 /* Debug */ = {
 3904 isa = XCBuildConfiguration;
 3905 buildSettings = {
 3906 ALWAYS_SEARCH_USER_PATHS = NO;
 3907 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3908 COPY_PHASE_STRIP = NO;
 3909 GCC_C_LANGUAGE_STANDARD = gnu99;
 3910 GCC_DYNAMIC_NO_PIC = NO;
 3911 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3912 GCC_OPTIMIZATION_LEVEL = 0;
 3913 GCC_PREPROCESSOR_DEFINITIONS = (
 3914 "DEBUG=1",
 3915 "$(inherited)",
 3916 );
 3917 GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 3918 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3919 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3920 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3921 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3922 GCC_WARN_UNUSED_VARIABLE = YES;
 3923 "HEADER_SEARCH_PATHS[arch=*]" = (
 3924 .,
 3925 icu,
 3926 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3927 "$(HEADER_SEARCH_PATHS)",
 3928 );
 3929 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3930 ONLY_ACTIVE_ARCH = NO;
 3931 PRODUCT_NAME = "$(TARGET_NAME)";
 3932 SDKROOT = macosx;
 3933 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3934 };
 3935 name = Debug;
 3936 };
 3937 0F46809714BA7E5E00BFE272 /* Release */ = {
 3938 isa = XCBuildConfiguration;
 3939 buildSettings = {
 3940 ALWAYS_SEARCH_USER_PATHS = NO;
 3941 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3942 COPY_PHASE_STRIP = YES;
 3943 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3944 GCC_C_LANGUAGE_STANDARD = gnu99;
 3945 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3946 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3947 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3948 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3949 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3950 GCC_WARN_UNUSED_VARIABLE = YES;
 3951 "HEADER_SEARCH_PATHS[arch=*]" = (
 3952 .,
 3953 icu,
 3954 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets$(HEADER_SEARCH_PATHS)",
 3955 );
 3956 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3957 ONLY_ACTIVE_ARCH = NO;
 3958 PRODUCT_NAME = "$(TARGET_NAME)";
 3959 SDKROOT = macosx;
 3960 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3961 };
 3962 name = Release;
 3963 };
 3964 0F46809814BA7E5E00BFE272 /* Profiling */ = {
 3965 isa = XCBuildConfiguration;
 3966 buildSettings = {
 3967 ALWAYS_SEARCH_USER_PATHS = NO;
 3968 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3969 COPY_PHASE_STRIP = YES;
 3970 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3971 GCC_C_LANGUAGE_STANDARD = gnu99;
 3972 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3973 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3974 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3975 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3976 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3977 GCC_WARN_UNUSED_VARIABLE = YES;
 3978 "HEADER_SEARCH_PATHS[arch=*]" = (
 3979 .,
 3980 icu,
 3981 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3982 "$(HEADER_SEARCH_PATHS)",
 3983 );
 3984 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3985 ONLY_ACTIVE_ARCH = NO;
 3986 PRODUCT_NAME = "$(TARGET_NAME)";
 3987 SDKROOT = macosx;
 3988 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3989 };
 3990 name = Profiling;
 3991 };
 3992 0F46809914BA7E5E00BFE272 /* Production */ = {
 3993 isa = XCBuildConfiguration;
 3994 buildSettings = {
 3995 ALWAYS_SEARCH_USER_PATHS = NO;
 3996 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3997 COPY_PHASE_STRIP = YES;
 3998 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3999 GCC_C_LANGUAGE_STANDARD = gnu99;
 4000 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 4001 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 4002 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 4003 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 4004 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 4005 GCC_WARN_UNUSED_VARIABLE = YES;
 4006 "HEADER_SEARCH_PATHS[arch=*]" = (
 4007 .,
 4008 icu,
 4009 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 4010 "$(HEADER_SEARCH_PATHS)",
 4011 );
 4012 MACOSX_DEPLOYMENT_TARGET = 10.7;
 4013 PRODUCT_NAME = "$(TARGET_NAME)";
 4014 SDKROOT = macosx;
 4015 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 4016 };
 4017 name = Production;
 4018 };
 4019 0F4680AD14BA7FD900BFE272 /* Debug */ = {
 4020 isa = XCBuildConfiguration;
 4021 buildSettings = {
 4022 PRODUCT_NAME = "Derived Sources copy";
 4023 };
 4024 name = Debug;
 4025 };
 4026 0F4680AE14BA7FD900BFE272 /* Release */ = {
 4027 isa = XCBuildConfiguration;
 4028 buildSettings = {
 4029 PRODUCT_NAME = "Derived Sources copy";
 4030 };
 4031 name = Release;
 4032 };
 4033 0F4680AF14BA7FD900BFE272 /* Profiling */ = {
 4034 isa = XCBuildConfiguration;
 4035 buildSettings = {
 4036 PRODUCT_NAME = "Derived Sources copy";
 4037 };
 4038 name = Profiling;
 4039 };
 4040 0F4680B014BA7FD900BFE272 /* Production */ = {
 4041 isa = XCBuildConfiguration;
 4042 buildSettings = {
 4043 PRODUCT_NAME = "Derived Sources copy";
 4044 };
 4045 name = Production;
 4046 };
37144047 1412113A0A48798400480255 /* Debug */ = {
37154048 isa = XCBuildConfiguration;
37164049 buildSettings = {

39524285/* End XCBuildConfiguration section */
39534286
39544287/* Begin XCConfigurationList section */
 4288 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */ = {
 4289 isa = XCConfigurationList;
 4290 buildConfigurations = (
 4291 0F46809614BA7E5E00BFE272 /* Debug */,
 4292 0F46809714BA7E5E00BFE272 /* Release */,
 4293 0F46809814BA7E5E00BFE272 /* Profiling */,
 4294 0F46809914BA7E5E00BFE272 /* Production */,
 4295 );
 4296 defaultConfigurationIsVisible = 0;
 4297 defaultConfigurationName = Production;
 4298 };
 4299 0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */ = {
 4300 isa = XCConfigurationList;
 4301 buildConfigurations = (
 4302 0F4680AD14BA7FD900BFE272 /* Debug */,
 4303 0F4680AE14BA7FD900BFE272 /* Release */,
 4304 0F4680AF14BA7FD900BFE272 /* Profiling */,
 4305 0F4680B014BA7FD900BFE272 /* Production */,
 4306 );
 4307 defaultConfigurationIsVisible = 0;
 4308 defaultConfigurationName = Production;
 4309 };
39554310 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
39564311 isa = XCConfigurationList;
39574312 buildConfigurations = (
106297

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 {
106297

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
106297

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};
106297

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
12851292 }
12861293}
12871294
1288 #endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
1289 
12901295#if DUMP_CODE_BLOCK_STATISTICS
12911296static HashSet<CodeBlock*> liveCodeBlockSet;
12921297#endif

@@CodeBlock::CodeBlock(CopyParsedBlockTag,
14561461{
14571462 setNumParameters(other.numParameters());
14581463 optimizeAfterWarmUp();
 1464 jitAfterWarmUp();
14591465
14601466 if (other.m_rareData) {
14611467 createRareDataIfNecessary();

@@CodeBlock::CodeBlock(ScriptExecutable* o
15041510 ASSERT(m_source);
15051511
15061512 optimizeAfterWarmUp();
 1513 jitAfterWarmUp();
15071514
15081515#if DUMP_CODE_BLOCK_STATISTICS
15091516 liveCodeBlockSet.add(this);

@@CodeBlock::~CodeBlock()
15211528#if ENABLE(VERBOSE_VALUE_PROFILE)
15221529 dumpValueProfiles();
15231530#endif
1524 
 1531
 1532#if ENABLE(LLINT)
 1533 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 1534 m_incomingLLIntCalls.begin()->remove();
 1535#endif // ENABLE(LLINT)
15251536#if ENABLE(JIT)
15261537 // We may be destroyed before any CodeBlocks that refer to us are destroyed.
15271538 // Consider that two CodeBlocks become unreachable at the same time. There

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

@@void CodeBlock::stronglyVisitStrongRefer
18551926 for (size_t i = 0; i < m_functionDecls.size(); ++i)
18561927 visitor.append(&m_functionDecls[i]);
18571928#if ENABLE(INTERPRETER)
1858  for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1859  visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1860  for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1861  visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1929 if (m_globalData->interpreter->enabled()) {
 1930 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
 1931 visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
 1932 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
 1933 visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1934 }
18621935#endif
18631936
18641937#if ENABLE(DFG_JIT)

@@void CodeBlock::stronglyVisitStrongRefer
18661939 // Make sure that executables that we have inlined don't die.
18671940 // FIXME: If they would have otherwise died, we should probably trigger recompilation.
18681941 for (size_t i = 0; i < inlineCallFrames().size(); ++i) {
1869  visitor.append(&inlineCallFrames()[i].executable);
1870  visitor.append(&inlineCallFrames()[i].callee);
 1942 InlineCallFrame& inlineCallFrame = inlineCallFrames()[i];
 1943 visitor.append(&inlineCallFrame.executable);
 1944 visitor.append(&inlineCallFrame.callee);
18711945 }
18721946 }
18731947#endif

@@void CodeBlock::unlinkCalls()
20672141{
20682142 if (!!m_alternative)
20692143 m_alternative->unlinkCalls();
 2144#if ENABLE(LLINT)
 2145 for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
 2146 if (m_llintCallLinkInfos[i].isLinked())
 2147 m_llintCallLinkInfos[i].unlink();
 2148 }
 2149#endif
20702150 if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
20712151 return;
20722152 if (!m_globalData->canUseJIT())

@@void CodeBlock::unlinkCalls()
20812161
20822162void CodeBlock::unlinkIncomingCalls()
20832163{
 2164#if ENABLE(LLINT)
 2165 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 2166 m_incomingLLIntCalls.begin()->unlink();
 2167#endif
 2168 if (m_incomingCalls.isEmpty())
 2169 return;
20842170 RepatchBuffer repatchBuffer(this);
20852171 while (m_incomingCalls.begin() != m_incomingCalls.end())
20862172 m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
20872173}
 2174
 2175unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
 2176{
 2177#if ENABLE(LLINT)
 2178 if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
 2179 && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
 2180 ASSERT(exec->codeBlock());
 2181 ASSERT(exec->codeBlock() == this);
 2182 ASSERT(JITCode::isBaselineCode(getJITType()));
 2183 Instruction* instruction = exec->currentVPC();
 2184 ASSERT(instruction);
 2185 return bytecodeOffset(instruction);
 2186 }
 2187#else
 2188 UNUSED_PARAM(exec);
 2189#endif
 2190 if (!m_rareData)
 2191 return 1;
 2192 Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
 2193 if (!callIndices.size())
 2194 return 1;
 2195 return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
 2196}
20882197#endif
20892198
20902199void CodeBlock::clearEvalCache()

@@bool FunctionCodeBlock::canCompileWithDF
21802289
21812290void ProgramCodeBlock::jettison()
21822291{
2183  ASSERT(getJITType() != JITCode::BaselineJIT);
 2292 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21842293 ASSERT(this == replacement());
21852294 static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21862295}
21872296
21882297void EvalCodeBlock::jettison()
21892298{
2190  ASSERT(getJITType() != JITCode::BaselineJIT);
 2299 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21912300 ASSERT(this == replacement());
21922301 static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21932302}
21942303
21952304void FunctionCodeBlock::jettison()
21962305{
2197  ASSERT(getJITType() != JITCode::BaselineJIT);
 2306 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21982307 ASSERT(this == replacement());
21992308 static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
22002309}
 2310
 2311void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2312{
 2313 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2314 ASSERT(this == replacement());
 2315 return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData);
 2316}
 2317
 2318void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2319{
 2320 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2321 ASSERT(this == replacement());
 2322 return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData);
 2323}
 2324
 2325void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData)
 2326{
 2327 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2328 ASSERT(this == replacement());
 2329 return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall);
 2330}
22012331#endif
22022332
22032333#if ENABLE(VALUE_PROFILER)

@@void CodeBlock::dumpValueProfiles()
23002430}
23012431#endif
23022432
 2433void CodeBlock::handleBytecodeDiscardingOpportunity()
 2434{
 2435#if !ENABLE(OPCODE_SAMPLING) && !ENABLE(LLINT)
 2436 if (BytecodeGenerator::dumpsGeneratedCode())
 2437 return;
 2438 if (!!alternative())
 2439 discardBytecode();
 2440 else
 2441 discardBytecodeLater();
 2442#endif
 2443}
 2444
23032445#ifndef NDEBUG
23042446bool CodeBlock::usesOpcode(OpcodeID opcodeID)
23052447{
106297

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
392388 enum CompileWithDFGState {

@@namespace JSC {
406402
407403 bool hasOptimizedReplacement()
408404 {
409  ASSERT(getJITType() == JITCode::BaselineJIT);
 405 ASSERT(JITCode::isBaselineCode(getJITType()));
410406 bool result = replacement()->getJITType() > getJITType();
411407#if !ASSERT_DISABLED
412408 if (result)
413409 ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
414410 else {
415  ASSERT(replacement()->getJITType() == JITCode::BaselineJIT);
 411 ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
416412 ASSERT(replacement() == this);
417413 }
418414#endif

@@namespace JSC {
471467
472468 void clearEvalCache();
473469
474 #if ENABLE(INTERPRETER)
475470 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
476471 {
477  if (!m_globalData->canUseJIT())
478  m_propertyAccessInstructions.append(propertyAccessInstruction);
 472 m_propertyAccessInstructions.append(propertyAccessInstruction);
479473 }
480474 void addGlobalResolveInstruction(unsigned globalResolveInstruction)
481475 {
482  if (!m_globalData->canUseJIT())
483  m_globalResolveInstructions.append(globalResolveInstruction);
 476 m_globalResolveInstructions.append(globalResolveInstruction);
484477 }
485478 bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
 479#if ENABLE(LLINT)
 480 LLIntCallLinkInfo* addLLIntCallLinkInfo()
 481 {
 482 m_llintCallLinkInfos.append(LLIntCallLinkInfo());
 483 return &m_llintCallLinkInfos.last();
 484 }
486485#endif
487486#if ENABLE(JIT)
488487 void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }

@@namespace JSC {
491490
492491 void addGlobalResolveInfo(unsigned globalResolveInstruction)
493492 {
494  if (m_globalData->canUseJIT())
495  m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
 493 m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
496494 }
497495 GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
498496 bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);

@@namespace JSC {
503501
504502 void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); }
505503 MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
 504 size_t numberOfMethodCallLinkInfos() { return m_methodCallLinkInfos.size(); }
506505#endif
507506
508507#if ENABLE(VALUE_PROFILER)

@@namespace JSC {
543542 bytecodeOffset].u.opcode)) - 1].u.profile == result);
544543 return result;
545544 }
 545 PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
 546 {
 547 return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
 548 }
546549
547550 unsigned totalNumberOfValueProfiles()
548551 {

@@namespace JSC {
569572
570573 bool likelyToTakeSlowCase(int bytecodeOffset)
571574 {
 575 if (!numberOfRareCaseProfiles())
 576 return false;
572577 unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
573578 return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
574579 }
575580
576581 bool couldTakeSlowCase(int bytecodeOffset)
577582 {
 583 if (!numberOfRareCaseProfiles())
 584 return false;
578585 unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
579586 return value >= Options::couldTakeSlowCaseMinimumCount && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold;
580587 }

@@namespace JSC {
593600
594601 bool likelyToTakeSpecialFastCase(int bytecodeOffset)
595602 {
 603 if (!numberOfRareCaseProfiles())
 604 return false;
596605 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
597606 return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold;
598607 }
599608
600609 bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
601610 {
 611 if (!numberOfRareCaseProfiles())
 612 return false;
602613 unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
603614 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
604615 unsigned value = slowCaseCount - specialFastCaseCount;

@@namespace JSC {
607618
608619 bool likelyToTakeAnySlowCase(int bytecodeOffset)
609620 {
 621 if (!numberOfRareCaseProfiles())
 622 return false;
610623 unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
611624 unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
612625 unsigned value = slowCaseCount + specialFastCaseCount;

@@namespace JSC {
704717
705718 bool addFrequentExitSite(const DFG::FrequentExitSite& site)
706719 {
707  ASSERT(getJITType() == JITCode::BaselineJIT);
 720 ASSERT(JITCode::isBaselineCode(getJITType()));
708721 return m_exitProfile.add(site);
709722 }
710723

@@namespace JSC {
809822 void copyPostParseDataFrom(CodeBlock* alternative);
810823 void copyPostParseDataFromAlternative();
811824
 825 // Functions for controlling when JITting kicks in, in a mixed mode
 826 // execution world.
 827
 828 void dontJITAnytimeSoon()
 829 {
 830 m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
 831 }
 832
 833 void jitAfterWarmUp()
 834 {
 835 m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
 836 }
 837
 838 void jitSoon()
 839 {
 840 m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
 841 }
 842
 843 int32_t llintExecuteCounter() const
 844 {
 845 return m_llintExecuteCounter;
 846 }
 847
812848 // Functions for controlling when tiered compilation kicks in. This
813849 // controls both when the optimizing compiler is invoked and when OSR
814850 // entry happens. Two triggers exist: the loop trigger and the return

@@namespace JSC {
10011037 bool m_shouldDiscardBytecode;
10021038
10031039 protected:
 1040 virtual void jitCompileImpl(JSGlobalData&) = 0;
10041041 virtual void visitWeakReferences(SlotVisitor&);
10051042 virtual void finalizeUnconditionally();
10061043

@@namespace JSC {
10131050 void tallyFrequentExitSites() { }
10141051#endif
10151052
1016 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
10171053 void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
10181054
10191055 CString registerName(ExecState*, int r) const;

@@namespace JSC {
10231059 void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
10241060 void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
10251061 void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
1026 #endif
10271062 void visitStructures(SlotVisitor&, Instruction* vPC) const;
10281063
10291064#if ENABLE(DFG_JIT)

@@namespace JSC {
10841119 RefPtr<SourceProvider> m_source;
10851120 unsigned m_sourceOffset;
10861121
1087 #if ENABLE(INTERPRETER)
10881122 Vector<unsigned> m_propertyAccessInstructions;
10891123 Vector<unsigned> m_globalResolveInstructions;
 1124#if ENABLE(LLINT)
 1125 SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
 1126 SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
10901127#endif
10911128#if ENABLE(JIT)
10921129 Vector<StructureStubInfo> m_structureStubInfos;

@@namespace JSC {
10971134 MacroAssemblerCodePtr m_jitCodeWithArityCheck;
10981135 SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
10991136#endif
1100 #if ENABLE(DFG_JIT)
 1137#if ENABLE(DFG_JIT) || ENABLE(LLINT)
11011138 OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1102 
 1139#endif
 1140#if ENABLE(DFG_JIT)
11031141 struct WeakReferenceTransition {
11041142 WeakReferenceTransition() { }
11051143

@@namespace JSC {
11621200
11631201 OwnPtr<CodeBlock> m_alternative;
11641202
 1203 int32_t m_llintExecuteCounter;
 1204
11651205 int32_t m_jitExecuteCounter;
11661206 uint32_t m_speculativeSuccessCounter;
11671207 uint32_t m_speculativeFailCounter;
11681208 uint8_t m_optimizationDelayCounter;
11691209 uint8_t m_reoptimizationRetryCounter;
1170 
 1210
11711211 struct RareData {
11721212 WTF_MAKE_FAST_ALLOCATED;
11731213 public:

@@namespace JSC {
12431283 protected:
12441284 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12451285 virtual void jettison();
 1286 virtual void jitCompileImpl(JSGlobalData&);
12461287 virtual CodeBlock* replacement();
12471288 virtual bool canCompileWithDFGInternal();
12481289#endif

@@namespace JSC {
12771318 protected:
12781319 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12791320 virtual void jettison();
 1321 virtual void jitCompileImpl(JSGlobalData&);
12801322 virtual CodeBlock* replacement();
12811323 virtual bool canCompileWithDFGInternal();
12821324#endif

@@namespace JSC {
13141356 protected:
13151357 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
13161358 virtual void jettison();
 1359 virtual void jitCompileImpl(JSGlobalData&);
13171360 virtual CodeBlock* replacement();
13181361 virtual bool canCompileWithDFGInternal();
13191362#endif
106297

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
106297

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
106297

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:
106297

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)
106297

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 {
201203 typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
202204 #undef OPCODE_ID_ENUM
203205
 206 const int maxOpcodeLength = 9;
204207 const int numOpcodeIDs = op_end + 1;
205208
206209 #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;

@@namespace JSC {
217220 FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
218221 #undef VERIFY_OPCODE_ID
219222
220 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 223#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
221224#if COMPILER(RVCT) || COMPILER(INTEL)
222225 typedef void* Opcode;
223226#else
106297

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(
106297

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;
106297

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(
18391816 instructions().append(func->index()); // func
18401817 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
18411818 instructions().append(callArguments.registerOffset()); // registerOffset
 1819#if ENABLE(LLINT)
 1820 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1821#else
18421822 instructions().append(0);
 1823#endif
18431824 instructions().append(0);
18441825 if (dst != ignoredResult()) {
18451826 ValueProfile* profile = emitProfiledOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitConst
19431924 instructions().append(func->index()); // func
19441925 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
19451926 instructions().append(callArguments.registerOffset()); // registerOffset
 1927#if ENABLE(LLINT)
 1928 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1929#else
19461930 instructions().append(0);
 1931#endif
19471932 instructions().append(0);
19481933 if (dst != ignoredResult()) {
19491934 ValueProfile* profile = emitProfiledOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitCatch
22042189{
22052190 m_usesExceptions = true;
22062191#if ENABLE(JIT)
 2192#if ENABLE(LLINT)
 2193 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(bitwise_cast<void*>(&llint_op_catch)) };
 2194#else
22072195 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
 2196#endif
22082197#else
22092198 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
22102199#endif
106297

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];
106297

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:
106297

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);
106297

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
673674 return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
674675}
675676
676 EncodedJSValue DFG_OPERATION getHostCallReturnValue();
677 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
678 
679 #if CPU(X86_64)
680 asm (
681 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
682 HIDE_SYMBOL(getHostCallReturnValue) "\n"
683 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
684  "mov -40(%r13), %r13\n"
685  "mov %r13, %rdi\n"
686  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
687 );
688 #elif CPU(X86)
689 asm (
690 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
691 HIDE_SYMBOL(getHostCallReturnValue) "\n"
692 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
693  "mov -40(%edi), %edi\n"
694  "mov %edi, 4(%esp)\n"
695  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
696 );
697 #elif CPU(ARM_THUMB2)
698 asm (
699 ".text" "\n"
700 ".align 2" "\n"
701 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
702 HIDE_SYMBOL(getHostCallReturnValue) "\n"
703 ".thumb" "\n"
704 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
705 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
706  "ldr r5, [r5, #-40]" "\n"
707  "cpy r0, r5" "\n"
708  "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
709 );
710 #endif
711 
712 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
713 {
714  JSGlobalData* globalData = &exec->globalData();
715  NativeCallFrameTracer tracer(globalData, exec);
716 
717  return JSValue::encode(exec->globalData().hostCallReturnValue);
718 }
719 
720677static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
721678{
722679 ExecState* exec = execCallee->callerFrame();
106297

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
106297

Source/JavaScriptCore/heap/Heap.h

@@namespace JSC {
4949 class JSGlobalData;
5050 class JSValue;
5151 class LiveObjectIterator;
 52 class LLIntOffsetsExtractor;
5253 class MarkedArgumentBuffer;
5354 class RegisterFile;
5455 class UString;

@@namespace JSC {
135136 void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
136137
137138 private:
 139 friend class CodeBlock;
 140 friend class LLIntOffsetsExtractor;
138141 friend class MarkedSpace;
139142 friend class MarkedBlock;
140143 friend class BumpSpace;
141144 friend class SlotVisitor;
142  friend class CodeBlock;
143145
144146 size_t waterMark();
145147 size_t highWaterMark();
106297

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;
106297

Source/JavaScriptCore/heap/MarkedSpace.h

@@namespace JSC {
4040class Heap;
4141class JSCell;
4242class LiveObjectIterator;
 43class LLIntOffsetsExtractor;
4344class WeakGCHandle;
4445class SlotVisitor;
4546

@@public:
8788 void freeBlocks(MarkedBlock* head);
8889
8990private:
 91 friend class LLIntOffsetsExtractor;
 92
9093 void* allocateSlowCase(SizeClass&);
9194 void* tryAllocateHelper(MarkedSpace::SizeClass&);
9295 void* tryAllocate(MarkedSpace::SizeClass&);
106297

Source/JavaScriptCore/interpreter/CallFrame.h

@@namespace JSC {
122122#if ENABLE(INTERPRETER)
123123 Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
124124#endif
 125#if ENABLE(LLINT)
 126 Instruction* currentVPC() const { return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag()); }
 127#endif
125128
126129 void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
127130 void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
106297

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

@@skip_id_custom_self:
33253352#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
33263353 skip_put_by_id:
33273354#endif
 3355 DEFINE_OPCODE(op_put_by_id_transition_direct)
 3356 DEFINE_OPCODE(op_put_by_id_transition_normal)
33283357 DEFINE_OPCODE(op_put_by_id_transition) {
33293358 /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
33303359

@@void Interpreter::retrieveLastCaller(Cal
51575186 bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
51585187#if ENABLE(JIT)
51595188 else
5160  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5189 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51615190#endif
51625191#else
5163  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5192 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51645193#endif
51655194 lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
51665195 sourceID = callerCodeBlock->ownerExecutable()->sourceID();
106297

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 {
100102
101103 class Interpreter {
102104 WTF_MAKE_FAST_ALLOCATED;
103  friend class JIT;
104105 friend class CachedCall;
 106 friend class LLIntOffsetsExtractor;
 107 friend class JIT;
105108 public:
106109 Interpreter();
 110 ~Interpreter();
107111
108  void initialize(bool canUseJIT);
 112 void initialize(LLInt::Data*, bool canUseJIT);
109113
110114 RegisterFile& registerFile() { return m_registerFile; }
111115
112116 Opcode getOpcode(OpcodeID id)
113117 {
114118 ASSERT(m_initialized);
115 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 119#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
116120 return m_opcodeTable[id];
117121#else
118122 return id;

@@namespace JSC {
122126 OpcodeID getOpcodeID(Opcode opcode)
123127 {
124128 ASSERT(m_initialized);
125 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 129#if ENABLE(LLINT)
 130 ASSERT(isOpcode(opcode));
 131 return m_opcodeIDTable.get(opcode);
 132#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
126133 ASSERT(isOpcode(opcode));
127134 if (!m_enabled)
128135 return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode));

@@namespace JSC {
132139 return opcode;
133140#endif
134141 }
 142
 143 bool enabled()
 144 {
 145 return m_enabled;
 146 }
135147
136148 bool isOpcode(Opcode);
137149

@@namespace JSC {
199211
200212 RegisterFile m_registerFile;
201213
202 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 214#if ENABLE(LLINT)
 215 Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
 216 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
 217#elif ENABLE(COMPUTED_GOTO_INTERPRETER)
203218 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
204219 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
205220#endif
106297

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);
106297

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#if COMPILER(GCC)
 30
 31#include "CallFrame.h"
 32#include "InlineASM.h"
 33#include "JSObject.h"
 34#include "JSValueInlineMethods.h"
 35#include "ScopeChain.h"
 36
 37namespace JSC {
 38
 39extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*);
 40
 41#if CPU(X86_64)
 42asm (
 43".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 44HIDE_SYMBOL(getHostCallReturnValue) "\n"
 45SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 46 "mov -40(%r13), %r13\n"
 47 "mov %r13, %rdi\n"
 48 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 49);
 50#elif CPU(X86)
 51asm (
 52".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 53HIDE_SYMBOL(getHostCallReturnValue) "\n"
 54SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 55 "mov -40(%edi), %edi\n"
 56 "mov %edi, 4(%esp)\n"
 57 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 58);
 59#elif CPU(ARM_THUMB2)
 60asm (
 61".text" "\n"
 62".align 2" "\n"
 63".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
 64HIDE_SYMBOL(getHostCallReturnValue) "\n"
 65".thumb" "\n"
 66".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
 67SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
 68 "ldr r5, [r5, #-40]" "\n"
 69 "cpy r0, r5" "\n"
 70 "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 71);
 72#endif
 73
 74extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
 75{
 76 return JSValue::encode(exec->globalData().hostCallReturnValue);
 77}
 78
 79} // namespace JSC
 80
 81#endif // COMPILER(GCC)
 82
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// Unfortunately this only works on GCC-like compilers. And it's currently only used
 34// by LLInt and DFG, which also are restricted to GCC-like compilers. We should
 35// probably fix that at some point.
 36#if COMPILER(GCC)
 37
 38#if CALLING_CONVENTION_IS_STDCALL
 39#define HOST_CALL_RETURN_VALUE_OPTION CDECL
 40#else
 41#define HOST_CALL_RETURN_VALUE_OPTION
 42#endif
 43
 44namespace JSC {
 45extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue();
 46}
 47
 48#endif // COMPILER(GCC)
 49
 50#endif // HostCallReturnValue_h
 51
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()
486488 DEFINE_SLOWCASE_OP(op_post_inc)
487489 DEFINE_SLOWCASE_OP(op_pre_dec)
488490 DEFINE_SLOWCASE_OP(op_pre_inc)
 491 case op_put_by_id_transition_direct:
 492 case op_put_by_id_transition_normal:
489493 DEFINE_SLOWCASE_OP(op_put_by_id)
490494 DEFINE_SLOWCASE_OP(op_put_by_val)
491495 DEFINE_SLOWCASE_OP(op_resolve_global)

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

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

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
106297

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;
106297

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}
106297

Source/JavaScriptCore/jit/JITStubs.cpp

@@DEFINE_STUB_FUNCTION(void, op_put_by_id_
14461446 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
14471447 JSValue baseValue = stackFrame.args[0].jsValue();
14481448 ASSERT(baseValue.isObject());
 1449
14491450 asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
14501451
14511452 CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();

@@DEFINE_STUB_FUNCTION(void, optimize_from
19311932 unsigned bytecodeIndex = stackFrame.args[0].int32();
19321933
19331934#if ENABLE(JIT_VERBOSE_OSR)
1934  printf("Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
 1935 printf("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
19351936#endif
19361937
19371938 if (codeBlock->hasOptimizedReplacement()) {

@@DEFINE_STUB_FUNCTION(void*, op_construct
21862187 return result;
21872188}
21882189
2189 inline CallFrame* arityCheckFor(CallFrame* callFrame, RegisterFile* registerFile, CodeSpecializationKind kind)
2190 {
2191  JSFunction* callee = asFunction(callFrame->callee());
2192  ASSERT(!callee->isHostFunction());
2193  CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
2194  int argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
2195 
2196  // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
2197  if (!registerFile->grow(callFrame->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
2198  return 0;
2199 
2200  ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
2201 
2202  // Too few arguments -- copy call frame and arguments, then fill in missing arguments with undefined.
2203  size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
2204  Register* src = callFrame->registers();
2205  Register* dst = callFrame->registers() + delta;
2206 
2207  int i;
2208  int end = -CallFrame::offsetFor(argumentCountIncludingThis);
2209  for (i = -1; i >= end; --i)
2210  dst[i] = src[i];
2211 
2212  end -= delta;
2213  for ( ; i >= end; --i)
2214  dst[i] = jsUndefined();
2215 
2216  CallFrame* newCallFrame = CallFrame::create(dst);
2217  ASSERT((void*)newCallFrame <= registerFile->end());
2218  return newCallFrame;
2219 }
2220 
22212190DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
22222191{
22232192 STUB_INIT_STACK_FRAME(stackFrame);
22242193
22252194 CallFrame* callFrame = stackFrame.callFrame;
22262195
2227  CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
 2196 CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
22282197 if (!newCallFrame)
22292198 return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
22302199

@@DEFINE_STUB_FUNCTION(void*, op_construct
22372206
22382207 CallFrame* callFrame = stackFrame.callFrame;
22392208
2240  CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
 2209 CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
22412210 if (!newCallFrame)
22422211 return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
22432212
106297

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"
106297

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 "GetterSetter.h"
 35#include "HostCallReturnValue.h"
 36#include "Interpreter.h"
 37#include "JIT.h"
 38#include "JITDriver.h"
 39#include "JSActivation.h"
 40#include "JSByteArray.h"
 41#include "JSGlobalObjectFunctions.h"
 42#include "JSPropertyNameIterator.h"
 43#include "JSStaticScopeObject.h"
 44#include "JSString.h"
 45#include "JSValue.h"
 46#include "LLIntCommon.h"
 47#include "LLIntExceptions.h"
 48#include "LowLevelInterpreter.h"
 49#include "Operations.h"
 50
 51namespace JSC { namespace LLInt {
 52
 53#define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
 54#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
 55
 56#define LLINT_RETURN_TWO(first, second) do { \
 57 union { \
 58 struct { \
 59 void* a; \
 60 void* b; \
 61 } pair; \
 62 int64_t i; \
 63 } __rt_u; \
 64 __rt_u.pair.a = first; \
 65 __rt_u.pair.b = second; \
 66 return __rt_u.i; \
 67 } while (false)
 68
 69#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
 70
 71#define LLINT_THROW(exceptionToThrow) do { \
 72 JSGlobalData& __t_globalData = exec->globalData(); \
 73 __t_globalData.exception = (exceptionToThrow); \
 74 pc = returnToThrow(exec, pc); \
 75 LLINT_END_IMPL(); \
 76 } while (false)
 77
 78#define LLINT_CHECK_EXCEPTION() do { \
 79 if (UNLIKELY(exec->globalData().exception)) { \
 80 pc = returnToThrow(exec, pc); \
 81 LLINT_END_IMPL(); \
 82 } \
 83 } while (false)
 84
 85#define LLINT_END() do { \
 86 LLINT_CHECK_EXCEPTION(); \
 87 LLINT_END_IMPL(); \
 88 } while (false)
 89
 90#define LLINT_BRANCH(opcode, condition) do { \
 91 bool __b_condition = (condition); \
 92 LLINT_CHECK_EXCEPTION(); \
 93 if (__b_condition) \
 94 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
 95 else \
 96 pc += OPCODE_LENGTH(opcode); \
 97 LLINT_END_IMPL(); \
 98 } while (false)
 99
 100#define LLINT_RETURN(value) do { \
 101 JSValue __r_returnValue = (value); \
 102 LLINT_CHECK_EXCEPTION(); \
 103 LLINT_OP(1) = __r_returnValue; \
 104 LLINT_END_IMPL(); \
 105 } while (false)
 106
 107#define LLINT_RETURN_PROFILED(opcode, value) do { \
 108 JSValue __rp_returnValue = (value); \
 109 LLINT_CHECK_EXCEPTION(); \
 110 LLINT_OP(1) = __rp_returnValue; \
 111 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
 112 JSValue::encode(__rp_returnValue); \
 113 LLINT_END_IMPL(); \
 114 } while (false)
 115
 116#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
 117
 118#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
 119 ExecState* __ct_exec = (exec); \
 120 Instruction* __ct_pc = (pc); \
 121 JSGlobalData& __ct_globalData = (__ct_exec)->globalData(); \
 122 __ct_globalData.exception = (exceptionToThrow); \
 123 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
 124 } while (false)
 125
 126#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
 127 ExecState* __cce_exec = (exec); \
 128 Instruction* __cce_pc = (pc); \
 129 if (UNLIKELY(__cce_exec->globalData().exception)) \
 130 LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
 131 } while (false)
 132
 133#define LLINT_CALL_RETURN(exec, pc, callTarget) do { \
 134 ExecState* __cr_exec = (exec); \
 135 Instruction* __cr_pc = (pc); \
 136 void* __cr_callTarget = (callTarget); \
 137 LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc); \
 138 LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget); \
 139 } while (false)
 140
 141extern "C" HelperReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 142{
 143 printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
 144 exec->codeBlock(),
 145 exec,
 146 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 147 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 148 fromWhere,
 149 operand,
 150 pc[operand].u.operand);
 151 LLINT_END();
 152}
 153
 154extern "C" HelperReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 155{
 156 JSValue value = LLINT_OP_C(operand).jsValue();
 157 union {
 158 struct {
 159 uint32_t tag;
 160 uint32_t payload;
 161 } bits;
 162 EncodedJSValue asValue;
 163 } u;
 164 u.asValue = JSValue::encode(value);
 165 printf("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x",
 166 exec->codeBlock(),
 167 exec,
 168 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 169 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 170 fromWhere,
 171 operand,
 172 pc[operand].u.operand,
 173 u.bits.tag,
 174 u.bits.payload);
 175#ifndef NDEBUG
 176 printf(": %s", value.description());
 177#endif
 178 printf("\n");
 179 LLINT_END();
 180}
 181
 182LLINT_HELPER_DECL(trace_prologue)
 183{
 184 printf("%p / %p: in prologue.\n", exec->codeBlock(), exec);
 185 LLINT_END();
 186}
 187
 188static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
 189{
 190 JSFunction* callee = asFunction(exec->callee());
 191 FunctionExecutable* executable = callee->jsExecutable();
 192 CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
 193 printf("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u.\n",
 194 codeBlock, exec, comment, callee, executable,
 195 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters);
 196}
 197
 198LLINT_HELPER_DECL(trace_prologue_function_for_call)
 199{
 200 traceFunctionPrologue(exec, "call prologue", CodeForCall);
 201 LLINT_END();
 202}
 203
 204LLINT_HELPER_DECL(trace_prologue_function_for_construct)
 205{
 206 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
 207 LLINT_END();
 208}
 209
 210LLINT_HELPER_DECL(trace_arityCheck_for_call)
 211{
 212 traceFunctionPrologue(exec, "call arity check", CodeForCall);
 213 LLINT_END();
 214}
 215
 216LLINT_HELPER_DECL(trace_arityCheck_for_construct)
 217{
 218 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
 219 LLINT_END();
 220}
 221
 222LLINT_HELPER_DECL(trace)
 223{
 224 printf("%p / %p: executing bc#%zu, ",
 225 exec->codeBlock(),
 226 exec,
 227 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()));
 228#ifndef NDEBUG
 229 printf("%s, ", opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)]);
 230#else
 231 printf("op#%u, ", exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode));
 232#endif
 233 printf("scope %p\n", exec->scopeChain());
 234 LLINT_END();
 235}
 236
 237LLINT_HELPER_DECL(special_trace)
 238{
 239 printf("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
 240 exec->codeBlock(),
 241 exec,
 242 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
 243 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
 244 exec->returnPC().value());
 245 LLINT_END();
 246}
 247
 248inline bool shouldJIT(ExecState* exec)
 249{
 250 // You can modify this to turn off JITting without rebuilding the world.
 251 return exec->globalData().canUseJIT();
 252}
 253
 254enum EntryKind { Prologue, ArityCheck };
 255static HelperReturnType entryOSR(ExecState* exec, Instruction* pc, CodeBlock* codeBlock, const char *name, EntryKind kind)
 256{
 257#if ENABLE(JIT_VERBOSE_OSR)
 258 printf("%p: Entered %s with executeCounter = %d\n", codeBlock, name, codeBlock->llintExecuteCounter());
 259#endif
 260
 261 if (!shouldJIT(exec)) {
 262 codeBlock->dontJITAnytimeSoon();
 263 LLINT_RETURN_TWO(0, exec);
 264 }
 265 if (!codeBlock->jitCompile(exec->globalData())) {
 266#if ENABLE(JIT_VERBOSE_OSR)
 267 printf(" Code was already compiled.\n");
 268#endif
 269 }
 270 codeBlock->jitSoon();
 271 if (kind == Prologue)
 272 LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
 273 ASSERT(kind == ArityCheck);
 274 LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
 275}
 276
 277LLINT_HELPER_DECL(entry_osr)
 278{
 279 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
 280}
 281
 282LLINT_HELPER_DECL(entry_osr_function_for_call)
 283{
 284 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
 285}
 286
 287LLINT_HELPER_DECL(entry_osr_function_for_construct)
 288{
 289 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
 290}
 291
 292LLINT_HELPER_DECL(entry_osr_function_for_call_arityCheck)
 293{
 294 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
 295}
 296
 297LLINT_HELPER_DECL(entry_osr_function_for_construct_arityCheck)
 298{
 299 return entryOSR(exec, pc, &asFunction(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
 300}
 301
 302LLINT_HELPER_DECL(loop_osr)
 303{
 304 CodeBlock* codeBlock = exec->codeBlock();
 305
 306#if ENABLE(JIT_VERBOSE_OSR)
 307 printf("%p: Entered loop_osr with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
 308#endif
 309
 310 if (!shouldJIT(exec)) {
 311 codeBlock->dontJITAnytimeSoon();
 312 LLINT_RETURN_TWO(0, exec);
 313 }
 314
 315 if (!codeBlock->jitCompile(exec->globalData())) {
 316#if ENABLE(JIT_VERBOSE_OSR)
 317 printf(" Code was already compiled.\n");
 318#endif
 319 }
 320 codeBlock->jitSoon();
 321
 322 ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
 323
 324 Vector<BytecodeAndMachineOffset> map;
 325 codeBlock->jitCodeMap()->decode(map);
 326 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
 327 ASSERT(mapping);
 328 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
 329
 330 void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
 331 ASSERT(jumpTarget);
 332
 333 LLINT_RETURN_TWO(jumpTarget, exec);
 334}
 335
 336LLINT_HELPER_DECL(replace)
 337{
 338 CodeBlock* codeBlock = exec->codeBlock();
 339
 340#if ENABLE(JIT_VERBOSE_OSR)
 341 printf("%p: Entered replace with executeCounter = %d\n", codeBlock, codeBlock->llintExecuteCounter());
 342#endif
 343
 344 if (shouldJIT(exec)) {
 345 if (!codeBlock->jitCompile(exec->globalData())) {
 346#if ENABLE(JIT_VERBOSE_OSR)
 347 printf(" Code was already compiled.\n");
 348#endif
 349 }
 350 codeBlock->jitSoon();
 351 } else
 352 codeBlock->dontJITAnytimeSoon();
 353 LLINT_END();
 354}
 355
 356LLINT_HELPER_DECL(register_file_check)
 357{
 358#if LLINT_HELPER_TRACING
 359 printf("Checking stack height with exec = %p.\n", exec);
 360 printf("CodeBlock = %p.\n", exec->codeBlock());
 361 printf("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
 362 printf("Num vars = %u.\n", exec->codeBlock()->m_numVars);
 363 printf("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end());
 364#endif
 365 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end());
 366 if (UNLIKELY(!exec->globalData().interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
 367 exec = exec->callerFrame();
 368 exec->globalData().exception = createStackOverflowError(exec);
 369 interpreterThrowInCaller(exec);
 370 pc = returnToThrowForThrownException(exec);
 371 }
 372 LLINT_END_IMPL();
 373}
 374
 375LLINT_HELPER_DECL(helper_call_arityCheck)
 376{
 377 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForCall);
 378 if (!newExec) {
 379 exec = exec->callerFrame();
 380 exec->globalData().exception = createStackOverflowError(exec);
 381 interpreterThrowInCaller(exec);
 382 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
 383 }
 384 LLINT_RETURN_TWO(0, newExec);
 385}
 386
 387LLINT_HELPER_DECL(helper_construct_arityCheck)
 388{
 389 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &exec->globalData().interpreter->registerFile(), CodeForConstruct);
 390 if (!newExec) {
 391 exec = exec->callerFrame();
 392 exec->globalData().exception = createStackOverflowError(exec);
 393 interpreterThrowInCaller(exec);
 394 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
 395 }
 396 LLINT_RETURN_TWO(0, newExec);
 397}
 398
 399LLINT_HELPER_DECL(helper_create_activation)
 400{
 401#if LLINT_HELPER_TRACING
 402 printf("Creating an activation, exec = %p!\n", exec);
 403#endif
 404 JSActivation* activation = JSActivation::create(exec->globalData(), exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
 405 exec->setScopeChain(exec->scopeChain()->push(activation));
 406 LLINT_RETURN(JSValue(activation));
 407}
 408
 409LLINT_HELPER_DECL(helper_create_arguments)
 410{
 411 JSValue arguments = JSValue(Arguments::create(exec->globalData(), exec));
 412 LLINT_CHECK_EXCEPTION();
 413 exec->uncheckedR(pc[1].u.operand) = arguments;
 414 exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
 415 LLINT_END();
 416}
 417
 418LLINT_HELPER_DECL(helper_create_this)
 419{
 420 JSFunction* constructor = asFunction(exec->callee());
 421
 422#if !ASSERT_DISABLED
 423 ConstructData constructData;
 424 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
 425#endif
 426
 427 Structure* structure;
 428 JSValue proto = LLINT_OP(2).jsValue();
 429 if (proto.isObject())
 430 structure = asObject(proto)->inheritorID(exec->globalData());
 431 else
 432 structure = constructor->scope()->globalObject->emptyObjectStructure();
 433
 434 LLINT_RETURN(constructEmptyObject(exec, structure));
 435}
 436
 437LLINT_HELPER_DECL(helper_convert_this)
 438{
 439 JSValue v1 = LLINT_OP(1).jsValue();
 440 ASSERT(v1.isPrimitive());
 441 LLINT_RETURN(v1.toThisObject(exec));
 442}
 443
 444LLINT_HELPER_DECL(helper_new_object)
 445{
 446 LLINT_RETURN(constructEmptyObject(exec));
 447}
 448
 449LLINT_HELPER_DECL(helper_new_array)
 450{
 451 LLINT_RETURN(constructArray(exec, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
 452}
 453
 454LLINT_HELPER_DECL(helper_new_array_buffer)
 455{
 456 LLINT_RETURN(constructArray(exec, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
 457}
 458
 459LLINT_HELPER_DECL(helper_new_regexp)
 460{
 461 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
 462 if (!regExp->isValid())
 463 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
 464 LLINT_RETURN(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
 465}
 466
 467LLINT_HELPER_DECL(helper_not)
 468{
 469 LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
 470}
 471
 472LLINT_HELPER_DECL(helper_eq)
 473{
 474 LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 475}
 476
 477LLINT_HELPER_DECL(helper_neq)
 478{
 479 LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 480}
 481
 482LLINT_HELPER_DECL(helper_stricteq)
 483{
 484 LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 485}
 486
 487LLINT_HELPER_DECL(helper_nstricteq)
 488{
 489 LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 490}
 491
 492LLINT_HELPER_DECL(helper_less)
 493{
 494 LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 495}
 496
 497LLINT_HELPER_DECL(helper_lesseq)
 498{
 499 LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 500}
 501
 502LLINT_HELPER_DECL(helper_greater)
 503{
 504 LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
 505}
 506
 507LLINT_HELPER_DECL(helper_greatereq)
 508{
 509 LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
 510}
 511
 512LLINT_HELPER_DECL(helper_pre_inc)
 513{
 514 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
 515}
 516
 517LLINT_HELPER_DECL(helper_pre_dec)
 518{
 519 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
 520}
 521
 522LLINT_HELPER_DECL(helper_post_inc)
 523{
 524 double result = LLINT_OP(2).jsValue().toNumber(exec);
 525 LLINT_OP(2) = jsNumber(result + 1);
 526 LLINT_RETURN(jsNumber(result));
 527}
 528
 529LLINT_HELPER_DECL(helper_post_dec)
 530{
 531 double result = LLINT_OP(2).jsValue().toNumber(exec);
 532 LLINT_OP(2) = jsNumber(result - 1);
 533 LLINT_RETURN(jsNumber(result));
 534}
 535
 536LLINT_HELPER_DECL(helper_to_jsnumber)
 537{
 538 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
 539}
 540
 541LLINT_HELPER_DECL(helper_negate)
 542{
 543 LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
 544}
 545
 546LLINT_HELPER_DECL(helper_add)
 547{
 548 JSValue v1 = LLINT_OP_C(2).jsValue();
 549 JSValue v2 = LLINT_OP_C(3).jsValue();
 550
 551#if LLINT_HELPER_TRACING
 552 printf("Trying to add %s", v1.description());
 553 printf(" to %s.\n", v2.description());
 554#endif
 555
 556 if (v1.isString() && !v2.isObject())
 557 LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
 558
 559 if (v1.isNumber() && v2.isNumber())
 560 LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
 561
 562 LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
 563}
 564
 565LLINT_HELPER_DECL(helper_mul)
 566{
 567 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) * LLINT_OP_C(3).jsValue().toNumber(exec)));
 568}
 569
 570LLINT_HELPER_DECL(helper_sub)
 571{
 572 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) - LLINT_OP_C(3).jsValue().toNumber(exec)));
 573}
 574
 575LLINT_HELPER_DECL(helper_div)
 576{
 577 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec) / LLINT_OP_C(3).jsValue().toNumber(exec)));
 578}
 579
 580LLINT_HELPER_DECL(helper_mod)
 581{
 582 LLINT_RETURN(jsNumber(fmod(LLINT_OP_C(2).jsValue().toNumber(exec), LLINT_OP_C(3).jsValue().toNumber(exec))));
 583}
 584
 585LLINT_HELPER_DECL(helper_lshift)
 586{
 587 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) << LLINT_OP_C(3).jsValue().toUInt32(exec)));
 588}
 589
 590LLINT_HELPER_DECL(helper_rshift)
 591{
 592 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
 593}
 594
 595LLINT_HELPER_DECL(helper_urshift)
 596{
 597 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toUInt32(exec) >> LLINT_OP_C(3).jsValue().toUInt32(exec)));
 598}
 599
 600LLINT_HELPER_DECL(helper_bitand)
 601{
 602 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) & LLINT_OP_C(3).jsValue().toInt32(exec)));
 603}
 604
 605LLINT_HELPER_DECL(helper_bitor)
 606{
 607 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) | LLINT_OP_C(3).jsValue().toInt32(exec)));
 608}
 609
 610LLINT_HELPER_DECL(helper_bitxor)
 611{
 612 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
 613}
 614
 615LLINT_HELPER_DECL(helper_bitnot)
 616{
 617 LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
 618}
 619
 620LLINT_HELPER_DECL(helper_check_has_instance)
 621{
 622 JSValue baseVal = LLINT_OP_C(1).jsValue();
 623#ifndef NDEBUG
 624 TypeInfo typeInfo(UnspecifiedType);
 625 ASSERT(!baseVal.isObject()
 626 || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
 627#endif
 628 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
 629}
 630
 631LLINT_HELPER_DECL(helper_instanceof)
 632{
 633 LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue())));
 634}
 635
 636LLINT_HELPER_DECL(helper_typeof)
 637{
 638 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
 639}
 640
 641LLINT_HELPER_DECL(helper_is_undefined)
 642{
 643 JSValue v = LLINT_OP_C(2).jsValue();
 644 LLINT_RETURN(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
 645}
 646
 647LLINT_HELPER_DECL(helper_is_boolean)
 648{
 649 LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isBoolean()));
 650}
 651
 652LLINT_HELPER_DECL(helper_is_number)
 653{
 654 LLINT_RETURN(jsBoolean(LLINT_OP_C(2).jsValue().isNumber()));
 655}
 656
 657LLINT_HELPER_DECL(helper_is_string)
 658{
 659 LLINT_RETURN(jsBoolean(isJSString(LLINT_OP_C(2).jsValue())));
 660}
 661
 662LLINT_HELPER_DECL(helper_is_object)
 663{
 664 LLINT_RETURN(jsBoolean(jsIsObjectType(LLINT_OP_C(2).jsValue())));
 665}
 666
 667LLINT_HELPER_DECL(helper_is_function)
 668{
 669 LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
 670}
 671
 672LLINT_HELPER_DECL(helper_in)
 673{
 674 LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
 675}
 676
 677LLINT_HELPER_DECL(helper_resolve)
 678{
 679 LLINT_RETURN_PROFILED(op_resolve, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
 680}
 681
 682LLINT_HELPER_DECL(helper_resolve_skip)
 683{
 684 LLINT_RETURN_PROFILED(
 685 op_resolve_skip,
 686 CommonSlowPaths::opResolveSkip(
 687 exec,
 688 exec->codeBlock()->identifier(pc[2].u.operand),
 689 pc[3].u.operand));
 690}
 691
 692static JSValue resolveGlobal(ExecState* exec, Instruction* pc)
 693{
 694 CodeBlock* codeBlock = exec->codeBlock();
 695 JSGlobalObject* globalObject = codeBlock->globalObject();
 696 ASSERT(globalObject->isGlobalObject());
 697 int property = pc[2].u.operand;
 698 Structure* structure = pc[3].u.structure.get();
 699
 700 ASSERT_UNUSED(structure, structure != globalObject->structure());
 701
 702 Identifier& ident = codeBlock->identifier(property);
 703 PropertySlot slot(globalObject);
 704
 705 if (globalObject->getPropertySlot(exec, ident, slot)) {
 706 JSValue result = slot.getValue(exec, ident);
 707 if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary()
 708 && slot.slotBase() == globalObject) {
 709 pc[3].u.structure.set(
 710 exec->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
 711 pc[4] = slot.cachedOffset();
 712 }
 713
 714 return result;
 715 }
 716
 717 exec->globalData().exception = createUndefinedVariableError(exec, ident);
 718 return JSValue();
 719}
 720
 721LLINT_HELPER_DECL(helper_resolve_global)
 722{
 723 LLINT_RETURN_PROFILED(op_resolve_global, resolveGlobal(exec, pc));
 724}
 725
 726LLINT_HELPER_DECL(helper_resolve_global_dynamic)
 727{
 728 LLINT_RETURN_PROFILED(op_resolve_global_dynamic, resolveGlobal(exec, pc));
 729}
 730
 731LLINT_HELPER_DECL(helper_resolve_for_resolve_global_dynamic)
 732{
 733 LLINT_RETURN_PROFILED(op_resolve_global_dynamic, CommonSlowPaths::opResolve(exec, exec->codeBlock()->identifier(pc[2].u.operand)));
 734}
 735
 736LLINT_HELPER_DECL(helper_resolve_base)
 737{
 738 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 739 if (pc[3].u.operand) {
 740 JSValue base = JSC::resolveBase(exec, ident, exec->scopeChain(), true);
 741 if (!base)
 742 LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
 743 LLINT_RETURN(base);
 744 }
 745
 746 LLINT_RETURN_PROFILED(op_resolve_base, JSC::resolveBase(exec, ident, exec->scopeChain(), false));
 747}
 748
 749LLINT_HELPER_DECL(helper_ensure_property_exists)
 750{
 751 JSObject* object = asObject(LLINT_OP(1).jsValue());
 752 PropertySlot slot(object);
 753 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
 754 if (!object->getPropertySlot(exec, ident, slot))
 755 LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.ustring()));
 756 LLINT_END();
 757}
 758
 759LLINT_HELPER_DECL(helper_resolve_with_base)
 760{
 761 JSValue result = CommonSlowPaths::opResolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
 762 LLINT_CHECK_EXCEPTION();
 763 LLINT_OP(2) = result;
 764 // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
 765 LLINT_END();
 766}
 767
 768LLINT_HELPER_DECL(helper_resolve_with_this)
 769{
 770 JSValue result = CommonSlowPaths::opResolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), LLINT_OP(1));
 771 LLINT_CHECK_EXCEPTION();
 772 LLINT_OP(2) = result;
 773 // FIXME: technically should have profiling, but we don't do it because the DFG won't use it.
 774 LLINT_END();
 775}
 776
 777LLINT_HELPER_DECL(helper_get_by_id)
 778{
 779 CodeBlock* codeBlock = exec->codeBlock();
 780 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
 781 JSValue baseValue = LLINT_OP_C(2).jsValue();
 782 PropertySlot slot(baseValue);
 783
 784 JSValue result = baseValue.get(exec, ident, slot);
 785 LLINT_CHECK_EXCEPTION();
 786 LLINT_OP(1) = result;
 787
 788 if (baseValue.isCell()
 789 && slot.isCacheable()
 790 && slot.slotBase() == baseValue
 791 && slot.cachedPropertyType() == PropertySlot::Value) {
 792
 793 JSCell* baseCell = baseValue.asCell();
 794 Structure* structure = baseCell->structure();
 795
 796 if (!structure->isUncacheableDictionary()
 797 && !structure->typeInfo().prohibitsPropertyCaching()) {
 798 pc[4].u.structure.set(
 799 exec->globalData(), codeBlock->ownerExecutable(), structure);
 800 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 801 }
 802 }
 803
 804 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
 805 LLINT_END();
 806}
 807
 808LLINT_HELPER_DECL(helper_get_arguments_length)
 809{
 810 CodeBlock* codeBlock = exec->codeBlock();
 811 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
 812 JSValue baseValue = LLINT_OP(2).jsValue();
 813 PropertySlot slot(baseValue);
 814 LLINT_RETURN(baseValue.get(exec, ident, slot));
 815}
 816
 817LLINT_HELPER_DECL(helper_put_by_id)
 818{
 819 CodeBlock* codeBlock = exec->codeBlock();
 820 Identifier& ident = codeBlock->identifier(pc[2].u.operand);
 821
 822 JSValue baseValue = LLINT_OP_C(1).jsValue();
 823 PutPropertySlot slot(codeBlock->isStrictMode());
 824 if (pc[8].u.operand)
 825 asObject(baseValue)->putDirect(exec->globalData(), ident, LLINT_OP_C(3).jsValue(), slot);
 826 else
 827 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
 828 LLINT_CHECK_EXCEPTION();
 829
 830 if (baseValue.isCell()
 831 && slot.isCacheable()) {
 832
 833 JSCell* baseCell = baseValue.asCell();
 834 Structure* structure = baseCell->structure();
 835
 836 if (!structure->isUncacheableDictionary()
 837 && !structure->typeInfo().prohibitsPropertyCaching()
 838 && baseCell == slot.base()) {
 839
 840 if (slot.type() == PutPropertySlot::NewProperty) {
 841 if (!structure->isDictionary() && structure->previousID()->propertyStorageCapacity() == structure->propertyStorageCapacity()) {
 842 // This is needed because some of the methods we call
 843 // below may GC.
 844 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
 845
 846 normalizePrototypeChain(exec, baseCell);
 847
 848 ASSERT(structure->previousID()->isObject());
 849 pc[4].u.structure.set(
 850 exec->globalData(), codeBlock->ownerExecutable(), structure->previousID());
 851 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 852 pc[6].u.structure.set(
 853 exec->globalData(), codeBlock->ownerExecutable(), structure);
 854 StructureChain* chain = structure->prototypeChain(exec);
 855 ASSERT(chain);
 856 pc[7].u.structureChain.set(
 857 exec->globalData(), codeBlock->ownerExecutable(), chain);
 858
 859 if (pc[8].u.operand)
 860 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_direct);
 861 else
 862 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id_transition_normal);
 863 }
 864 } else {
 865 pc[0].u.opcode = bitwise_cast<void*>(&llint_op_put_by_id);
 866 pc[4].u.structure.set(
 867 exec->globalData(), codeBlock->ownerExecutable(), structure);
 868 pc[5].u.operand = slot.cachedOffset() * sizeof(JSValue);
 869 }
 870 }
 871 }
 872
 873 if (false && !strcmp(ident.ascii().data(), "renderReflections"))
 874 printf("Finishing access to renderReflections from LLInt slow path.\n");
 875
 876 LLINT_END();
 877}
 878
 879LLINT_HELPER_DECL(helper_del_by_id)
 880{
 881 CodeBlock* codeBlock = exec->codeBlock();
 882 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
 883 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
 884 LLINT_CHECK_EXCEPTION();
 885 if (!couldDelete && codeBlock->isStrictMode())
 886 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
 887 LLINT_RETURN(jsBoolean(couldDelete));
 888}
 889
 890inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
 891{
 892 if (LIKELY(baseValue.isCell() && subscript.isString())) {
 893 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
 894 return result;
 895 }
 896
 897 if (subscript.isUInt32()) {
 898 uint32_t i = subscript.asUInt32();
 899 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
 900 return asString(baseValue)->getIndex(exec, i);
 901
 902 if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
 903 return asByteArray(baseValue)->getIndex(exec, i);
 904
 905 return baseValue.get(exec, i);
 906 }
 907
 908 Identifier property(exec, subscript.toString(exec)->value(exec));
 909 return baseValue.get(exec, property);
 910}
 911
 912LLINT_HELPER_DECL(helper_get_by_val)
 913{
 914 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
 915}
 916
 917LLINT_HELPER_DECL(helper_get_argument_by_val)
 918{
 919 JSValue arguments = LLINT_OP(2).jsValue();
 920 if (!arguments) {
 921 arguments = Arguments::create(exec->globalData(), exec);
 922 LLINT_CHECK_EXCEPTION();
 923 LLINT_OP(2) = arguments;
 924 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
 925 }
 926
 927 LLINT_RETURN(getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
 928}
 929
 930LLINT_HELPER_DECL(helper_get_by_pname)
 931{
 932 LLINT_RETURN(getByVal(exec, LLINT_OP(2).jsValue(), LLINT_OP(3).jsValue()));
 933}
 934
 935LLINT_HELPER_DECL(helper_put_by_val)
 936{
 937 JSGlobalData& globalData = exec->globalData();
 938
 939 JSValue baseValue = LLINT_OP_C(1).jsValue();
 940 JSValue subscript = LLINT_OP_C(2).jsValue();
 941 JSValue value = LLINT_OP_C(3).jsValue();
 942
 943 if (LIKELY(subscript.isUInt32())) {
 944 uint32_t i = subscript.asUInt32();
 945 if (isJSArray(baseValue)) {
 946 JSArray* jsArray = asArray(baseValue);
 947 if (jsArray->canSetIndex(i))
 948 jsArray->setIndex(globalData, i, value);
 949 else
 950 JSArray::putByIndex(jsArray, exec, i, value);
 951 LLINT_END();
 952 }
 953 if (isJSByteArray(baseValue)
 954 && asByteArray(baseValue)->canAccessIndex(i)) {
 955 JSByteArray* jsByteArray = asByteArray(baseValue);
 956 if (value.isInt32()) {
 957 jsByteArray->setIndex(i, value.asInt32());
 958 LLINT_END();
 959 }
 960 if (value.isNumber()) {
 961 jsByteArray->setIndex(i, value.asNumber());
 962 LLINT_END();
 963 }
 964 }
 965 baseValue.put(exec, i, value);
 966 LLINT_END();
 967 }
 968
 969 Identifier property(exec, subscript.toString(exec)->value(exec));
 970 LLINT_CHECK_EXCEPTION();
 971 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
 972 baseValue.put(exec, property, value, slot);
 973 LLINT_END();
 974}
 975
 976LLINT_HELPER_DECL(helper_del_by_val)
 977{
 978 JSValue baseValue = LLINT_OP_C(2).jsValue();
 979 JSObject* baseObject = baseValue.toObject(exec);
 980
 981 JSValue subscript = LLINT_OP_C(3).jsValue();
 982
 983 bool couldDelete;
 984
 985 uint32_t i;
 986 if (subscript.getUInt32(i))
 987 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
 988 else {
 989 LLINT_CHECK_EXCEPTION();
 990 Identifier property(exec, subscript.toString(exec)->value(exec));
 991 LLINT_CHECK_EXCEPTION();
 992 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
 993 }
 994
 995 if (!couldDelete && exec->codeBlock()->isStrictMode())
 996 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
 997
 998 LLINT_RETURN(jsBoolean(couldDelete));
 999}
 1000
 1001LLINT_HELPER_DECL(helper_put_by_index)
 1002{
 1003 LLINT_OP_C(1).jsValue().put(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
 1004 LLINT_END();
 1005}
 1006
 1007LLINT_HELPER_DECL(helper_put_getter_setter)
 1008{
 1009 ASSERT(LLINT_OP(1).jsValue().isObject());
 1010 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
 1011
 1012 GetterSetter* accessor = GetterSetter::create(exec);
 1013 LLINT_CHECK_EXCEPTION();
 1014
 1015 JSValue getter = LLINT_OP(3).jsValue();
 1016 JSValue setter = LLINT_OP(4).jsValue();
 1017 ASSERT(getter.isObject() || getter.isUndefined());
 1018 ASSERT(setter.isObject() || setter.isUndefined());
 1019 ASSERT(getter.isObject() || setter.isObject());
 1020
 1021 if (!getter.isUndefined())
 1022 accessor->setGetter(exec->globalData(), asObject(getter));
 1023 if (!setter.isUndefined())
 1024 accessor->setSetter(exec->globalData(), asObject(setter));
 1025 baseObj->putDirectAccessor(
 1026 exec->globalData(),
 1027 exec->codeBlock()->identifier(pc[2].u.operand),
 1028 accessor, Accessor);
 1029 LLINT_END();
 1030}
 1031
 1032LLINT_HELPER_DECL(helper_jmp_scopes)
 1033{
 1034 unsigned count = pc[1].u.operand;
 1035 ScopeChainNode* tmp = exec->scopeChain();
 1036 while (count--)
 1037 tmp = tmp->pop();
 1038 exec->setScopeChain(tmp);
 1039 pc += pc[2].u.operand;
 1040 LLINT_END();
 1041}
 1042
 1043LLINT_HELPER_DECL(helper_jtrue)
 1044{
 1045 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
 1046}
 1047
 1048LLINT_HELPER_DECL(helper_jfalse)
 1049{
 1050 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
 1051}
 1052
 1053LLINT_HELPER_DECL(helper_jless)
 1054{
 1055 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1056}
 1057
 1058LLINT_HELPER_DECL(helper_jnless)
 1059{
 1060 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1061}
 1062
 1063LLINT_HELPER_DECL(helper_jgreater)
 1064{
 1065 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1066}
 1067
 1068LLINT_HELPER_DECL(helper_jngreater)
 1069{
 1070 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1071}
 1072
 1073LLINT_HELPER_DECL(helper_jlesseq)
 1074{
 1075 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1076}
 1077
 1078LLINT_HELPER_DECL(helper_jnlesseq)
 1079{
 1080 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
 1081}
 1082
 1083LLINT_HELPER_DECL(helper_jgreatereq)
 1084{
 1085 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1086}
 1087
 1088LLINT_HELPER_DECL(helper_jngreatereq)
 1089{
 1090 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
 1091}
 1092
 1093LLINT_HELPER_DECL(helper_switch_imm)
 1094{
 1095 JSValue scrutinee = LLINT_OP_C(3).jsValue();
 1096 ASSERT(scrutinee.isDouble());
 1097 double value = scrutinee.asDouble();
 1098 int32_t intValue = static_cast<int32_t>(value);
 1099 int defaultOffset = pc[2].u.operand;
 1100 if (value == intValue) {
 1101 CodeBlock* codeBlock = exec->codeBlock();
 1102 pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
 1103 } else
 1104 pc += defaultOffset;
 1105 LLINT_END();
 1106}
 1107
 1108LLINT_HELPER_DECL(helper_switch_string)
 1109{
 1110 JSValue scrutinee = LLINT_OP_C(3).jsValue();
 1111 int defaultOffset = pc[2].u.operand;
 1112 if (!scrutinee.isString())
 1113 pc += defaultOffset;
 1114 else {
 1115 CodeBlock* codeBlock = exec->codeBlock();
 1116 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
 1117 }
 1118 LLINT_END();
 1119}
 1120
 1121LLINT_HELPER_DECL(helper_new_func)
 1122{
 1123 CodeBlock* codeBlock = exec->codeBlock();
 1124 ASSERT(codeBlock->codeType() != FunctionCode
 1125 || !codeBlock->needsFullScopeChain()
 1126 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
 1127#if LLINT_HELPER_TRACING
 1128 printf("Creating function!\n");
 1129#endif
 1130 LLINT_RETURN(codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scopeChain()));
 1131}
 1132
 1133LLINT_HELPER_DECL(helper_new_func_exp)
 1134{
 1135 CodeBlock* codeBlock = exec->codeBlock();
 1136 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
 1137 JSFunction* func = function->make(exec, exec->scopeChain());
 1138
 1139 if (!function->name().isNull()) {
 1140 JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(exec, function->name(), func, ReadOnly | DontDelete);
 1141 func->setScope(exec->globalData(), func->scope()->push(functionScopeObject));
 1142 }
 1143
 1144 LLINT_RETURN(func);
 1145}
 1146
 1147static HelperReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
 1148{
 1149 ExecState* exec = execCallee->callerFrame();
 1150 JSGlobalData* globalData = &exec->globalData();
 1151
 1152 execCallee->setScopeChain(exec->scopeChain());
 1153 execCallee->setCodeBlock(0);
 1154
 1155 if (kind == CodeForCall) {
 1156 CallData callData;
 1157 CallType callType = getCallData(callee, callData);
 1158
 1159 ASSERT(callType != CallTypeJS);
 1160
 1161 if (callType == CallTypeHost) {
 1162 globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
 1163
 1164 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1165 }
 1166
 1167#if LLINT_HELPER_TRACING
 1168 printf("Call callee is not a function: %s\n", callee.description());
 1169#endif
 1170
 1171 ASSERT(callType == CallTypeNone);
 1172 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
 1173 }
 1174
 1175 ASSERT(kind == CodeForConstruct);
 1176
 1177 ConstructData constructData;
 1178 ConstructType constructType = getConstructData(callee, constructData);
 1179
 1180 ASSERT(constructType != ConstructTypeJS);
 1181
 1182 if (constructType == ConstructTypeHost) {
 1183 globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
 1184 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1185 }
 1186
 1187#if LLINT_HELPER_TRACING
 1188 printf("Constructor callee is not a function: %s\n", callee.description());
 1189#endif
 1190
 1191 ASSERT(constructType == ConstructTypeNone);
 1192 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
 1193}
 1194
 1195inline HelperReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
 1196{
 1197 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
 1198 if (!calleeAsFunctionCell)
 1199 return handleHostCall(execCallee, pc, calleeAsValue, kind);
 1200
 1201 JSFunction* callee = asFunction(calleeAsFunctionCell);
 1202 execCallee->setScopeChain(callee->scopeUnchecked());
 1203 ExecutableBase* executable = callee->executable();
 1204
 1205 MacroAssemblerCodePtr codePtr;
 1206 CodeBlock* codeBlock = 0;
 1207 if (executable->isHostFunction())
 1208 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
 1209 else {
 1210 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
 1211 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
 1212 if (error)
 1213 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
 1214 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
 1215 ASSERT(codeBlock);
 1216 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
 1217 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
 1218 else
 1219 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
 1220 }
 1221
 1222 if (callLinkInfo) {
 1223 if (callLinkInfo->isOnList())
 1224 callLinkInfo->remove();
 1225 ExecState* execCaller = execCallee->callerFrame();
 1226 callLinkInfo->callee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
 1227 callLinkInfo->lastSeenCallee.set(execCaller->globalData(), execCaller->codeBlock()->ownerExecutable(), callee);
 1228 callLinkInfo->machineCodeTarget = codePtr;
 1229 if (codeBlock)
 1230 codeBlock->linkIncomingCall(callLinkInfo);
 1231 }
 1232
 1233 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
 1234}
 1235
 1236inline HelperReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
 1237{
 1238 // This needs to:
 1239 // - Set up a call frame.
 1240 // - Figure out what to call and compile it if necessary.
 1241 // - If possible, link the call's inline cache.
 1242 // - Return a tuple of machine code address to call and the new call frame.
 1243
 1244 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
 1245
 1246 ExecState* execCallee = exec + pc[3].u.operand;
 1247
 1248 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
 1249 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1250 execCallee->setCallerFrame(exec);
 1251
 1252 ASSERT(pc[4].u.callLinkInfo);
 1253 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
 1254}
 1255
 1256LLINT_HELPER_DECL(helper_call)
 1257{
 1258 return genericCall(exec, pc, CodeForCall);
 1259}
 1260
 1261LLINT_HELPER_DECL(helper_construct)
 1262{
 1263 return genericCall(exec, pc, CodeForConstruct);
 1264}
 1265
 1266LLINT_HELPER_DECL(helper_call_varargs)
 1267{
 1268 // This needs to:
 1269 // - Set up a call frame while respecting the variable arguments.
 1270 // - Figure out what to call and compile it if necessary.
 1271 // - Return a tuple of machine code address to call and the new call frame.
 1272
 1273 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
 1274
 1275 ExecState* execCallee = loadVarargs(
 1276 exec, &exec->globalData().interpreter->registerFile(),
 1277 LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
 1278 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
 1279
 1280 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1281 execCallee->setCallerFrame(exec);
 1282 exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_varargs));
 1283
 1284 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
 1285}
 1286
 1287LLINT_HELPER_DECL(helper_call_eval)
 1288{
 1289 JSValue calleeAsValue = LLINT_OP(1).jsValue();
 1290
 1291 ExecState* execCallee = exec + pc[3].u.operand;
 1292 JSGlobalData& globalData = exec->globalData();
 1293
 1294 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
 1295 execCallee->setCallerFrame(exec);
 1296 execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue;
 1297 execCallee->setScopeChain(exec->scopeChain());
 1298 execCallee->setReturnPC(bitwise_cast<Instruction*>(&llint_generic_return_point));
 1299 execCallee->setCodeBlock(0);
 1300 exec->uncheckedR(RegisterFile::ArgumentCount).tag() = bitwise_cast<int32_t>(pc + OPCODE_LENGTH(op_call_eval));
 1301
 1302 if (!isHostFunction(calleeAsValue, globalFuncEval))
 1303 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
 1304
 1305 globalData.hostCallReturnValue = eval(execCallee);
 1306 LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast<void*>(getHostCallReturnValue));
 1307}
 1308
 1309LLINT_HELPER_DECL(helper_tear_off_activation)
 1310{
 1311 ASSERT(exec->codeBlock()->needsFullScopeChain());
 1312 JSValue activationValue = LLINT_OP(1).jsValue();
 1313 if (!activationValue) {
 1314 if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue()) {
 1315 if (!exec->codeBlock()->isStrictMode())
 1316 asArguments(v)->tearOff(exec);
 1317 }
 1318 LLINT_END();
 1319 }
 1320 JSActivation* activation = asActivation(activationValue);
 1321 activation->tearOff(exec->globalData());
 1322 if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)).jsValue())
 1323 asArguments(v)->didTearOffActivation(exec->globalData(), activation);
 1324 LLINT_END();
 1325}
 1326
 1327LLINT_HELPER_DECL(helper_tear_off_arguments)
 1328{
 1329 ASSERT(exec->codeBlock()->usesArguments() && !exec->codeBlock()->needsFullScopeChain());
 1330 asArguments(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue())->tearOff(exec);
 1331 LLINT_END();
 1332}
 1333
 1334LLINT_HELPER_DECL(helper_strcat)
 1335{
 1336 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
 1337}
 1338
 1339LLINT_HELPER_DECL(helper_to_primitive)
 1340{
 1341 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
 1342}
 1343
 1344LLINT_HELPER_DECL(helper_get_pnames)
 1345{
 1346 JSValue v = LLINT_OP(2).jsValue();
 1347 if (v.isUndefinedOrNull()) {
 1348 pc += pc[5].u.operand;
 1349 LLINT_END();
 1350 }
 1351
 1352 JSObject* o = v.toObject(exec);
 1353 Structure* structure = o->structure();
 1354 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
 1355 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
 1356 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
 1357
 1358 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
 1359 LLINT_OP(2) = JSValue(o);
 1360 LLINT_OP(3) = Register::withInt(0);
 1361 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
 1362
 1363 pc += OPCODE_LENGTH(op_get_pnames);
 1364 LLINT_END();
 1365}
 1366
 1367LLINT_HELPER_DECL(helper_next_pname)
 1368{
 1369 JSObject* base = asObject(LLINT_OP(2).jsValue());
 1370 JSString* property = asString(LLINT_OP(1).jsValue());
 1371 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
 1372 // Go to target.
 1373 pc += pc[6].u.operand;
 1374 } // Else, don't change the PC, so the interpreter will reloop.
 1375 LLINT_END();
 1376}
 1377
 1378LLINT_HELPER_DECL(helper_push_scope)
 1379{
 1380 JSValue v = LLINT_OP(1).jsValue();
 1381 JSObject* o = v.toObject(exec);
 1382 LLINT_CHECK_EXCEPTION();
 1383
 1384 LLINT_OP(1) = o;
 1385 exec->setScopeChain(exec->scopeChain()->push(o));
 1386
 1387 LLINT_END();
 1388}
 1389
 1390LLINT_HELPER_DECL(helper_pop_scope)
 1391{
 1392 exec->setScopeChain(exec->scopeChain()->pop());
 1393 LLINT_END();
 1394}
 1395
 1396LLINT_HELPER_DECL(helper_push_new_scope)
 1397{
 1398 CodeBlock* codeBlock = exec->codeBlock();
 1399 JSObject* scope = JSStaticScopeObject::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), DontDelete);
 1400 exec->setScopeChain(exec->scopeChain()->push(scope));
 1401 LLINT_RETURN(scope);
 1402}
 1403
 1404LLINT_HELPER_DECL(helper_throw)
 1405{
 1406 LLINT_THROW(LLINT_OP_C(1).jsValue());
 1407}
 1408
 1409LLINT_HELPER_DECL(helper_throw_reference_error)
 1410{
 1411 LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
 1412}
 1413
 1414LLINT_HELPER_DECL(helper_debug)
 1415{
 1416 int debugHookID = pc[1].u.operand;
 1417 int firstLine = pc[2].u.operand;
 1418 int lastLine = pc[3].u.operand;
 1419
 1420 exec->globalData().interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
 1421
 1422 LLINT_END();
 1423}
 1424
 1425LLINT_HELPER_DECL(helper_profile_will_call)
 1426{
 1427 (*Profiler::enabledProfilerReference())->willExecute(exec, LLINT_OP(1).jsValue());
 1428 LLINT_END();
 1429}
 1430
 1431LLINT_HELPER_DECL(helper_profile_did_call)
 1432{
 1433 (*Profiler::enabledProfilerReference())->didExecute(exec, LLINT_OP(1).jsValue());
 1434 LLINT_END();
 1435}
 1436
 1437} } // namespace JSC::LLInt
 1438
 1439#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_setter);
 131LLINT_HELPER_DECL(helper_jmp_scopes);
 132LLINT_HELPER_DECL(helper_jtrue);
 133LLINT_HELPER_DECL(helper_jfalse);
 134LLINT_HELPER_DECL(helper_jless);
 135LLINT_HELPER_DECL(helper_jnless);
 136LLINT_HELPER_DECL(helper_jgreater);
 137LLINT_HELPER_DECL(helper_jngreater);
 138LLINT_HELPER_DECL(helper_jlesseq);
 139LLINT_HELPER_DECL(helper_jnlesseq);
 140LLINT_HELPER_DECL(helper_jgreatereq);
 141LLINT_HELPER_DECL(helper_jngreatereq);
 142LLINT_HELPER_DECL(helper_switch_imm);
 143LLINT_HELPER_DECL(helper_switch_char);
 144LLINT_HELPER_DECL(helper_switch_string);
 145LLINT_HELPER_DECL(helper_new_func);
 146LLINT_HELPER_DECL(helper_new_func_exp);
 147LLINT_HELPER_DECL(helper_call);
 148LLINT_HELPER_DECL(helper_construct);
 149LLINT_HELPER_DECL(helper_call_varargs);
 150LLINT_HELPER_DECL(helper_call_eval);
 151LLINT_HELPER_DECL(helper_tear_off_activation);
 152LLINT_HELPER_DECL(helper_tear_off_arguments);
 153LLINT_HELPER_DECL(helper_strcat);
 154LLINT_HELPER_DECL(helper_to_primitive);
 155LLINT_HELPER_DECL(helper_get_pnames);
 156LLINT_HELPER_DECL(helper_next_pname);
 157LLINT_HELPER_DECL(helper_push_scope);
 158LLINT_HELPER_DECL(helper_pop_scope);
 159LLINT_HELPER_DECL(helper_push_new_scope);
 160LLINT_HELPER_DECL(helper_throw);
 161LLINT_HELPER_DECL(helper_throw_reference_error);
 162LLINT_HELPER_DECL(helper_debug);
 163LLINT_HELPER_DECL(helper_profile_will_call);
 164LLINT_HELPER_DECL(helper_profile_did_call);
 165
 166} } // namespace JSC::LLInt
 167
 168#endif // ENABLE(LLINT)
 169
 170#endif // LLIntHelpers_h
 171
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(ARM_THUMB2)
 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 "CodeBlock.h"
 29#include "Executable.h"
 30#include "Heap.h"
 31#include "Interpreter.h"
 32#include "JITStubs.h"
 33#include "JSArray.h"
 34#include "JSCell.h"
 35#include "JSFunction.h"
 36#include "JSGlobalData.h"
 37#include "JSGlobalObject.h"
 38#include "JSObject.h"
 39#include "JSPropertyNameIterator.h"
 40#include "JSString.h"
 41#include "JSTypeInfo.h"
 42#include "JSVariableObject.h"
 43#include "JumpTable.h"
 44#include "LLIntOfflineAsmConfig.h"
 45#include "MarkedSpace.h"
 46#include "RegisterFile.h"
 47#include "ScopeChain.h"
 48#include "Structure.h"
 49#include "StructureChain.h"
 50#include "ValueProfile.h"
 51#include <wtf/text/StringImpl.h>
 52
 53namespace JSC {
 54
 55#define OFFLINE_ASM_OFFSETOF(clazz, field) OBJECT_OFFSETOF(clazz, field)
 56
 57class LLIntOffsetsExtractor {
 58public:
 59 static const unsigned* dummy();
 60};
 61
 62const unsigned* LLIntOffsetsExtractor::dummy()
 63{
 64// This is a file generated by offlineasm/generate_offsets_extractor.rb, and contains code
 65// to create a table of offsets, sizes, and a header identifying what combination of
 66// Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor
 67// because the fields whose offsets we're extracting are mostly private. So we make their
 68// classes friends with LLIntOffsetsExtractor, and include the header here, to get the C++
 69// compiler to kindly step aside and yield to our best intentions.
 70#include "LLIntDesiredOffsets.h"
 71 return extractorTable;
 72}
 73
 74} // namespace JSC
 75
 76int main(int, char**)
 77{
 78 // Out of an abundance of caution, make sure that LLIntOffsetsExtractor::dummy() is live,
 79 // and the extractorTable is live, too.
 80 printf("%p\n", JSC::LLIntOffsetsExtractor::dummy());
 81 return 0;
 82}
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. fromWhere
 227# should be an immediate integer - any integer you like; use it to identify the place you're
 228# debugging from. operand should likewise be an immediate, and should identify the operand
 229# in the instruction stream you'd like to print out.
 230macro traceOperand(fromWhere, operand)
 231 cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
 232 move t0, PC
 233 move t1, cfr
 234end
 235
 236# Debugging operation if you'd like to print the value of an operand in the instruction
 237# stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
 238# value.
 239macro traceValue(fromWhere, operand)
 240 cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
 241 move t0, PC
 242 move t1, cfr
 243end
 244
 245macro traceExecution()
 246 if EXECUTION_TRACING
 247 callHelper(_llint_trace)
 248 end
 249end
 250
 251# Call a helper for call opcodes.
 252macro callCallHelper(advance, helper, action)
 253 addp advance * 4, PC, t0
 254 storep t0, ArgumentCount + TagOffset[cfr]
 255 cCall2(helper, cfr, PC)
 256 move t1, cfr
 257 action(t0)
 258end
 259
 260macro slowPathForCall(advance, helper)
 261 callCallHelper(
 262 advance,
 263 helper,
 264 macro (callee)
 265 call callee
 266 dispatchAfterCall()
 267 end)
 268end
 269
 270macro checkSwitchToJIT(increment, action)
 271 if JIT_ENABLED
 272 loadp CodeBlock[cfr], t0
 273 baddis increment, CodeBlock::m_llintExecuteCounter[t0], .continue
 274 action()
 275 .continue:
 276 end
 277end
 278
 279macro checkSwitchToJITForLoop()
 280 checkSwitchToJIT(
 281 1,
 282 macro ()
 283 storei PC, ArgumentCount + TagOffset[cfr]
 284 cCall2(_llint_loop_osr, cfr, PC)
 285 move t1, cfr
 286 btpz t0, .recover
 287 jmp t0
 288 .recover:
 289 loadi ArgumentCount + TagOffset[cfr], PC
 290 end)
 291end
 292
 293macro checkSwitchToJITForEpilogue()
 294 checkSwitchToJIT(
 295 10,
 296 macro ()
 297 callHelper(_llint_replace)
 298 end)
 299end
 300
 301macro assertNotConstant(index)
 302 assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
 303end
 304
 305# Index, tag, and payload must be different registers. Index is not
 306# changed.
 307macro loadConstantOrVariable(index, tag, payload)
 308 bigteq index, FirstConstantRegisterIndex, .constant
 309 loadi TagOffset[cfr, index, 8], tag
 310 loadi PayloadOffset[cfr, index, 8], payload
 311 jmp .done
 312.constant:
 313 loadp CodeBlock[cfr], payload
 314 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
 315 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 316 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 317 loadp TagOffset[payload, index, 8], tag
 318 loadp PayloadOffset[payload, index, 8], payload
 319.done:
 320end
 321
 322# Index and payload may be the same register. Index may be clobbered.
 323macro loadConstantOrVariable2Reg(index, tag, payload)
 324 bigteq index, FirstConstantRegisterIndex, .constant
 325 loadi TagOffset[cfr, index, 8], tag
 326 loadi PayloadOffset[cfr, index, 8], payload
 327 jmp .done
 328.constant:
 329 loadp CodeBlock[cfr], tag
 330 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[tag], tag
 331 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 332 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 333 lshifti 3, index
 334 addp index, tag
 335 loadp PayloadOffset[tag], payload
 336 loadp TagOffset[tag], tag
 337.done:
 338end
 339
 340macro loadConstantOrVariablePayloadTagCustom(index, tagCheck, payload)
 341 bigteq index, FirstConstantRegisterIndex, .constant
 342 tagCheck(TagOffset[cfr, index, 8])
 343 loadi PayloadOffset[cfr, index, 8], payload
 344 jmp .done
 345.constant:
 346 loadp CodeBlock[cfr], payload
 347 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[payload], payload
 348 # There is a bit of evil here: if the index contains a value >= FirstConstantRegisterIndex,
 349 # then value << 3 will be equal to (value - FirstConstantRegisterIndex) << 3.
 350 tagCheck(TagOffset[payload, index, 8])
 351 loadp PayloadOffset[payload, index, 8], payload
 352.done:
 353end
 354
 355# Index and payload must be different registers. Index is not mutated. Use
 356# this if you know what the tag of the variable should be. Doing the tag
 357# test as part of loading the variable reduces register use, but may not
 358# be faster than doing loadConstantOrVariable followed by a branch on the
 359# tag.
 360macro loadConstantOrVariablePayload(index, expectedTag, payload, slow)
 361 loadConstantOrVariablePayloadTagCustom(
 362 index,
 363 macro (actualTag) bineq actualTag, expectedTag, slow end,
 364 payload)
 365end
 366
 367macro loadConstantOrVariablePayloadUnchecked(index, payload)
 368 loadConstantOrVariablePayloadTagCustom(
 369 index,
 370 macro (actualTag) end,
 371 payload)
 372end
 373
 374macro writeBarrier(tag, payload)
 375 # Nothing to do, since we don't have a generational or incremental collector.
 376end
 377
 378macro valueProfile(tag, payload, profile)
 379 storei tag, ValueProfile::m_buckets + TagOffset[profile]
 380 storei payload, ValueProfile::m_buckets + PayloadOffset[profile]
 381end
 382
 383
 384# Indicate the beginning of LLInt.
 385_llint_begin:
 386 crash()
 387
 388
 389# Entrypoints into the interpreter
 390
 391macro functionForCallCodeBlockGetter(targetRegister)
 392 loadp Callee[cfr], targetRegister
 393 loadp JSFunction::m_executable[targetRegister], targetRegister
 394 loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
 395end
 396
 397macro functionForConstructCodeBlockGetter(targetRegister)
 398 loadp Callee[cfr], targetRegister
 399 loadp JSFunction::m_executable[targetRegister], targetRegister
 400 loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
 401end
 402
 403macro notFunctionCodeBlockGetter(targetRegister)
 404 loadp CodeBlock[cfr], targetRegister
 405end
 406
 407macro functionCodeBlockSetter(sourceRegister)
 408 storep sourceRegister, CodeBlock[cfr]
 409end
 410
 411macro notFunctionCodeBlockSetter(sourceRegister)
 412 # Nothing to do!
 413end
 414
 415# Do the bare minimum required to execute code. Sets up the PC, leave the CodeBlock*
 416# in t1. May also trigger prologue entry OSR.
 417macro prologue(codeBlockGetter, codeBlockSetter, osrHelper, traceHelper)
 418 preserveReturnAddressAfterCall(t2)
 419
 420 # Set up the call frame and check if we should OSR.
 421 storep t2, ReturnPC[cfr]
 422 if EXECUTION_TRACING
 423 callHelper(traceHelper)
 424 end
 425 codeBlockGetter(t1)
 426 if JIT_ENABLED
 427 baddis 5, CodeBlock::m_llintExecuteCounter[t1], .continue
 428 cCall2(osrHelper, cfr, PC)
 429 move t1, cfr
 430 btpz t0, .recover
 431 loadp ReturnPC[cfr], t2
 432 restoreReturnAddressBeforeReturn(t2)
 433 jmp t0
 434 .recover:
 435 codeBlockGetter(t1)
 436 .continue:
 437 end
 438 codeBlockSetter(t1)
 439
 440 # Set up the PC.
 441 loadp CodeBlock::m_instructions[t1], t0
 442 loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
 443end
 444
 445# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
 446# Must call dispatch(0) after calling this.
 447macro functionInitialization(profileArgSkip)
 448 # Profile the arguments. Unfortunately, we have no choice but to do this. This
 449 # code is pretty horrendous because of the difference in ordering between
 450 # arguments and value profiles, the desire to have a simple loop-down-to-zero
 451 # loop, and the desire to use only three registers so as to preserve the PC and
 452 # the code block. It is likely that this code should be rewritten in a more
 453 # optimal way for architectures that have more than five registers available
 454 # for arbitrary use in the interpreter.
 455 loadi CodeBlock::m_numParameters[t1], t0
 456 addi -profileArgSkip, t0 # Use addi because that's what has the peephole
 457 assert(macro (ok) bigteq t0, 0, ok end)
 458 btiz t0, .argumentProfileDone
 459 loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
 460 muli sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
 461 negi t0
 462 lshifti 3, t0
 463 addp t2, t3
 464.argumentProfileLoop:
 465 loadi ThisArgumentOffset + TagOffset + 8 - profileArgSkip * 8[cfr, t0], t2
 466 subp sizeof ValueProfile, t3
 467 storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
 468 loadi ThisArgumentOffset + PayloadOffset + 8 - profileArgSkip * 8[cfr, t0], t2
 469 storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
 470 baddinz 8, t0, .argumentProfileLoop
 471.argumentProfileDone:
 472
 473 # Check stack height.
 474 loadi CodeBlock::m_numCalleeRegisters[t1], t0
 475 loadp CodeBlock::m_globalData[t1], t2
 476 loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the RegisterFile from the JITStackFrame
 477 lshifti 3, t0
 478 addp t0, cfr, t0
 479 bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK
 480
 481 # Stack height check failed - need to call a helper.
 482 callHelper(_llint_register_file_check)
 483.stackHeightOK:
 484end
 485
 486# Expects that CodeBlock is in t1, which is what prologue() leaves behind.
 487macro functionArityCheck(doneLabel, helper)
 488 loadi PayloadOffset + ArgumentCount[cfr], t0
 489 biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
 490 cCall2(helper, cfr, PC) # This helper has a simple protocol: t0 = 0 => no error, t0 != 0 => error
 491 move t1, cfr
 492 btiz t0, .continue
 493 loadp JITStackFrame::globalData[sp], t1
 494 loadp JSGlobalData::callFrameForThrow[t1], t0
 495 jmp JSGlobalData::targetMachinePCForThrow[t1]
 496.continue:
 497 # Reload CodeBlock and PC, since the helper clobbered it.
 498 loadp CodeBlock[cfr], t1
 499 loadp CodeBlock::m_instructions[t1], t0
 500 loadp CodeBlock::Instructions::m_instructions + VectorBufferOffset[t0], PC
 501 jmp doneLabel
 502end
 503
 504_llint_program_prologue:
 505 prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
 506 dispatch(0)
 507
 508
 509_llint_eval_prologue:
 510 prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue)
 511 dispatch(0)
 512
 513
 514_llint_function_for_call_prologue:
 515 prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call)
 516.functionForCallBegin:
 517 functionInitialization(0)
 518 dispatch(0)
 519
 520
 521_llint_function_for_construct_prologue:
 522 prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct)
 523.functionForConstructBegin:
 524 functionInitialization(1)
 525 dispatch(0)
 526
 527
 528_llint_function_for_call_arity_check:
 529 prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call)
 530 functionArityCheck(.functionForCallBegin, _llint_helper_call_arityCheck)
 531
 532
 533_llint_function_for_construct_arity_check:
 534 prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct)
 535 functionArityCheck(.functionForConstructBegin, _llint_helper_construct_arityCheck)
 536
 537# Instruction implementations
 538
 539_llint_op_enter:
 540 traceExecution()
 541 loadp CodeBlock[cfr], t2
 542 loadi CodeBlock::m_numVars[t2], t2
 543 btiz t2, .opEnterDone
 544 move UndefinedTag, t0
 545 move 0, t1
 546.opEnterLoop:
 547 subi 1, t2
 548 storei t0, TagOffset[cfr, t2, 8]
 549 storei t1, PayloadOffset[cfr, t2, 8]
 550 btinz t2, .opEnterLoop
 551.opEnterDone:
 552 dispatch(1)
 553
 554
 555_llint_op_create_activation:
 556 traceExecution()
 557 loadi 4[PC], t0
 558 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateActivationDone
 559 callHelper(_llint_helper_create_activation)
 560.opCreateActivationDone:
 561 dispatch(2)
 562
 563
 564_llint_op_init_lazy_reg:
 565 traceExecution()
 566 loadi 4[PC], t0
 567 storei EmptyValueTag, TagOffset[cfr, t0, 8]
 568 storei 0, PayloadOffset[cfr, t0, 8]
 569 dispatch(2)
 570
 571
 572_llint_op_create_arguments:
 573 traceExecution()
 574 loadi 4[PC], t0
 575 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
 576 callHelper(_llint_helper_create_arguments)
 577.opCreateArgumentsDone:
 578 dispatch(2)
 579
 580
 581macro allocateBasicJSObject(sizeClassIndex, classInfoOffset, structure, result, scratch1, scratch2, slowCase)
 582 const offsetOfMySizeClass = JSGlobalData::heap + Heap::m_objectSpace + MarkedSpace::m_preciseSizeClasses + sizeClassIndex * sizeof MarkedSpace::SizeClass
 583
 584 # FIXME: we can get the global data in one load from the stack.
 585 loadp CodeBlock[cfr], scratch1
 586 loadp CodeBlock::m_globalData[scratch1], scratch1
 587
 588 # Get the object from the free list.
 589 loadp offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1], result
 590 btpz result, slowCase
 591
 592 # Remove the object from the free list.
 593 loadp [result], scratch2
 594 storep scratch2, offsetOfMySizeClass + MarkedSpace::SizeClass::firstFreeCell[scratch1]
 595
 596 # Initialize the object.
 597 loadp classInfoOffset[scratch1], scratch2
 598 storep scratch2, [result]
 599 storep structure, JSCell::m_structure[result]
 600 storep 0, JSObject::m_inheritorID[result]
 601 addp sizeof JSObject, result, scratch1
 602 storep scratch1, JSObject::m_propertyStorage[result]
 603end
 604
 605_llint_op_create_this:
 606 traceExecution()
 607 loadi 8[PC], t0
 608 assertNotConstant(t0)
 609 bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow
 610 loadi PayloadOffset[cfr, t0, 8], t0
 611 loadp JSCell::m_structure[t0], t1
 612 bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow
 613 loadp JSObject::m_inheritorID[t0], t2
 614 btpz t2, .opCreateThisSlow
 615 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow)
 616 loadi 4[PC], t1
 617 storei CellTag, TagOffset[cfr, t1, 8]
 618 storei t0, PayloadOffset[cfr, t1, 8]
 619 dispatch(3)
 620
 621.opCreateThisSlow:
 622 callHelper(_llint_helper_create_this)
 623 dispatch(3)
 624
 625
 626_llint_op_get_callee:
 627 traceExecution()
 628 loadi 4[PC], t0
 629 loadp PayloadOffset + Callee[cfr], t1
 630 storei CellTag, TagOffset[cfr, t0, 8]
 631 storei t1, PayloadOffset[cfr, t0, 8]
 632 dispatch(2)
 633
 634
 635_llint_op_convert_this:
 636 traceExecution()
 637 loadi 4[PC], t0
 638 bineq TagOffset[cfr, t0, 8], CellTag, .opConvertThisSlow
 639 loadi PayloadOffset[cfr, t0, 8], t0
 640 loadp JSCell::m_structure[t0], t0
 641 bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
 642 dispatch(2)
 643
 644.opConvertThisSlow:
 645 callHelper(_llint_helper_convert_this)
 646 dispatch(2)
 647
 648
 649_llint_op_new_object:
 650 traceExecution()
 651 loadp CodeBlock[cfr], t0
 652 loadp CodeBlock::m_globalObject[t0], t0
 653 loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
 654 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t1, t0, t2, t3, .opNewObjectSlow)
 655 loadi 4[PC], t1
 656 storei CellTag, TagOffset[cfr, t1, 8]
 657 storei t0, PayloadOffset[cfr, t1, 8]
 658 dispatch(2)
 659
 660.opNewObjectSlow:
 661 callHelper(_llint_helper_new_object)
 662 dispatch(2)
 663
 664
 665_llint_op_new_array:
 666 traceExecution()
 667 callHelper(_llint_helper_new_array)
 668 dispatch(4)
 669
 670
 671_llint_op_new_array_buffer:
 672 traceExecution()
 673 callHelper(_llint_helper_new_array_buffer)
 674 dispatch(4)
 675
 676
 677_llint_op_new_regexp:
 678 traceExecution()
 679 callHelper(_llint_helper_new_regexp)
 680 dispatch(3)
 681
 682
 683_llint_op_mov:
 684 traceExecution()
 685 loadi 8[PC], t1
 686 loadi 4[PC], t0
 687 loadConstantOrVariable(t1, t2, t3)
 688 storei t2, TagOffset[cfr, t0, 8]
 689 storei t3, PayloadOffset[cfr, t0, 8]
 690 dispatch(3)
 691
 692
 693_llint_op_not:
 694 traceExecution()
 695 loadi 8[PC], t0
 696 loadi 4[PC], t1
 697 loadConstantOrVariable(t0, t2, t3)
 698 bineq t2, BooleanTag, .opNotSlow
 699 xori 1, t3
 700 storei t2, TagOffset[cfr, t1, 8]
 701 storei t3, PayloadOffset[cfr, t1, 8]
 702 dispatch(3)
 703
 704.opNotSlow:
 705 callHelper(_llint_helper_not)
 706 dispatch(3)
 707
 708
 709_llint_op_eq:
 710 traceExecution()
 711 loadi 12[PC], t2
 712 loadi 8[PC], t0
 713 loadConstantOrVariable(t2, t3, t1)
 714 loadConstantOrVariable2Reg(t0, t2, t0)
 715 bineq t2, t3, .opEqSlow
 716 bieq t2, CellTag, .opEqSlow
 717 bib t2, LowestTag, .opEqSlow
 718 loadi 4[PC], t2
 719 cieq t0, t1, t0
 720 storei BooleanTag, TagOffset[cfr, t2, 8]
 721 storei t0, PayloadOffset[cfr, t2, 8]
 722 dispatch(4)
 723
 724.opEqSlow:
 725 callHelper(_llint_helper_eq)
 726 dispatch(4)
 727
 728
 729_llint_op_eq_null:
 730 traceExecution()
 731 loadi 8[PC], t0
 732 loadi 4[PC], t3
 733 assertNotConstant(t0)
 734 loadi TagOffset[cfr, t0, 8], t1
 735 loadi PayloadOffset[cfr, t0, 8], t0
 736 bineq t1, CellTag, .opEqNullImmediate
 737 loadp JSCell::m_structure[t0], t1
 738 tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
 739 jmp .opEqNullNotImmediate
 740.opEqNullImmediate:
 741 cieq t1, NullTag, t2
 742 cieq t1, UndefinedTag, t1
 743 ori t2, t1
 744.opEqNullNotImmediate:
 745 storei BooleanTag, TagOffset[cfr, t3, 8]
 746 storei t1, PayloadOffset[cfr, t3, 8]
 747 dispatch(3)
 748
 749
 750_llint_op_neq:
 751 traceExecution()
 752 loadi 12[PC], t2
 753 loadi 8[PC], t0
 754 loadConstantOrVariable(t2, t3, t1)
 755 loadConstantOrVariable2Reg(t0, t2, t0)
 756 bineq t2, t3, .opNeqSlow
 757 bieq t2, CellTag, .opNeqSlow
 758 bib t2, LowestTag, .opNeqSlow
 759 loadi 4[PC], t2
 760 cineq t0, t1, t0
 761 storei BooleanTag, TagOffset[cfr, t2, 8]
 762 storei t0, PayloadOffset[cfr, t2, 8]
 763 dispatch(4)
 764
 765.opNeqSlow:
 766 callHelper(_llint_helper_neq)
 767 dispatch(4)
 768
 769
 770_llint_op_neq_null:
 771 traceExecution()
 772 loadi 8[PC], t0
 773 loadi 4[PC], t3
 774 assertNotConstant(t0)
 775 loadi TagOffset[cfr, t0, 8], t1
 776 loadi PayloadOffset[cfr, t0, 8], t0
 777 bineq t1, CellTag, .opNeqNullImmediate
 778 loadp JSCell::m_structure[t0], t1
 779 tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
 780 jmp .opNeqNullNotImmediate
 781.opNeqNullImmediate:
 782 cineq t1, NullTag, t2
 783 cineq t1, UndefinedTag, t1
 784 andi t2, t1
 785.opNeqNullNotImmediate:
 786 storei BooleanTag, TagOffset[cfr, t3, 8]
 787 storei t1, PayloadOffset[cfr, t3, 8]
 788 dispatch(3)
 789
 790
 791macro strictEq(equalityOperation, helper)
 792 loadi 12[PC], t2
 793 loadi 8[PC], t0
 794 loadConstantOrVariable(t2, t3, t1)
 795 loadConstantOrVariable2Reg(t0, t2, t0)
 796 bineq t2, t3, .slow
 797 bib t2, LowestTag, .slow
 798 bineq t2, CellTag, .notString
 799 loadp JSCell::m_structure[t0], t2
 800 loadp JSCell::m_structure[t1], t3
 801 bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .notString
 802 bbeq Structure::m_typeInfo + TypeInfo::m_type[t3], StringType, .slow
 803.notString:
 804 loadi 4[PC], t2
 805 equalityOperation(t0, t1, t0)
 806 storei BooleanTag, TagOffset[cfr, t2, 8]
 807 storei t0, PayloadOffset[cfr, t2, 8]
 808 dispatch(4)
 809
 810.slow:
 811 callHelper(helper)
 812 dispatch(4)
 813end
 814
 815_llint_op_stricteq:
 816 traceExecution()
 817 strictEq(macro (left, right, result) cieq left, right, result end, _llint_helper_stricteq)
 818
 819
 820_llint_op_nstricteq:
 821 traceExecution()
 822 strictEq(macro (left, right, result) cineq left, right, result end, _llint_helper_nstricteq)
 823
 824
 825_llint_op_less:
 826 traceExecution()
 827 callHelper(_llint_helper_less)
 828 dispatch(4)
 829
 830
 831_llint_op_lesseq:
 832 traceExecution()
 833 callHelper(_llint_helper_lesseq)
 834 dispatch(4)
 835
 836
 837_llint_op_greater:
 838 traceExecution()
 839 callHelper(_llint_helper_greater)
 840 dispatch(4)
 841
 842
 843_llint_op_greatereq:
 844 traceExecution()
 845 callHelper(_llint_helper_greatereq)
 846 dispatch(4)
 847
 848
 849_llint_op_pre_inc:
 850 traceExecution()
 851 loadi 4[PC], t0
 852 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
 853 loadi PayloadOffset[cfr, t0, 8], t1
 854 baddio 1, t1, .opPreIncSlow
 855 storei t1, PayloadOffset[cfr, t0, 8]
 856 dispatch(2)
 857
 858.opPreIncSlow:
 859 callHelper(_llint_helper_pre_inc)
 860 dispatch(2)
 861
 862
 863_llint_op_pre_dec:
 864 traceExecution()
 865 loadi 4[PC], t0
 866 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
 867 loadi PayloadOffset[cfr, t0, 8], t1
 868 bsubio 1, t1, .opPreDecSlow
 869 storei t1, PayloadOffset[cfr, t0, 8]
 870 dispatch(2)
 871
 872.opPreDecSlow:
 873 callHelper(_llint_helper_pre_dec)
 874 dispatch(2)
 875
 876
 877_llint_op_post_inc:
 878 traceExecution()
 879 loadi 8[PC], t0
 880 loadi 4[PC], t1
 881 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
 882 bieq t0, t1, .opPostIncDone
 883 loadi PayloadOffset[cfr, t0, 8], t2
 884 move t2, t3
 885 baddio 1, t3, .opPostIncSlow
 886 storei Int32Tag, TagOffset[cfr, t1, 8]
 887 storei t2, PayloadOffset[cfr, t1, 8]
 888 storei t3, PayloadOffset[cfr, t0, 8]
 889.opPostIncDone:
 890 dispatch(3)
 891
 892.opPostIncSlow:
 893 callHelper(_llint_helper_post_inc)
 894 dispatch(3)
 895
 896
 897_llint_op_post_dec:
 898 traceExecution()
 899 loadi 8[PC], t0
 900 loadi 4[PC], t1
 901 bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
 902 bieq t0, t1, .opPostDecDone
 903 loadi PayloadOffset[cfr, t0, 8], t2
 904 move t2, t3
 905 bsubio 1, t3, .opPostDecSlow
 906 storei Int32Tag, TagOffset[cfr, t1, 8]
 907 storei t2, PayloadOffset[cfr, t1, 8]
 908 storei t3, PayloadOffset[cfr, t0, 8]
 909.opPostDecDone:
 910 dispatch(3)
 911
 912.opPostDecSlow:
 913 callHelper(_llint_helper_post_dec)
 914 dispatch(3)
 915
 916
 917_llint_op_to_jsnumber:
 918 traceExecution()
 919 loadi 8[PC], t0
 920 loadi 4[PC], t1
 921 loadConstantOrVariable(t0, t2, t3)
 922 bieq t2, Int32Tag, .opToJsnumberIsInt
 923 biaeq t2, EmptyValueTag, .opToJsnumberSlow
 924.opToJsnumberIsInt:
 925 storei t2, TagOffset[cfr, t1, 8]
 926 storei t3, PayloadOffset[cfr, t1, 8]
 927 dispatch(3)
 928
 929.opToJsnumberSlow:
 930 callHelper(_llint_helper_to_jsnumber)
 931 dispatch(3)
 932
 933
 934_llint_op_negate:
 935 traceExecution()
 936 loadi 8[PC], t0
 937 loadi 4[PC], t3
 938 loadConstantOrVariable(t0, t1, t2)
 939 bineq t1, Int32Tag, .opNegateSrcNotInt
 940 btiz t2, 0x7fffffff, .opNegateSlow
 941 negi t2
 942 storei Int32Tag, TagOffset[cfr, t3, 8]
 943 storei t2, PayloadOffset[cfr, t3, 8]
 944 dispatch(3)
 945.opNegateSrcNotInt:
 946 bia t1, LowestTag, .opNegateSlow
 947 xori 0x80000000, t1
 948 storei t1, TagOffset[cfr, t3, 8]
 949 storei t2, PayloadOffset[cfr, t3, 8]
 950 dispatch(3)
 951
 952.opNegateSlow:
 953 callHelper(_llint_helper_negate)
 954 dispatch(3)
 955
 956
 957macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, helper)
 958 loadi 12[PC], t2
 959 loadi 8[PC], t0
 960 loadConstantOrVariable(t2, t3, t1)
 961 loadConstantOrVariable2Reg(t0, t2, t0)
 962 bineq t2, Int32Tag, .op1NotInt
 963 bineq t3, Int32Tag, .op2NotInt
 964 loadi 4[PC], t2
 965 integerOperationAndStore(t3, t1, t0, .slow, t2)
 966 dispatch(5)
 967
 968.op1NotInt:
 969 # First operand is definitely not an int, the second operand could be anything.
 970 bia t2, LowestTag, .slow
 971 bib t3, LowestTag, .op1NotIntOp2Double
 972 bineq t3, Int32Tag, .slow
 973 ci2d t1, ft1
 974 jmp .op1NotIntReady
 975.op1NotIntOp2Double:
 976 fii2d t1, t3, ft1
 977.op1NotIntReady:
 978 loadi 4[PC], t1
 979 fii2d t0, t2, ft0
 980 doubleOperation(ft1, ft0)
 981 stored ft0, [cfr, t1, 8]
 982 dispatch(5)
 983
 984.op2NotInt:
 985 # First operand is definitely an int, the second operand is definitely not.
 986 loadi 4[PC], t2
 987 bia t3, LowestTag, .slow
 988 ci2d t0, ft0
 989 fii2d t1, t3, ft1
 990 doubleOperation(ft1, ft0)
 991 stored ft0, [cfr, t2, 8]
 992 dispatch(5)
 993
 994.slow:
 995 callHelper(helper)
 996 dispatch(5)
 997end
 998
 999macro binaryOp(integerOperation, doubleOperation, helper)
 1000 binaryOpCustomStore(
 1001 macro (int32Tag, left, right, slow, index)
 1002 integerOperation(left, right, slow)
 1003 storei int32Tag, TagOffset[cfr, index, 8]
 1004 storei right, PayloadOffset[cfr, index, 8]
 1005 end,
 1006 doubleOperation, helper)
 1007end
 1008
 1009_llint_op_add:
 1010 traceExecution()
 1011 binaryOp(
 1012 macro (left, right, slow) baddio left, right, slow end,
 1013 macro (left, right) addd left, right end,
 1014 _llint_helper_add)
 1015
 1016
 1017_llint_op_mul:
 1018 traceExecution()
 1019 binaryOpCustomStore(
 1020 macro (int32Tag, left, right, slow, index)
 1021 const scratch = int32Tag # We know that we can reuse the int32Tag register since it has a constant.
 1022 move right, scratch
 1023 bmulio left, scratch, slow
 1024 btinz scratch, .done
 1025 bilt left, 0, slow
 1026 bilt right, 0, slow
 1027 .done:
 1028 storei Int32Tag, TagOffset[cfr, index, 8]
 1029 storei scratch, PayloadOffset[cfr, index, 8]
 1030 end,
 1031 macro (left, right) muld left, right end,
 1032 _llint_helper_mul)
 1033
 1034
 1035_llint_op_sub:
 1036 traceExecution()
 1037 binaryOp(
 1038 macro (left, right, slow) bsubio left, right, slow end,
 1039 macro (left, right) subd left, right end,
 1040 _llint_helper_sub)
 1041
 1042
 1043_llint_op_div:
 1044 traceExecution()
 1045 binaryOpCustomStore(
 1046 macro (int32Tag, left, right, slow, index)
 1047 ci2d left, ft0
 1048 ci2d right, ft1
 1049 divd ft0, ft1
 1050 bcd2i ft1, right, .notInt
 1051 storei int32Tag, TagOffset[cfr, index, 8]
 1052 storei right, PayloadOffset[cfr, index, 8]
 1053 jmp .done
 1054 .notInt:
 1055 stored ft1, [cfr, index, 8]
 1056 .done:
 1057 end,
 1058 macro (left, right) divd left, right end,
 1059 _llint_helper_div)
 1060
 1061
 1062_llint_op_mod:
 1063 traceExecution()
 1064 callHelper(_llint_helper_mod)
 1065 dispatch(4)
 1066
 1067
 1068macro bitOp(operation, helper, advance)
 1069 loadi 12[PC], t2
 1070 loadi 8[PC], t0
 1071 loadConstantOrVariable(t2, t3, t1)
 1072 loadConstantOrVariable2Reg(t0, t2, t0)
 1073 bineq t3, Int32Tag, .slow
 1074 bineq t2, Int32Tag, .slow
 1075 loadi 4[PC], t2
 1076 operation(t1, t0, .slow)
 1077 storei t3, TagOffset[cfr, t2, 8]
 1078 storei t0, PayloadOffset[cfr, t2, 8]
 1079 dispatch(advance)
 1080
 1081.slow:
 1082 callHelper(helper)
 1083 dispatch(advance)
 1084end
 1085
 1086_llint_op_lshift:
 1087 traceExecution()
 1088 bitOp(
 1089 macro (left, right, slow) lshifti left, right end,
 1090 _llint_helper_lshift,
 1091 4)
 1092
 1093
 1094_llint_op_rshift:
 1095 traceExecution()
 1096 bitOp(
 1097 macro (left, right, slow) rshifti left, right end,
 1098 _llint_helper_rshift,
 1099 4)
 1100
 1101
 1102_llint_op_urshift:
 1103 traceExecution()
 1104 bitOp(
 1105 macro (left, right, slow)
 1106 urshifti left, right
 1107 bilt right, 0, slow
 1108 end,
 1109 _llint_helper_urshift,
 1110 4)
 1111
 1112
 1113_llint_op_bitand:
 1114 traceExecution()
 1115 bitOp(
 1116 macro (left, right, slow) andi left, right end,
 1117 _llint_helper_bitand,
 1118 5)
 1119
 1120
 1121_llint_op_bitxor:
 1122 traceExecution()
 1123 bitOp(
 1124 macro (left, right, slow) xori left, right end,
 1125 _llint_helper_bitxor,
 1126 5)
 1127
 1128
 1129_llint_op_bitor:
 1130 traceExecution()
 1131 bitOp(
 1132 macro (left, right, slow) ori left, right end,
 1133 _llint_helper_bitor,
 1134 5)
 1135
 1136
 1137_llint_op_bitnot:
 1138 traceExecution()
 1139 loadi 8[PC], t1
 1140 loadi 4[PC], t0
 1141 loadConstantOrVariable(t1, t2, t3)
 1142 bineq t2, Int32Tag, .opBitnotSlow
 1143 noti t3
 1144 storei t2, TagOffset[cfr, t0, 8]
 1145 storei t3, PayloadOffset[cfr, t0, 8]
 1146 dispatch(3)
 1147
 1148.opBitnotSlow:
 1149 callHelper(_llint_helper_bitnot)
 1150 dispatch(3)
 1151
 1152
 1153_llint_op_check_has_instance:
 1154 traceExecution()
 1155 loadi 4[PC], t1
 1156 loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow)
 1157 loadp JSCell::m_structure[t0], t0
 1158 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsHasInstance, .opCheckHasInstanceSlow
 1159 dispatch(2)
 1160
 1161.opCheckHasInstanceSlow:
 1162 callHelper(_llint_helper_check_has_instance)
 1163 dispatch(2)
 1164
 1165
 1166_llint_op_instanceof:
 1167 traceExecution()
 1168 # Check that baseVal implements the default HasInstance behavior.
 1169 # FIXME: This should be deprecated.
 1170 loadi 12[PC], t1
 1171 loadConstantOrVariablePayloadUnchecked(t1, t0)
 1172 loadp JSCell::m_structure[t0], t0
 1173 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow
 1174
 1175 # Actually do the work.
 1176 loadi 16[PC], t0
 1177 loadi 4[PC], t3
 1178 loadConstantOrVariablePayload(t0, CellTag, t1, .opInstanceofSlow)
 1179 loadp JSCell::m_structure[t1], t2
 1180 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
 1181 loadi 8[PC], t0
 1182 loadConstantOrVariablePayload(t0, CellTag, t2, .opInstanceofSlow)
 1183
 1184 # Register state: t1 = prototype, t2 = value
 1185 move 1, t0
 1186.opInstanceofLoop:
 1187 loadp JSCell::m_structure[t2], t2
 1188 loadi Structure::m_prototype + PayloadOffset[t2], t2
 1189 bpeq t2, t1, .opInstanceofDone
 1190 btinz t2, .opInstanceofLoop
 1191
 1192 move 0, t0
 1193.opInstanceofDone:
 1194 storei BooleanTag, TagOffset[cfr, t3, 8]
 1195 storei t0, PayloadOffset[cfr, t3, 8]
 1196 dispatch(5)
 1197
 1198.opInstanceofSlow:
 1199 callHelper(_llint_helper_instanceof)
 1200 dispatch(5)
 1201
 1202
 1203_llint_op_typeof:
 1204 traceExecution()
 1205 callHelper(_llint_helper_typeof)
 1206 dispatch(3)
 1207
 1208
 1209_llint_op_is_undefined:
 1210 traceExecution()
 1211 callHelper(_llint_helper_is_undefined)
 1212 dispatch(3)
 1213
 1214
 1215_llint_op_is_boolean:
 1216 traceExecution()
 1217 callHelper(_llint_helper_is_boolean)
 1218 dispatch(3)
 1219
 1220
 1221_llint_op_is_number:
 1222 traceExecution()
 1223 callHelper(_llint_helper_is_number)
 1224 dispatch(3)
 1225
 1226
 1227_llint_op_is_string:
 1228 traceExecution()
 1229 callHelper(_llint_helper_is_string)
 1230 dispatch(3)
 1231
 1232
 1233_llint_op_is_object:
 1234 traceExecution()
 1235 callHelper(_llint_helper_is_object)
 1236 dispatch(3)
 1237
 1238
 1239_llint_op_is_function:
 1240 traceExecution()
 1241 callHelper(_llint_helper_is_function)
 1242 dispatch(3)
 1243
 1244
 1245_llint_op_in:
 1246 traceExecution()
 1247 callHelper(_llint_helper_in)
 1248 dispatch(4)
 1249
 1250
 1251_llint_op_resolve:
 1252 traceExecution()
 1253 callHelper(_llint_helper_resolve)
 1254 dispatch(4)
 1255
 1256
 1257_llint_op_resolve_skip:
 1258 traceExecution()
 1259 callHelper(_llint_helper_resolve_skip)
 1260 dispatch(5)
 1261
 1262
 1263macro resolveGlobal(size, slow)
 1264 # Operands are as follows:
 1265 # 4[PC] Destination for the load.
 1266 # 8[PC] Property identifier index in the code block.
 1267 # 12[PC] Structure pointer, initialized to 0 by bytecode generator.
 1268 # 16[PC] Offset in global object, initialized to 0 by bytecode generator.
 1269 loadp CodeBlock[cfr], t0
 1270 loadp CodeBlock::m_globalObject[t0], t0
 1271 loadp JSCell::m_structure[t0], t1
 1272 bpneq t1, 12[PC], slow
 1273 loadi 16[PC], t1
 1274 loadp JSObject::m_propertyStorage[t0], t0
 1275 loadi TagOffset[t0, t1, 8], t2
 1276 loadi PayloadOffset[t0, t1, 8], t3
 1277 loadi 4[PC], t0
 1278 storei t2, TagOffset[cfr, t0, 8]
 1279 storei t3, PayloadOffset[cfr, t0, 8]
 1280 loadi (size - 1) * 4[PC], t0
 1281 valueProfile(t2, t3, t0)
 1282end
 1283
 1284_llint_op_resolve_global:
 1285 traceExecution()
 1286 resolveGlobal(6, .opResolveGlobalSlow)
 1287 dispatch(6)
 1288
 1289.opResolveGlobalSlow:
 1290 callHelper(_llint_helper_resolve_global)
 1291 dispatch(6)
 1292
 1293
 1294# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
 1295# scopes as they are traversed. scopeCheck() is called with two arguments: the register
 1296# holding the scope, and a register that can be used for scratch. Note that this does not
 1297# use t3, so you can hold stuff in t3 if need be.
 1298macro getScope(deBruijinIndexOperand, scopeCheck)
 1299 loadp ScopeChain + PayloadOffset[cfr], t0
 1300 loadi deBruijinIndexOperand, t2
 1301
 1302 btiz t2, .done
 1303
 1304 loadp CodeBlock[cfr], t1
 1305 bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
 1306 btbz CodeBlock::m_needsFullScopeChain[t1], .loop
 1307
 1308 loadi CodeBlock::m_activationRegister[t1], t1
 1309
 1310 # Need to conditionally skip over one scope.
 1311 bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
 1312 scopeCheck(t0, t1)
 1313 loadp ScopeChainNode::next[t0], t0
 1314.noActivation:
 1315 subi 1, t2
 1316
 1317 btiz t2, .done
 1318.loop:
 1319 scopeCheck(t0, t1)
 1320 loadp ScopeChainNode::next[t0], t0
 1321 subi 1, t2
 1322 btinz t2, .loop
 1323
 1324.done:
 1325end
 1326
 1327_llint_op_resolve_global_dynamic:
 1328 traceExecution()
 1329 loadp JITStackFrame::globalData[sp], t3
 1330 loadp JSGlobalData::activationStructure[t3], t3
 1331 getScope(
 1332 20[PC],
 1333 macro (scope, scratch)
 1334 loadp ScopeChainNode::object[scope], scratch
 1335 bpneq JSCell::m_structure[scratch], t3, .opResolveGlobalDynamicSuperSlow
 1336 end)
 1337 resolveGlobal(7, .opResolveGlobalDynamicSlow)
 1338 dispatch(7)
 1339
 1340.opResolveGlobalDynamicSuperSlow:
 1341 callHelper(_llint_helper_resolve_for_resolve_global_dynamic)
 1342 dispatch(7)
 1343
 1344.opResolveGlobalDynamicSlow:
 1345 callHelper(_llint_helper_resolve_global_dynamic)
 1346 dispatch(7)
 1347
 1348
 1349_llint_op_get_scoped_var:
 1350 traceExecution()
 1351 # Operands are as follows:
 1352 # 4[PC] Destination for the load.
 1353 # 8[PC] Index of register in the scope.
 1354 # 12[PC] De Bruijin index.
 1355 getScope(12[PC], macro (scope, scratch) end)
 1356 loadi 4[PC], t1
 1357 loadi 8[PC], t2
 1358 loadp ScopeChainNode::object[t0], t0
 1359 loadp JSVariableObject::m_registers[t0], t0
 1360 loadi TagOffset[t0, t2, 8], t3
 1361 loadi PayloadOffset[t0, t2, 8], t0
 1362 storei t3, TagOffset[cfr, t1, 8]
 1363 storei t0, PayloadOffset[cfr, t1, 8]
 1364 loadi 16[PC], t1
 1365 valueProfile(t3, t0, t1)
 1366 dispatch(5)
 1367
 1368
 1369_llint_op_put_scoped_var:
 1370 traceExecution()
 1371 getScope(8[PC], macro (scope, scratch) end)
 1372 loadi 12[PC], t1
 1373 loadConstantOrVariable(t1, t3, t2)
 1374 loadi 4[PC], t1
 1375 writeBarrier(t3, t2)
 1376 loadp ScopeChainNode::object[t0], t0
 1377 loadp JSVariableObject::m_registers[t0], t0
 1378 storei t3, TagOffset[t0, t1, 8]
 1379 storei t2, PayloadOffset[t0, t1, 8]
 1380 dispatch(4)
 1381
 1382
 1383_llint_op_get_global_var:
 1384 traceExecution()
 1385 loadi 8[PC], t1
 1386 loadi 4[PC], t3
 1387 loadp CodeBlock[cfr], t0
 1388 loadp CodeBlock::m_globalObject[t0], t0
 1389 loadp JSGlobalObject::m_registers[t0], t0
 1390 loadi TagOffset[t0, t1, 8], t2
 1391 loadi PayloadOffset[t0, t1, 8], t1
 1392 storei t2, TagOffset[cfr, t3, 8]
 1393 storei t1, PayloadOffset[cfr, t3, 8]
 1394 loadi 12[PC], t3
 1395 valueProfile(t2, t1, t3)
 1396 dispatch(4)
 1397
 1398
 1399_llint_op_put_global_var:
 1400 traceExecution()
 1401 loadi 8[PC], t1
 1402 loadp CodeBlock[cfr], t0
 1403 loadp CodeBlock::m_globalObject[t0], t0
 1404 loadp JSGlobalObject::m_registers[t0], t0
 1405 loadConstantOrVariable(t1, t2, t3)
 1406 loadi 4[PC], t1
 1407 writeBarrier(t2, t3)
 1408 storei t2, TagOffset[t0, t1, 8]
 1409 storei t3, PayloadOffset[t0, t1, 8]
 1410 dispatch(3)
 1411
 1412
 1413_llint_op_resolve_base:
 1414 traceExecution()
 1415 callHelper(_llint_helper_resolve_base)
 1416 dispatch(5)
 1417
 1418
 1419_llint_op_ensure_property_exists:
 1420 traceExecution()
 1421 callHelper(_llint_helper_ensure_property_exists)
 1422 dispatch(3)
 1423
 1424
 1425_llint_op_resolve_with_base:
 1426 traceExecution()
 1427 callHelper(_llint_helper_resolve_with_base)
 1428 dispatch(5)
 1429
 1430
 1431_llint_op_resolve_with_this:
 1432 traceExecution()
 1433 callHelper(_llint_helper_resolve_with_this)
 1434 dispatch(5)
 1435
 1436
 1437_llint_op_get_by_id:
 1438 traceExecution()
 1439 # We only do monomorphic get_by_id caching for now, and we do not modify the
 1440 # opcode. We do, however, allow for the cache to change anytime if fails, since
 1441 # ping-ponging is free. At best we get lucky and the get_by_id will continue
 1442 # to take fast path on the new cache. At worst we take slow path, which is what
 1443 # we would have been doing anyway.
 1444 loadi 8[PC], t0
 1445 loadi 16[PC], t1
 1446 loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
 1447 loadi 20[PC], t2
 1448 loadp JSObject::m_propertyStorage[t3], t0
 1449 bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
 1450 loadi 4[PC], t1
 1451 loadi TagOffset[t0, t2], t3
 1452 loadi PayloadOffset[t0, t2], t2
 1453 storei t3, TagOffset[cfr, t1, 8]
 1454 storei t2, PayloadOffset[cfr, t1, 8]
 1455 loadi 32[PC], t1
 1456 valueProfile(t3, t2, t1)
 1457 dispatch(9)
 1458
 1459.opGetByIdSlow:
 1460 callHelper(_llint_helper_get_by_id)
 1461 dispatch(9)
 1462
 1463
 1464_llint_op_get_arguments_length:
 1465 traceExecution()
 1466 loadi 8[PC], t0
 1467 loadi 4[PC], t1
 1468 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
 1469 loadi ArgumentCount + PayloadOffset[cfr], t2
 1470 subi 1, t2
 1471 storei Int32Tag, TagOffset[cfr, t1, 8]
 1472 storei t2, PayloadOffset[cfr, t1, 8]
 1473 dispatch(4)
 1474
 1475.opGetArgumentsLengthSlow:
 1476 callHelper(_llint_helper_get_arguments_length)
 1477 dispatch(4)
 1478
 1479
 1480_llint_op_put_by_id:
 1481 traceExecution()
 1482 loadi 4[PC], t3
 1483 loadi 16[PC], t1
 1484 loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
 1485 loadi 12[PC], t2
 1486 loadp JSObject::m_propertyStorage[t0], t3
 1487 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
 1488 loadi 20[PC], t1
 1489 loadConstantOrVariable2Reg(t2, t0, t2)
 1490 writeBarrier(t0, t2)
 1491 storei t0, TagOffset[t3, t1]
 1492 storei t2, PayloadOffset[t3, t1]
 1493 dispatch(9)
 1494
 1495.opPutByIdSlow:
 1496 callHelper(_llint_helper_put_by_id)
 1497 dispatch(9)
 1498
 1499
 1500macro putByIdTransition(additionalChecks)
 1501 traceExecution()
 1502 loadi 4[PC], t3
 1503 loadi 16[PC], t1
 1504 loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
 1505 loadi 12[PC], t2
 1506 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
 1507 additionalChecks(t1, t3, .opPutByIdSlow)
 1508 loadi 20[PC], t1
 1509 loadp JSObject::m_propertyStorage[t0], t3
 1510 addp t1, t3
 1511 loadConstantOrVariable2Reg(t2, t1, t2)
 1512 writeBarrier(t1, t2)
 1513 storei t1, TagOffset[t3]
 1514 loadi 24[PC], t1
 1515 storei t2, PayloadOffset[t3]
 1516 storep t1, JSCell::m_structure[t0]
 1517 dispatch(9)
 1518end
 1519
 1520_llint_op_put_by_id_transition_direct:
 1521 putByIdTransition(macro (oldStructure, scratch, slow) end)
 1522
 1523
 1524_llint_op_put_by_id_transition_normal:
 1525 putByIdTransition(
 1526 macro (oldStructure, scratch, slow)
 1527 const protoCell = oldStructure # Reusing the oldStructure register for the proto
 1528
 1529 loadp 28[PC], scratch
 1530 assert(macro (ok) btpnz scratch, ok end)
 1531 loadp StructureChain::m_vector[scratch], scratch
 1532 assert(macro (ok) btpnz scratch, ok end)
 1533 bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
 1534 .loop:
 1535 loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
 1536 loadp JSCell::m_structure[protoCell], oldStructure
 1537 bpneq oldStructure, [scratch], slow
 1538 addp 4, scratch
 1539 bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
 1540 .done:
 1541 end)
 1542
 1543
 1544_llint_op_del_by_id:
 1545 traceExecution()
 1546 callHelper(_llint_helper_del_by_id)
 1547 dispatch(4)
 1548
 1549
 1550_llint_op_get_by_val:
 1551 traceExecution()
 1552 loadp CodeBlock[cfr], t1
 1553 loadi 8[PC], t2
 1554 loadi 12[PC], t3
 1555 loadp CodeBlock::m_globalData[t1], t1
 1556 loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
 1557 loadp JSGlobalData::jsArrayClassInfo[t1], t2
 1558 loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
 1559 bpneq [t0], t2, .opGetByValSlow
 1560 loadp JSArray::m_storage[t0], t3
 1561 biaeq t1, JSArray::m_vectorLength[t0], .opGetByValSlow
 1562 loadi 4[PC], t0
 1563 loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
 1564 loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
 1565 bieq t2, EmptyValueTag, .opGetByValSlow
 1566 storei t2, TagOffset[cfr, t0, 8]
 1567 storei t1, PayloadOffset[cfr, t0, 8]
 1568 loadi 16[PC], t0
 1569 valueProfile(t2, t1, t0)
 1570 dispatch(5)
 1571
 1572.opGetByValSlow:
 1573 callHelper(_llint_helper_get_by_val)
 1574 dispatch(5)
 1575
 1576
 1577_llint_op_get_argument_by_val:
 1578 traceExecution()
 1579 loadi 8[PC], t0
 1580 loadi 12[PC], t1
 1581 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
 1582 loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
 1583 addi 1, t2
 1584 loadi ArgumentCount + PayloadOffset[cfr], t1
 1585 biaeq t2, t1, .opGetArgumentByValSlow
 1586 negi t2
 1587 loadi 4[PC], t3
 1588 loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
 1589 loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1
 1590 storei t0, TagOffset[cfr, t3, 8]
 1591 storei t1, PayloadOffset[cfr, t3, 8]
 1592 dispatch(4)
 1593
 1594.opGetArgumentByValSlow:
 1595 callHelper(_llint_helper_get_argument_by_val)
 1596 dispatch(4)
 1597
 1598
 1599_llint_op_get_by_pname:
 1600 traceExecution()
 1601 loadi 12[PC], t0
 1602 loadConstantOrVariablePayload(t0, CellTag, t1, .opGetByPnameSlow)
 1603 loadi 16[PC], t0
 1604 bpneq t1, PayloadOffset[cfr, t0, 8], .opGetByPnameSlow
 1605 loadi 8[PC], t0
 1606 loadConstantOrVariablePayload(t0, CellTag, t2, .opGetByPnameSlow)
 1607 loadi 20[PC], t0
 1608 loadi PayloadOffset[cfr, t0, 8], t3
 1609 loadp JSCell::m_structure[t2], t0
 1610 bpneq t0, JSPropertyNameIterator::m_cachedStructure[t3], .opGetByPnameSlow
 1611 loadi 24[PC], t0
 1612 loadi [cfr, t0, 8], t0
 1613 subi 1, t0
 1614 biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow
 1615 loadp JSObject::m_propertyStorage[t2], t2
 1616 loadi TagOffset[t2, t0, 8], t1
 1617 loadi PayloadOffset[t2, t0, 8], t3
 1618 loadi 4[PC], t0
 1619 storei t1, TagOffset[cfr, t0, 8]
 1620 storei t3, PayloadOffset[cfr, t0, 8]
 1621 dispatch(7)
 1622
 1623.opGetByPnameSlow:
 1624 callHelper(_llint_helper_get_by_pname)
 1625 dispatch(7)
 1626
 1627
 1628_llint_op_put_by_val:
 1629 traceExecution()
 1630 loadi 4[PC], t0
 1631 loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
 1632 loadi 8[PC], t0
 1633 loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
 1634 loadp CodeBlock[cfr], t0
 1635 loadp CodeBlock::m_globalData[t0], t0
 1636 loadp JSGlobalData::jsArrayClassInfo[t0], t0
 1637 bpneq [t1], t0, .opPutByValSlow
 1638 biaeq t2, JSArray::m_vectorLength[t1], .opPutByValSlow
 1639 loadp JSArray::m_storage[t1], t0
 1640 bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
 1641.opPutByValStoreResult:
 1642 loadi 12[PC], t3
 1643 loadConstantOrVariable2Reg(t3, t1, t3)
 1644 writeBarrier(t1, t3)
 1645 storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8]
 1646 storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8]
 1647 dispatch(4)
 1648
 1649.opPutByValEmpty:
 1650 addi 1, ArrayStorage::m_numValuesInVector[t0]
 1651 bib t2, ArrayStorage::m_length[t0], .opPutByValStoreResult
 1652 addi 1, t2, t1
 1653 storei t1, ArrayStorage::m_length[t0]
 1654 jmp .opPutByValStoreResult
 1655
 1656.opPutByValSlow:
 1657 callHelper(_llint_helper_put_by_val)
 1658 dispatch(4)
 1659
 1660
 1661_llint_op_del_by_val:
 1662 traceExecution()
 1663 callHelper(_llint_helper_del_by_val)
 1664 dispatch(4)
 1665
 1666
 1667_llint_op_put_by_index:
 1668 traceExecution()
 1669 callHelper(_llint_helper_put_by_index)
 1670 dispatch(4)
 1671
 1672
 1673_llint_op_put_getter_setter:
 1674 traceExecution()
 1675 callHelper(_llint_helper_put_getter_setter)
 1676 dispatch(5)
 1677
 1678
 1679_llint_op_loop:
 1680 nop
 1681_llint_op_jmp:
 1682 traceExecution()
 1683 dispatchBranch(4[PC])
 1684
 1685
 1686_llint_op_jmp_scopes:
 1687 traceExecution()
 1688 callHelper(_llint_helper_jmp_scopes)
 1689 dispatch(0)
 1690
 1691
 1692macro jumpTrueOrFalse(conditionOp, slow)
 1693 loadi 4[PC], t1
 1694 loadConstantOrVariablePayload(t1, BooleanTag, t0, .slow)
 1695 conditionOp(t0, .target)
 1696 dispatch(3)
 1697
 1698.target:
 1699 dispatchBranch(8[PC])
 1700
 1701.slow:
 1702 callHelper(slow)
 1703 dispatch(0)
 1704end
 1705
 1706_llint_op_loop_if_true:
 1707 nop
 1708_llint_op_jtrue:
 1709 traceExecution()
 1710 jumpTrueOrFalse(
 1711 macro (value, target) btinz value, target end,
 1712 _llint_helper_jtrue)
 1713
 1714
 1715_llint_op_loop_if_false:
 1716 nop
 1717_llint_op_jfalse:
 1718 traceExecution()
 1719 jumpTrueOrFalse(
 1720 macro (value, target) btiz value, target end,
 1721 _llint_helper_jfalse)
 1722
 1723
 1724macro equalNull(cellHandler, immediateHandler)
 1725 loadi 4[PC], t0
 1726 loadi TagOffset[cfr, t0, 8], t1
 1727 loadi PayloadOffset[cfr, t0, 8], t0
 1728 bineq t1, CellTag, .immediate
 1729 loadp JSCell::m_structure[t0], t2
 1730 cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
 1731 dispatch(3)
 1732
 1733.target:
 1734 dispatchBranch(8[PC])
 1735
 1736.immediate:
 1737 ori 1, t1
 1738 immediateHandler(t1, .target)
 1739 dispatch(3)
 1740end
 1741
 1742_llint_op_jeq_null:
 1743 traceExecution()
 1744 equalNull(
 1745 macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
 1746 macro (value, target) bieq value, NullTag, target end)
 1747
 1748
 1749_llint_op_jneq_null:
 1750 traceExecution()
 1751 equalNull(
 1752 macro (value, target) btbz value, MasqueradesAsUndefined, target end,
 1753 macro (value, target) bineq value, NullTag, target end)
 1754
 1755
 1756_llint_op_jneq_ptr:
 1757 traceExecution()
 1758 loadi 4[PC], t0
 1759 loadi 8[PC], t1
 1760 bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
 1761 bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
 1762.opJneqPtrBranch:
 1763 dispatchBranch(12[PC])
 1764.opJneqPtrFallThrough:
 1765 dispatch(4)
 1766
 1767
 1768macro compare(integerCompare, doubleCompare, helper)
 1769 loadi 4[PC], t2
 1770 loadi 8[PC], t3
 1771 loadConstantOrVariable(t2, t0, t1)
 1772 loadConstantOrVariable2Reg(t3, t2, t3)
 1773 bineq t0, Int32Tag, .op1NotInt
 1774 bineq t2, Int32Tag, .op2NotInt
 1775 integerCompare(t1, t3, .jumpTarget)
 1776 dispatch(4)
 1777
 1778.op1NotInt:
 1779 bia t0, LowestTag, .slow
 1780 bib t2, LowestTag, .op1NotIntOp2Double
 1781 bineq t2, Int32Tag, .slow
 1782 ci2d t3, ft1
 1783 jmp .op1NotIntReady
 1784.op1NotIntOp2Double:
 1785 fii2d t3, t2, ft1
 1786.op1NotIntReady:
 1787 fii2d t1, t0, ft0
 1788 doubleCompare(ft0, ft1, .jumpTarget)
 1789 dispatch(4)
 1790
 1791.op2NotInt:
 1792 ci2d t1, ft0
 1793 bia t2, LowestTag, .slow
 1794 fii2d t3, t2, ft1
 1795 doubleCompare(ft0, ft1, .jumpTarget)
 1796 dispatch(4)
 1797
 1798.jumpTarget:
 1799 dispatchBranch(12[PC])
 1800
 1801.slow:
 1802 callHelper(helper)
 1803 dispatch(0)
 1804end
 1805
 1806_llint_op_loop_if_less:
 1807 nop
 1808_llint_op_jless:
 1809 traceExecution()
 1810 compare(
 1811 macro (left, right, target) bilt left, right, target end,
 1812 macro (left, right, target) bdlt left, right, target end,
 1813 _llint_helper_jless)
 1814
 1815
 1816_llint_op_jnless:
 1817 traceExecution()
 1818 compare(
 1819 macro (left, right, target) bigteq left, right, target end,
 1820 macro (left, right, target) bdgtequn left, right, target end,
 1821 _llint_helper_jnless)
 1822
 1823
 1824_llint_op_loop_if_greater:
 1825 nop
 1826_llint_op_jgreater:
 1827 traceExecution()
 1828 compare(
 1829 macro (left, right, target) bigt left, right, target end,
 1830 macro (left, right, target) bdgt left, right, target end,
 1831 _llint_helper_jgreater)
 1832
 1833
 1834_llint_op_jngreater:
 1835 traceExecution()
 1836 compare(
 1837 macro (left, right, target) bilteq left, right, target end,
 1838 macro (left, right, target) bdltequn left, right, target end,
 1839 _llint_helper_jngreater)
 1840
 1841
 1842_llint_op_loop_if_lesseq:
 1843 nop
 1844_llint_op_jlesseq:
 1845 traceExecution()
 1846 compare(
 1847 macro (left, right, target) bilteq left, right, target end,
 1848 macro (left, right, target) bdlteq left, right, target end,
 1849 _llint_helper_jlesseq)
 1850
 1851
 1852_llint_op_jnlesseq:
 1853 traceExecution()
 1854 compare(
 1855 macro (left, right, target) bigt left, right, target end,
 1856 macro (left, right, target) bdgtun left, right, target end,
 1857 _llint_helper_jnlesseq)
 1858
 1859
 1860_llint_op_loop_if_greatereq:
 1861 nop
 1862_llint_op_jgreatereq:
 1863 traceExecution()
 1864 compare(
 1865 macro (left, right, target) bigteq left, right, target end,
 1866 macro (left, right, target) bdgteq left, right, target end,
 1867 _llint_helper_jgreatereq)
 1868
 1869
 1870_llint_op_jngreatereq:
 1871 traceExecution()
 1872 compare(
 1873 macro (left, right, target) bilt left, right, target end,
 1874 macro (left, right, target) bdltun left, right, target end,
 1875 _llint_helper_jngreatereq)
 1876
 1877
 1878_llint_op_loop_hint:
 1879 traceExecution()
 1880 checkSwitchToJITForLoop()
 1881 dispatch(1)
 1882
 1883
 1884_llint_op_switch_imm:
 1885 traceExecution()
 1886 loadi 12[PC], t2
 1887 loadi 4[PC], t3
 1888 loadConstantOrVariable(t2, t1, t0)
 1889 loadp CodeBlock[cfr], t2
 1890 loadp CodeBlock::m_rareData[t2], t2
 1891 muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
 1892 loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
 1893 addp t3, t2
 1894 bineq t1, Int32Tag, .opSwitchImmNotInt
 1895 subi SimpleJumpTable::min[t2], t0
 1896 biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
 1897 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
 1898 loadi [t3, t0, 4], t1
 1899 btiz t1, .opSwitchImmFallThrough
 1900 dispatchBranchWithOffset(t1)
 1901
 1902.opSwitchImmNotInt:
 1903 bib t1, LowestTag, .opSwitchImmSlow # Go to slow path if it's a double.
 1904.opSwitchImmFallThrough:
 1905 dispatchBranch(8[PC])
 1906
 1907.opSwitchImmSlow:
 1908 callHelper(_llint_helper_switch_imm)
 1909 dispatch(0)
 1910
 1911
 1912_llint_op_switch_char:
 1913 traceExecution()
 1914 loadi 12[PC], t2
 1915 loadi 4[PC], t3
 1916 loadConstantOrVariable(t2, t1, t0)
 1917 loadp CodeBlock[cfr], t2
 1918 loadp CodeBlock::m_rareData[t2], t2
 1919 muli sizeof SimpleJumpTable, t3
 1920 loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
 1921 addp t3, t2
 1922 bineq t1, CellTag, .opSwitchCharFallThrough
 1923 loadp JSCell::m_structure[t0], t1
 1924 bbneq Structure::m_typeInfo + TypeInfo::m_type[t1], StringType, .opSwitchCharFallThrough
 1925 loadp JSString::m_value[t0], t0
 1926 bineq StringImpl::m_length[t0], 1, .opSwitchCharFallThrough
 1927 loadp StringImpl::m_data8[t0], t1
 1928 btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
 1929 loadh [t1], t0
 1930 jmp .opSwitchCharReady
 1931.opSwitchChar8Bit:
 1932 loadb [t1], t0
 1933.opSwitchCharReady:
 1934 subi SimpleJumpTable::min[t2], t0
 1935 biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
 1936 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
 1937 loadi [t2, t0, 4], t1
 1938 btiz t1, .opSwitchImmFallThrough
 1939 dispatchBranchWithOffset(t1)
 1940
 1941.opSwitchCharFallThrough:
 1942 dispatchBranch(8[PC])
 1943
 1944
 1945_llint_op_switch_string:
 1946 traceExecution()
 1947 callHelper(_llint_helper_switch_string)
 1948 dispatch(0)
 1949
 1950
 1951_llint_op_new_func:
 1952 traceExecution()
 1953 btiz 12[PC], .opNewFuncUnchecked
 1954 loadi 4[PC], t1
 1955 bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
 1956.opNewFuncUnchecked:
 1957 callHelper(_llint_helper_new_func)
 1958.opNewFuncDone:
 1959 dispatch(4)
 1960
 1961
 1962_llint_op_new_func_exp:
 1963 traceExecution()
 1964 callHelper(_llint_helper_new_func_exp)
 1965 dispatch(3)
 1966
 1967
 1968macro doCall(helper)
 1969 loadi 4[PC], t0
 1970 loadi 16[PC], t1
 1971 loadp LLIntCallLinkInfo::callee[t1], t2
 1972 loadConstantOrVariablePayload(t0, CellTag, t3, .opCallSlow)
 1973 bineq t3, t2, .opCallSlow
 1974 loadi 12[PC], t3
 1975 addp 24, PC
 1976 lshifti 3, t3
 1977 addp cfr, t3 # t3 contains the new value of cfr
 1978 loadp JSFunction::m_scopeChain[t2], t0
 1979 storei t2, Callee + PayloadOffset[t3]
 1980 storei t0, ScopeChain + PayloadOffset[t3]
 1981 loadi 8 - 24[PC], t2
 1982 storei PC, ArgumentCount + TagOffset[cfr]
 1983 storep cfr, CallerFrame[t3]
 1984 storei t2, ArgumentCount + PayloadOffset[t3]
 1985 storei CellTag, Callee + TagOffset[t3]
 1986 storei CellTag, ScopeChain + TagOffset[t3]
 1987 move t3, cfr
 1988 call LLIntCallLinkInfo::machineCodeTarget[t1]
 1989 dispatchAfterCall()
 1990
 1991.opCallSlow:
 1992 slowPathForCall(6, helper)
 1993end
 1994
 1995_llint_op_call:
 1996 traceExecution()
 1997 doCall(_llint_helper_call)
 1998
 1999
 2000_llint_op_construct:
 2001 traceExecution()
 2002 doCall(_llint_helper_construct)
 2003
 2004
 2005_llint_op_call_varargs:
 2006 traceExecution()
 2007 slowPathForCall(6, _llint_helper_call_varargs)
 2008
 2009
 2010_llint_op_call_eval:
 2011 traceExecution()
 2012
 2013 # Eval is executed in one of two modes:
 2014 #
 2015 # 1) We find that we're really invoking eval() in which case the
 2016 # execution is perfomed entirely inside the helper, and it
 2017 # returns the PC of a function that just returns the return value
 2018 # that the eval returned.
 2019 #
 2020 # 2) We find that we're invoking something called eval() that is not
 2021 # the real eval. Then the helper returns the PC of the thing to
 2022 # call, and we call it.
 2023 #
 2024 # This allows us to handle two cases, which would require a total of
 2025 # up to four pieces of state that cannot be easily packed into two
 2026 # registers (C functions can return up to two registers, easily):
 2027 #
 2028 # - The call frame register. This may or may not have been modified
 2029 # by the helper, but the convention is that it returns it. It's not
 2030 # totally clear if that's necessary, since the cfr is callee save.
 2031 # But that's our style in this here interpreter so we stick with it.
 2032 #
 2033 # - A bit to say if the helper successfully executed the eval and has
 2034 # the return value, or did not execute the eval but has a PC for us
 2035 # to call.
 2036 #
 2037 # - Either:
 2038 # - The JS return value (two registers), or
 2039 #
 2040 # - The PC to call.
 2041 #
 2042 # It turns out to be easier to just always have this return the cfr
 2043 # and a PC to call, and that PC may be a dummy thunk that just
 2044 # returns the JS value that the eval returned.
 2045
 2046 slowPathForCall(4, _llint_helper_call_eval)
 2047
 2048
 2049_llint_generic_return_point:
 2050 dispatchAfterCall()
 2051
 2052
 2053_llint_op_tear_off_activation:
 2054 traceExecution()
 2055 loadi 4[PC], t0
 2056 loadi 8[PC], t1
 2057 bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationCreated
 2058 bieq TagOffset[cfr, t1, 8], EmptyValueTag, .opTearOffActivationNotCreated
 2059.opTearOffActivationCreated:
 2060 callHelper(_llint_helper_tear_off_activation)
 2061.opTearOffActivationNotCreated:
 2062 dispatch(3)
 2063
 2064
 2065_llint_op_tear_off_arguments:
 2066 traceExecution()
 2067 loadi 4[PC], t0
 2068 subi 1, t0 # Get the unmodifiedArgumentsRegister
 2069 bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
 2070 callHelper(_llint_helper_tear_off_arguments)
 2071.opTearOffArgumentsNotCreated:
 2072 dispatch(2)
 2073
 2074
 2075macro doReturn()
 2076 loadp ReturnPC[cfr], t2
 2077 loadp CallerFrame[cfr], cfr
 2078 restoreReturnAddressBeforeReturn(t2)
 2079 ret
 2080end
 2081
 2082_llint_op_ret:
 2083 traceExecution()
 2084 checkSwitchToJITForEpilogue()
 2085 loadi 4[PC], t2
 2086 loadConstantOrVariable(t2, t1, t0)
 2087 doReturn()
 2088
 2089
 2090_llint_op_call_put_result:
 2091 loadi 4[PC], t2
 2092 loadi 8[PC], t3
 2093 storei t1, TagOffset[cfr, t2, 8]
 2094 storei t0, PayloadOffset[cfr, t2, 8]
 2095 valueProfile(t1, t0, t3)
 2096 traceExecution() # Needs to be here because it would clobber t1, t0
 2097 dispatch(3)
 2098
 2099
 2100_llint_op_ret_object_or_this:
 2101 traceExecution()
 2102 checkSwitchToJITForEpilogue()
 2103 loadi 4[PC], t2
 2104 loadConstantOrVariable(t2, t1, t0)
 2105 bineq t1, CellTag, .opRetObjectOrThisNotObject
 2106 loadp JSCell::m_structure[t0], t2
 2107 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
 2108 doReturn()
 2109
 2110.opRetObjectOrThisNotObject:
 2111 loadi 8[PC], t2
 2112 loadConstantOrVariable(t2, t1, t0)
 2113 doReturn()
 2114
 2115
 2116_llint_op_method_check:
 2117 traceExecution()
 2118 # We ignore method checks and use normal get_by_id optimizations.
 2119 dispatch(1)
 2120
 2121
 2122_llint_op_strcat:
 2123 traceExecution()
 2124 callHelper(_llint_helper_strcat)
 2125 dispatch(4)
 2126
 2127
 2128_llint_op_to_primitive:
 2129 traceExecution()
 2130 loadi 8[PC], t2
 2131 loadi 4[PC], t3
 2132 loadConstantOrVariable(t2, t1, t0)
 2133 bineq t1, CellTag, .opToPrimitiveIsImm
 2134 loadp JSCell::m_structure[t0], t2
 2135 bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
 2136.opToPrimitiveIsImm:
 2137 storei t1, TagOffset[cfr, t3, 8]
 2138 storei t0, PayloadOffset[cfr, t3, 8]
 2139 dispatch(3)
 2140
 2141.opToPrimitiveSlowCase:
 2142 callHelper(_llint_helper_to_primitive)
 2143 dispatch(3)
 2144
 2145
 2146_llint_op_get_pnames:
 2147 traceExecution()
 2148 callHelper(_llint_helper_get_pnames)
 2149 dispatch(0) # The helper either advances the PC or jumps us to somewhere else.
 2150
 2151
 2152_llint_op_next_pname:
 2153 traceExecution()
 2154 loadi 12[PC], t1
 2155 loadi 16[PC], t2
 2156 loadi PayloadOffset[cfr, t1, 8], t0
 2157 bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
 2158 loadi 20[PC], t2
 2159 loadi PayloadOffset[cfr, t2, 8], t2
 2160 loadp JSPropertyNameIterator::m_jsStrings[t2], t3
 2161 loadi [t3, t0, 8], t3
 2162 addi 1, t0
 2163 storei t0, PayloadOffset[cfr, t1, 8]
 2164 loadi 4[PC], t1
 2165 storei CellTag, TagOffset[cfr, t1, 8]
 2166 storei t3, PayloadOffset[cfr, t1, 8]
 2167 loadi 8[PC], t3
 2168 loadi PayloadOffset[cfr, t3, 8], t3
 2169 loadp JSCell::m_structure[t3], t1
 2170 bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
 2171 loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
 2172 loadp StructureChain::m_vector[t0], t0
 2173 btpz [t0], .opNextPnameTarget
 2174.opNextPnameCheckPrototypeLoop:
 2175 bieq Structure::m_prototype + TagOffset[t1], NullTag, .opNextPnameSlow
 2176 loadp Structure::m_prototype + PayloadOffset[t1], t2
 2177 loadp JSCell::m_structure[t2], t1
 2178 bpneq t1, [t0], .opNextPnameSlow
 2179 addp 4, t0
 2180 btpnz [t0], .opNextPnameCheckPrototypeLoop
 2181.opNextPnameTarget:
 2182 dispatchBranch(24[PC])
 2183
 2184.opNextPnameEnd:
 2185 dispatch(7)
 2186
 2187.opNextPnameSlow:
 2188 callHelper(_llint_helper_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
 2189 dispatch(0)
 2190
 2191
 2192_llint_op_push_scope:
 2193 traceExecution()
 2194 callHelper(_llint_helper_push_scope)
 2195 dispatch(2)
 2196
 2197
 2198_llint_op_pop_scope:
 2199 traceExecution()
 2200 callHelper(_llint_helper_pop_scope)
 2201 dispatch(1)
 2202
 2203
 2204_llint_op_push_new_scope:
 2205 traceExecution()
 2206 callHelper(_llint_helper_push_new_scope)
 2207 dispatch(4)
 2208
 2209
 2210_llint_op_catch:
 2211 # This is where we end up from the JIT's throw trampoline (because the
 2212 # machine code return address will be set to _llint_op_catch), and from
 2213 # the interpreter's throw trampoline (see _llint_throw_trampoline).
 2214 # The JIT throwing protocol calls for the cfr to be in t0. The throwing
 2215 # code must have known that we were throwing to the interpreter, and have
 2216 # set JSGlobalData::targetInterpreterPCForThrow.
 2217 move t0, cfr
 2218 loadp JITStackFrame::globalData[sp], t3
 2219 loadi JSGlobalData::targetInterpreterPCForThrow[t3], PC
 2220 loadi JSGlobalData::exception + PayloadOffset[t3], t0
 2221 loadi JSGlobalData::exception + TagOffset[t3], t1
 2222 storei 0, JSGlobalData::exception + PayloadOffset[t3]
 2223 storei EmptyValueTag, JSGlobalData::exception + TagOffset[t3]
 2224 loadi 4[PC], t2
 2225 storei t0, PayloadOffset[cfr, t2, 8]
 2226 storei t1, TagOffset[cfr, t2, 8]
 2227 traceExecution() # This needs to be here because we don't want to clobber t0, t1, t2, t3 above.
 2228 dispatch(2)
 2229
 2230
 2231_llint_op_throw:
 2232 traceExecution()
 2233 callHelper(_llint_helper_throw)
 2234 dispatch(2)
 2235
 2236
 2237_llint_op_throw_reference_error:
 2238 traceExecution()
 2239 callHelper(_llint_helper_throw_reference_error)
 2240 dispatch(2)
 2241
 2242
 2243_llint_op_jsr:
 2244 traceExecution()
 2245 loadi 4[PC], t0
 2246 addi 3 * 4, PC, t1
 2247 storei t1, [cfr, t0, 8]
 2248 dispatchBranch(8[PC])
 2249
 2250
 2251_llint_op_sret:
 2252 traceExecution()
 2253 loadi 4[PC], t0
 2254 loadp [cfr, t0, 8], PC
 2255 dispatch(0)
 2256
 2257
 2258_llint_op_debug:
 2259 traceExecution()
 2260 callHelper(_llint_helper_debug)
 2261 dispatch(4)
 2262
 2263
 2264_llint_op_profile_will_call:
 2265 traceExecution()
 2266 loadp JITStackFrame::enabledProfilerReference[sp], t0
 2267 btpz [t0], .opProfileWillCallDone
 2268 callHelper(_llint_helper_profile_will_call)
 2269.opProfileWillCallDone:
 2270 dispatch(2)
 2271
 2272
 2273_llint_op_profile_did_call:
 2274 traceExecution()
 2275 loadp JITStackFrame::enabledProfilerReference[sp], t0
 2276 btpz [t0], .opProfileWillCallDone
 2277 callHelper(_llint_helper_profile_did_call)
 2278.opProfileDidCallDone:
 2279 dispatch(2)
 2280
 2281
 2282_llint_op_end:
 2283 traceExecution()
 2284 checkSwitchToJITForEpilogue()
 2285 loadi 4[PC], t0
 2286 loadi TagOffset[cfr, t0, 8], t1
 2287 loadi PayloadOffset[cfr, t0, 8], t0
 2288 doReturn()
 2289
 2290
 2291_llint_throw_from_helper_trampoline:
 2292 # When throwing from the interpreter (i.e. throwing from LLIntHelpers), so
 2293 # the throw target is not necessarily interpreted code, we come to here.
 2294 # This essentially emulates the JIT's throwing protocol.
 2295 loadp JITStackFrame::globalData[sp], t1
 2296 loadp JSGlobalData::callFrameForThrow[t1], t0
 2297 jmp JSGlobalData::targetMachinePCForThrow[t1]
 2298
 2299
 2300_llint_throw_during_call_trampoline:
 2301 preserveReturnAddressAfterCall(t2)
 2302 loadp JITStackFrame::globalData[sp], t1
 2303 loadp JSGlobalData::callFrameForThrow[t1], t0
 2304 jmp JSGlobalData::targetMachinePCForThrow[t1]
 2305
 2306
 2307# Lastly, make sure that we can link even though we don't support all opcodes.
 2308# These opcodes should never arise when using LLInt or either JIT. We assert
 2309# as much.
 2310
 2311macro notSupported()
 2312 if ASSERT_ENABLED
 2313 crash()
 2314 else
 2315 # We should use whatever the smallest possible instruction is, just to
 2316 # ensure that there is a gap between instruction labels. If multiple
 2317 # smallest instructions exist, we should pick the one that is most
 2318 # likely result in execution being halted. Currently that is the break
 2319 # instruction on all architectures we're interested in. (Break is int3
 2320 # on Intel, which is 1 byte, and bkpt on ARMv7, which is 2 bytes.)
 2321 break
 2322 end
 2323end
 2324
 2325_llint_op_get_array_length:
 2326 notSupported()
 2327
 2328_llint_op_get_by_id_chain:
 2329 notSupported()
 2330
 2331_llint_op_get_by_id_custom_chain:
 2332 notSupported()
 2333
 2334_llint_op_get_by_id_custom_proto:
 2335 notSupported()
 2336
 2337_llint_op_get_by_id_custom_self:
 2338 notSupported()
 2339
 2340_llint_op_get_by_id_generic:
 2341 notSupported()
 2342
 2343_llint_op_get_by_id_getter_chain:
 2344 notSupported()
 2345
 2346_llint_op_get_by_id_getter_proto:
 2347 notSupported()
 2348
 2349_llint_op_get_by_id_getter_self:
 2350 notSupported()
 2351
 2352_llint_op_get_by_id_proto:
 2353 notSupported()
 2354
 2355_llint_op_get_by_id_self:
 2356 notSupported()
 2357
 2358_llint_op_get_string_length:
 2359 notSupported()
 2360
 2361_llint_op_put_by_id_generic:
 2362 notSupported()
 2363
 2364_llint_op_put_by_id_replace:
 2365 notSupported()
 2366
 2367_llint_op_put_by_id_transition:
 2368 notSupported()
 2369
 2370
 2371# Indicate the end of LLInt.
 2372_llint_end:
 2373 crash()
 2374
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#include <wtf/InlineASM.h>
 33
 34// This is a file generated by offlineasm, which contains all of the assembly code
 35// for the interpreter, as compiled from LowLevelInterpreter.asm.
 36#include "LLIntAssembly.h"
 37
 38#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
 24require "ast"
 25require "opt"
 26
 27class NoChildren
 28 def armV7Single
 29 doubleOperand = armV7Operand
 30 raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^d/
 31 "s" + ($~.post_match.to_i * 2).to_s
 32 end
 33end
 34
 35class SpecialRegister < NoChildren
 36 def initialize(name)
 37 @name = name
 38 end
 39
 40 def armV7Operand
 41 @name
 42 end
 43
 44 def address?
 45 false
 46 end
 47
 48 def label?
 49 false
 50 end
 51
 52 def immediate?
 53 false
 54 end
 55
 56 def register?
 57 true
 58 end
 59end
 60
 61ARMv7_EXTRA_GPRS = [SpecialRegister.new("r3"), SpecialRegister.new("r8"), SpecialRegister.new("r9")]
 62ARMv7_EXTRA_FPRS = [SpecialRegister.new("d7")]
 63ARMv7_SCRATCH_FPR = SpecialRegister.new("d8")
 64
 65def armV7MoveImmediate(value, register)
 66 # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
 67 if value >= 0 && value < 256
 68 $asm.puts "movw #{register.armV7Operand}, \##{value}"
 69 elsif (~value) >= 0 && (~value) < 256
 70 $asm.puts "mvn #{register.armV7Operand}, \##{~value}"
 71 else
 72 $asm.puts "movw #{register.armV7Operand}, \##{value & 0xffff}"
 73 if (value & 0xffff0000) != 0
 74 $asm.puts "movt #{register.armV7Operand}, \##{value >> 16}"
 75 end
 76 end
 77end
 78
 79class RegisterID
 80 def armV7Operand
 81 case name
 82 when "t0", "a0", "r0"
 83 "r0"
 84 when "t1", "a1", "r1"
 85 "r1"
 86 when "t2", "a2"
 87 "r2"
 88 when "a3"
 89 "r3"
 90 when "t3"
 91 "r4"
 92 when "t4"
 93 "r7"
 94 when "cfr"
 95 "r5"
 96 when "lr"
 97 "lr"
 98 when "sp"
 99 "sp"
 100 else
 101 raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
 102 end
 103 end
 104end
 105
 106class FPRegisterID
 107 def armV7Operand
 108 case name
 109 when "ft0", "fr"
 110 "d0"
 111 when "ft1"
 112 "d1"
 113 when "ft2"
 114 "d2"
 115 when "ft3"
 116 "d3"
 117 when "ft4"
 118 "d4"
 119 when "ft5"
 120 "d5"
 121 else
 122 raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
 123 end
 124 end
 125end
 126
 127class Immediate
 128 def armV7Operand
 129 raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 255
 130 "\##{value}"
 131 end
 132end
 133
 134class Address
 135 def armV7Operand
 136 raise "Bad offset at #{codeOriginString}" if offset.value < -0xff or offset.value > 0xfff
 137 "[#{base.armV7Operand}, \##{offset.value}]"
 138 end
 139end
 140
 141class BaseIndex
 142 def armV7Operand
 143 raise "Bad offset at #{codeOriginString}" if offset.value != 0
 144 case scale
 145 when 1
 146 scaleShift = 0
 147 when 2
 148 scaleShift = 1
 149 when 4
 150 scaleShift = 2
 151 when 8
 152 scaleShift = 8
 153 else
 154 raise "Bad scale at #{codeOriginString}"
 155 end
 156 "[#{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scaleShift}]"
 157 end
 158end
 159
 160class AbsoluteAddress
 161 def armV7Operand
 162 raise "Unconverted absolute address at #{codeOriginString}"
 163 end
 164end
 165
 166#
 167# Lowering of branch ops. For example:
 168#
 169# baddiz foo, bar, baz
 170#
 171# will become:
 172#
 173# addi foo, bar
 174# bz baz
 175#
 176
 177def armV7LowerBranchOps(list)
 178 newList = []
 179 list.each {
 180 | node |
 181 if node.is_a? Instruction
 182 case node.opcode
 183 when /^b(addi|subi|ori|muli|addp)/
 184 op = $1
 185 branch = "b" + $~.post_match
 186 newList << Instruction.new(node.codeOrigin, op, node.operands[0..-2])
 187 newList << Instruction.new(node.codeOrigin, branch, [node.operands[-1]])
 188 else
 189 newList << node
 190 end
 191 else
 192 newList << node
 193 end
 194 }
 195 newList
 196end
 197
 198#
 199# Lowering of malformed addresses. For example:
 200#
 201# loadp 10000[foo], bar
 202#
 203# will become:
 204#
 205# move 10000, tmp
 206# addp foo, tmp
 207# loadp 0[tmp], bar
 208#
 209
 210class Node
 211 def armV7LowerMalformedAddressesRecurse(list)
 212 mapChildren {
 213 | node |
 214 node.armV7LowerMalformedAddressesRecurse(list)
 215 }
 216 end
 217end
 218
 219class Address
 220 def armV7LowerMalformedAddressesRecurse(list)
 221 if offset.value < -0xff or offset.value > 0xfff
 222 tmp = Tmp.new(codeOrigin, :gpr)
 223 list << Instruction.new(codeOrigin, "move", [offset, tmp])
 224 list << Instruction.new(codeOrigin, "addp", [base, tmp])
 225 Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
 226 else
 227 self
 228 end
 229 end
 230end
 231
 232class BaseIndex
 233 def armV7LowerMalformedAddressesRecurse(list)
 234 if offset.value != 0
 235 tmp = Tmp.new(codeOrigin, :gpr)
 236 list << Instruction.new(codeOrigin, "move", [offset, tmp])
 237 list << Instruction.new(codeOrigin, "addp", [base, tmp])
 238 BaseIndex.new(codeOrigin, tmp, index, scale, Immediate.new(codeOrigin, 0))
 239 else
 240 self
 241 end
 242 end
 243end
 244
 245class AbsoluteAddress
 246 def armV7LowerMalformedAddressesRecurse(list)
 247 tmp = Tmp.new(codeOrigin, :gpr)
 248 list << Instruction.new(codeOrigin, "move", [address, tmp])
 249 Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
 250 end
 251end
 252
 253def armV7LowerMalformedAddresses(list)
 254 newList = []
 255 list.each {
 256 | node |
 257 newList << node.armV7LowerMalformedAddressesRecurse(newList)
 258 }
 259 newList
 260end
 261
 262#
 263# Lowering of misplaced immediates. For example:
 264#
 265# storei 0, [foo]
 266#
 267# will become:
 268#
 269# move 0, tmp
 270# storei tmp, [foo]
 271#
 272
 273def armV7LowerMisplacedImmediates(list)
 274 newList = []
 275 list.each {
 276 | node |
 277 if node.is_a? Instruction
 278 case node.opcode
 279 when "storei", "storep"
 280 operands = node.operands
 281 newOperands = []
 282 operands.each {
 283 | operand |
 284 if operand.is_a? Immediate
 285 tmp = Tmp.new(operand.codeOrigin, :gpr)
 286 newList << Instruction.new(operand.codeOrigin, "move", [operand, tmp])
 287 newOperands << tmp
 288 else
 289 newOperands << operand
 290 end
 291 }
 292 newList << Instruction.new(node.codeOrigin, node.opcode, newOperands)
 293 else
 294 newList << node
 295 end
 296 else
 297 newList << node
 298 end
 299 }
 300 newList
 301end
 302
 303#
 304# Lowering of malformed immediates except when used in a "move" instruction.
 305# For example:
 306#
 307# addp 642641, foo
 308#
 309# will become:
 310#
 311# move 642641, tmp
 312# addp tmp, foo
 313#
 314
 315class Node
 316 def armV7LowerMalformedImmediatesRecurse(list)
 317 mapChildren {
 318 | node |
 319 node.armV7LowerMalformedImmediatesRecurse(list)
 320 }
 321 end
 322end
 323
 324class Address
 325 def armV7LowerMalformedImmediatesRecurse(list)
 326 self
 327 end
 328end
 329
 330class BaseIndex
 331 def armV7LowerMalformedImmediatesRecurse(list)
 332 self
 333 end
 334end
 335
 336class AbsoluteAddress
 337 def armV7LowerMalformedImmediatesRecurse(list)
 338 self
 339 end
 340end
 341
 342class Immediate
 343 def armV7LowerMalformedImmediatesRecurse(list)
 344 if value < 0 or value > 255
 345 tmp = Tmp.new(codeOrigin, :gpr)
 346 list << Instruction.new(codeOrigin, "move", [self, tmp])
 347 tmp
 348 else
 349 self
 350 end
 351 end
 352end
 353
 354def armV7LowerMalformedImmediates(list)
 355 newList = []
 356 list.each {
 357 | node |
 358 if node.is_a? Instruction
 359 case node.opcode
 360 when "move"
 361 newList << node
 362 when "addi", "addp", "subi", "subp"
 363 if node.operands[0].is_a? Immediate and
 364 node.operands[0].value < 0 and
 365 node.operands[0].value >= 255
 366 if node.opcode =~ /add/
 367 newOpcode = "sub" + node.opcode[-1..-1]
 368 else
 369 newOpcode = "add" + node.opcode[-1..-1]
 370 end
 371 newList << Instruction.new(node.codeOrigin, newOpcode,
 372 [Immediate.new(-node.operands[0].value)] + node.operands[1..-1])
 373 else
 374 newList << node.armV7LowerMalformedImmediatesRecurse(newList)
 375 end
 376 when "muli"
 377 if node.operands[0].is_a? Immediate
 378 tmp = Tmp.new(codeOrigin, :gpr)
 379 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
 380 newList << Instruction.new(node.codeOrigin, "muli", [tmp] + node.operands[1..-1])
 381 else
 382 newList << node.armV7LowerMalformedImmediatesRecurse(newList)
 383 end
 384 else
 385 newList << node.armV7LowerMalformedImmediatesRecurse(newList)
 386 end
 387 else
 388 newList << node
 389 end
 390 }
 391 newList
 392end
 393
 394#
 395# Lowering of misplaced addresses. For example:
 396#
 397# addi foo, [bar]
 398#
 399# will become:
 400#
 401# loadi [bar], tmp
 402# addi foo, tmp
 403# storei tmp, [bar]
 404#
 405# Another example:
 406#
 407# addi [foo], bar
 408#
 409# will become:
 410#
 411# loadi [foo], tmp
 412# addi tmp, bar
 413#
 414
 415def armV7AsRegister(preList, postList, operand, suffix, needStore)
 416 return operand unless operand.address?
 417
 418 tmp = Tmp.new(operand.codeOrigin, if suffix == "d" then :fpr else :gpr end)
 419 preList << Instruction.new(operand.codeOrigin, "load" + suffix, [operand, tmp])
 420 if needStore
 421 postList << Instruction.new(operand.codeOrigin, "store" + suffix, [tmp, operand])
 422 end
 423 tmp
 424end
 425
 426def armV7AsRegisters(preList, postList, operands, suffix)
 427 newOperands = []
 428 operands.each_with_index {
 429 | operand, index |
 430 newOperands << armV7AsRegister(preList, postList, operand, suffix, index == operands.size - 1)
 431 }
 432 newOperands
 433end
 434
 435def armV7LowerMisplacedAddresses(list)
 436 newList = []
 437 list.each {
 438 | node |
 439 if node.is_a? Instruction
 440 postInstructions = []
 441 case node.opcode
 442 when "addi", "addp", "andi", "andp", "lshifti", "muli", "negi", "noti", "ori", "orp", "rshifti",
 443 "urshifti", "subi", "subp", "xori", "xorp", /^bi/, /^bp/, /^bti/, /^btp/, "call", /^ci/, /^cp/,
 444 /^ti/
 445 newList << Instruction.new(node.codeOrigin,
 446 node.opcode,
 447 armV7AsRegisters(newList, postInstructions, node.operands, "i"))
 448 when "bbeq", "bbneq", "bba", "bbaeq", "bbb", "bbbeq", "btbo", "btbz", "btbnz", "tbz", "tbnz",
 449 "tbo"
 450 newList << Instruction.new(node.codeOrigin,
 451 node.opcode,
 452 armV7AsRegisters(newList, postInstructions, node.operands, "b"))
 453 when "bbgt", "bbgteq", "bblt", "bblteq", "btbs", "tbs"
 454 newList << Instruction.new(node.codeOrigin,
 455 node.opcode,
 456 armV7AsRegisters(newList, postInstructions, node.operands, "bs"))
 457 when "addd", "divd", "subd", "muld", "sqrtd", /^bd/
 458 newList << Instruction.new(node.codeOrigin,
 459 node.opcode,
 460 armV7AsRegisters(newList, postInstructions, node.operands, "d"))
 461 when "jmp", "call"
 462 newList << Instruction.new(node.codeOrigin,
 463 node.opcode,
 464 [armV7AsRegister(newList, postInstructions, node.operands[0], "p", false)])
 465 else
 466 newList << node
 467 end
 468 newList += postInstructions
 469 else
 470 newList << node
 471 end
 472 }
 473 newList
 474end
 475
 476#
 477# Lowering of register reuse in compare instructions. For example:
 478#
 479# cieq t0, t1, t0
 480#
 481# will become:
 482#
 483# mov tmp, t0
 484# cieq tmp, t1, t0
 485#
 486
 487def armV7LowerRegisterReuse(list)
 488 newList = []
 489 list.each {
 490 | node |
 491 if node.is_a? Instruction
 492 case node.opcode
 493 when "cieq", "cineq", "cia", "ciaeq", "cib", "cibeq", "cigt", "cigteq", "cilt", "cilteq",
 494 "cpeq", "cpneq", "cpa", "cpaeq", "cpb", "cpbeq", "cpgt", "cpgteq", "cplt", "cplteq",
 495 "tio", "tis", "tiz", "tinz", "tbo", "tbs", "tbz", "tbnz"
 496 if node.operands.size == 2
 497 if node.operands[0] == node.operands[1]
 498 tmp = Tmp.new(node.codeOrigin, :gpr)
 499 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
 500 newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1]])
 501 else
 502 newList << node
 503 end
 504 else
 505 raise "Wrong number of arguments at #{node.codeOriginString}" unless node.operands.size == 3
 506 if node.operands[0] == node.operands[2]
 507 tmp = Tmp.new(node.codeOrigin, :gpr)
 508 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
 509 newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1], node.operands[2]])
 510 elsif node.operands[1] == node.operands[2]
 511 tmp = Tmp.new(node.codeOrigin, :gpr)
 512 newList << Instruction.new(node.codeOrigin, "move", [node.operands[1], tmp])
 513 newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], tmp, node.operands[2]])
 514 else
 515 newList << node
 516 end
 517 end
 518 else
 519 newList << node
 520 end
 521 else
 522 newList << node
 523 end
 524 }
 525 newList
 526end
 527
 528#
 529# Actual lowering code follows.
 530#
 531
 532class Sequence
 533 def lowerARMv7
 534 myList = @list
 535
 536 # Verify that we will only see instructions and labels.
 537 myList.each {
 538 | node |
 539 unless node.is_a? Instruction or
 540 node.is_a? Label or
 541 node.is_a? LocalLabel or
 542 node.is_a? Skip
 543 raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
 544 end
 545 }
 546
 547 myList = armV7LowerBranchOps(myList)
 548 myList = armV7LowerMalformedAddresses(myList)
 549 myList = armV7LowerMisplacedImmediates(myList)
 550 myList = armV7LowerMalformedImmediates(myList)
 551 myList = armV7LowerMisplacedAddresses(myList)
 552 myList = armV7LowerRegisterReuse(myList)
 553 myList = assignRegistersToTemporaries(myList, :gpr, ARMv7_EXTRA_GPRS)
 554 myList = assignRegistersToTemporaries(myList, :fpr, ARMv7_EXTRA_FPRS)
 555 myList.each {
 556 | node |
 557 node.lower("ARMv7")
 558 }
 559 end
 560end
 561
 562def armV7Operands(operands)
 563 operands.map{|v| v.armV7Operand}.join(", ")
 564end
 565
 566def armV7FlippedOperands(operands)
 567 armV7Operands([operands[-1]] + operands[0..-2])
 568end
 569
 570def emitArmV7Compact(opcode2, opcode3, operands)
 571 if operands.size == 3
 572 $asm.puts "#{opcode3} #{armV7FlippedOperands(operands)}"
 573 else
 574 raise unless operands.size == 2
 575 raise unless operands[1].is_a? RegisterID
 576 if operands[0].is_a? Immediate
 577 $asm.puts "#{opcode3} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
 578 else
 579 $asm.puts "#{opcode2} #{armV7FlippedOperands(operands)}"
 580 end
 581 end
 582end
 583
 584def emitArmV7(opcode, operands)
 585 if operands.size == 3
 586 $asm.puts "#{opcode} #{armV7FlippedOperands(operands)}"
 587 else
 588 raise unless operands.size == 2
 589 $asm.puts "#{opcode} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
 590 end
 591end
 592
 593def emitArmV7DoubleBranch(branchOpcode, operands)
 594 $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
 595 $asm.puts "vmrs apsr_nzcv, fpscr"
 596 $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
 597end
 598
 599def armV7TestingZero(operands)
 600 value = operands[0]
 601 case operands.size
 602 when 2
 603 mask = Immediate.new(codeOrigin, -1)
 604 when 3
 605 mask = operands[1]
 606 else
 607 raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
 608 end
 609
 610 (mask.is_a? Immediate and mask.value == -1) or value == mask
 611end
 612
 613def emitArmV7Test(operands)
 614 value = operands[0]
 615 case operands.size
 616 when 2
 617 mask = Immediate.new(codeOrigin, -1)
 618 when 3
 619 mask = operands[1]
 620 else
 621 raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
 622 end
 623
 624 if mask.is_a? Immediate and mask.value == -1
 625 $asm.puts "tst #{value.armV7Operand}, #{value.armV7Operand}"
 626 elsif mask.is_a? Immediate
 627 $asm.puts "tst.w #{value.armV7Operand}, #{mask.armV7Operand}"
 628 else
 629 $asm.puts "tst #{value.armV7Operand}, #{mask.armV7Operand}"
 630 end
 631end
 632
 633def emitArmV7Compare(operands, code)
 634 $asm.puts "movs #{operands[2].armV7Operand}, \#0"
 635 $asm.puts "cmp #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
 636 $asm.puts "it #{code}"
 637 $asm.puts "mov#{code} #{operands[2].armV7Operand}, \#1"
 638end
 639
 640def emitArmV7TestSet(operands, code)
 641 $asm.puts "movs #{operands[-1].armV7Operand}, \#0"
 642 emitArmV7Test(operands)
 643 $asm.puts "it #{code}"
 644 $asm.puts "mov#{code} #{operands[-1].armV7Operand}, \#1"
 645end
 646
 647class Instruction
 648 def lowerARMv7
 649 $asm.comment codeOriginString
 650 case opcode
 651 when "addi", "addp"
 652 if operands.size == 3 and operands[0].is_a? Immediate
 653 raise unless operands[1].is_a? RegisterID
 654 raise unless operands[2].is_a? RegisterID
 655 if operands[0].value == 0
 656 unless operands[1] == operands[2]
 657 $asm.puts "mov #{operands[2].armV7Operand}, #{operands[1].armV7Operand}"
 658 end
 659 else
 660 $asm.puts "adds #{armV7FlippedOperands(operands)}"
 661 end
 662 elsif operands.size == 3 and operands[0].is_a? RegisterID
 663 raise unless operands[1].is_a? RegisterID
 664 raise unless operands[2].is_a? RegisterID
 665 $asm.puts "adds #{armV7FlippedOperands(operands)}"
 666 else
 667 if operands[0].is_a? Immediate
 668 unless Immediate.new(nil, 0) == operands[0]
 669 $asm.puts "adds #{armV7FlippedOperands(operands)}"
 670 end
 671 else
 672 $asm.puts "add #{armV7FlippedOperands(operands)}"
 673 end
 674 end
 675 when "andi", "andp"
 676 emitArmV7Compact("ands", "and", operands)
 677 when "ori", "orp"
 678 emitArmV7Compact("orrs", "orr", operands)
 679 when "xori", "xorp"
 680 emitArmV7Compact("eors", "eor", operands)
 681 when "lshifti"
 682 emitArmV7Compact("lsls", "lsls", operands)
 683 when "rshifti"
 684 emitArmV7Compact("asrs", "asrs", operands)
 685 when "urshifti"
 686 emitArmV7Compact("lsrs", "lsrs", operands)
 687 when "muli"
 688 emitArmV7("muls", operands)
 689 when "subi", "subp"
 690 emitArmV7Compact("subs", "subs", operands)
 691 when "negi"
 692 $asm.puts "rsbs #{operands[0].armV7Operand}, #{operands[0].armV7Operand}, \#0"
 693 when "noti"
 694 $asm.puts "mvns #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
 695 when "loadi", "loadp"
 696 $asm.puts "ldr #{armV7FlippedOperands(operands)}"
 697 when "storei", "storep"
 698 $asm.puts "str #{armV7Operands(operands)}"
 699 when "loadb"
 700 $asm.puts "ldrb #{armV7FlippedOperands(operands)}"
 701 when "loadbs"
 702 $asm.puts "ldrsb.w #{armV7FlippedOperands(operands)}"
 703 when "storeb"
 704 $asm.puts "strb #{armV7FlippedOperands(operands)}"
 705 when "loadh"
 706 $asm.puts "ldrh #{armV7FlippedOperands(operands)}"
 707 when "loadhs"
 708 $asm.puts "ldrsh.w #{armV7FlippedOperands(operands)}"
 709 when "storeh"
 710 $asm.puts "strh #{armV7FlippedOperands(operands)}"
 711 when "addd"
 712 emitArmV7("vadd.f64", operands)
 713 when "divd"
 714 emitArmV7("vdiv.f64", operands)
 715 when "subd"
 716 emitArmV7("vsub.f64", operands)
 717 when "muld"
 718 emitArmV7("vmul.f64", operands)
 719 when "sqrtd"
 720 $asm.puts "vsqrt.f64 #{armV7FlippedOperands(operands)}"
 721 when "ci2d"
 722 $asm.puts "vmov #{operands[1].armV7Single}, #{operands[0].armV7Operand}"
 723 $asm.puts "vcvt.f64.s32 #{operands[1].armV7Operand}, #{operands[1].armV7Single}"
 724 when "bdeq"
 725 emitArmV7DoubleBranch("beq", operands)
 726 when "bdneq"
 727 $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
 728 $asm.puts "vmrs apsr_nzcv, fpscr"
 729 isUnordered = LocalLabel.unique("bdneq")
 730 $asm.puts "bvs #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
 731 $asm.puts "bne #{operands[2].asmLabel}"
 732 isUnordered.lower("ARMv7")
 733 when "bdgt"
 734 emitArmV7DoubleBranch("bgt", operands)
 735 when "bdgteq"
 736 emitArmV7DoubleBranch("bge", operands)
 737 when "bdlt"
 738 emitArmV7DoubleBranch("bmi", operands)
 739 when "bdlteq"
 740 emitArmV7DoubleBranch("bls", operands)
 741 when "bdequn"
 742 $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
 743 $asm.puts "vmrs apsr_nzcv, fpscr"
 744 $asm.puts "bvs #{operands[2].asmLabel}"
 745 $asm.puts "beq #{operands[2].asmLabel}"
 746 when "bdnequn"
 747 emitArmV7DoubleBranch("bne", operands)
 748 when "bdgtun"
 749 emitArmV7DoubleBranch("bhi", operands)
 750 when "bdgtequn"
 751 emitArmV7DoubleBranch("bpl", operands)
 752 when "bdltun"
 753 emitArmV7DoubleBranch("blt", operands)
 754 when "bdltequn"
 755 emitArmV7DoubleBranch("ble", operands)
 756 when "btd2i"
 757 # FIXME: may be a good idea to just get rid of this instruction, since the interpreter
 758 # currently does not use it.
 759 raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
 760 when "td2i"
 761 $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
 762 $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
 763 when "bcd2i"
 764 $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
 765 $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
 766 $asm.puts "vcvt.f64.s32 #{ARMv7_SCRATCH_FPR.armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
 767 emitArmV7DoubleBranch("bne", [ARMv7_SCRATCH_FPR, operands[0], operands[2]])
 768 $asm.puts "cbz #{operands[1].armV7Operand}, #{operands[2].asmLabel}"
 769 when "movdz"
 770 # FIXME: either support this or remove it.
 771 raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
 772 when "pop"
 773 $asm.puts "pop #{operands[0].armV7Operand}"
 774 when "push"
 775 $asm.puts "push #{operands[0].armV7Operand}"
 776 when "move", "sxi2p", "zxi2p"
 777 if operands[0].is_a? Immediate
 778 armV7MoveImmediate(operands[0].value, operands[1])
 779 else
 780 $asm.puts "mov #{armV7FlippedOperands(operands)}"
 781 end
 782 when "nop"
 783 $asm.puts "nop"
 784 when "bieq", "bpeq", "bbeq"
 785 if Immediate.new(nil, 0) == operands[0]
 786 $asm.puts "cbz #{operands[1].armV7Operand} #{operands[2].asmLabel}"
 787 elsif Immediate.new(nil, 0) == operands[1]
 788 $asm.puts "cbz #{operands[0].armV7Operand} #{operands[2].asmLabel}"
 789 else
 790 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 791 $asm.puts "beq #{operands[2].asmLabel}"
 792 end
 793 when "bineq", "bpneq", "bbneq"
 794 if Immediate.new(nil, 0) == operands[0]
 795 $asm.puts "cbnz #{operands[1].armV7Operand} #{operands[2].asmLabel}"
 796 elsif Immediate.new(nil, 0) == operands[1]
 797 $asm.puts "cbnz #{operands[0].armV7Operand} #{operands[2].asmLabel}"
 798 else
 799 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 800 $asm.puts "bne #{operands[2].asmLabel}"
 801 end
 802 when "bia", "bpa", "bba"
 803 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 804 $asm.puts "bhi #{operands[2].asmLabel}"
 805 when "biaeq", "bpaeq", "bbaeq"
 806 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 807 $asm.puts "bhs #{operands[2].asmLabel}"
 808 when "bib", "bpb", "bbb"
 809 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 810 $asm.puts "blo #{operands[2].asmLabel}"
 811 when "bibeq", "bpbeq", "bbbeq"
 812 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 813 $asm.puts "bls #{operands[2].asmLabel}"
 814 when "bigt", "bpgt", "bbgt"
 815 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 816 $asm.puts "bgt #{operands[2].asmLabel}"
 817 when "bigteq", "bpgteq", "bbgteq"
 818 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 819 $asm.puts "bge #{operands[2].asmLabel}"
 820 when "bilt", "bplt", "bblt"
 821 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 822 $asm.puts "blt #{operands[2].asmLabel}"
 823 when "bilteq", "bplteq", "bblteq"
 824 $asm.puts "cmp #{armV7Operands(operands[0..1])}"
 825 $asm.puts "ble #{operands[2].asmLabel}"
 826 when "btiz", "btpz", "btbz"
 827 if armV7TestingZero(operands)
 828 $asm.puts "cbz #{operands[0].armV7Operand}, #{operands[-1].asmLabel}"
 829 else
 830 emitArmV7Test(operands)
 831 $asm.puts "beq #{operands[-1].asmLabel}"
 832 end
 833 when "btinz", "btpnz", "btbnz"
 834 if armV7TestingZero(operands)
 835 $asm.puts "cbnz #{operands[0].armV7Operand}, #{operands[-1].asmLabel}"
 836 else
 837 emitArmV7Test(operands)
 838 $asm.puts "bne #{operands[-1].asmLabel}"
 839 end
 840 when "btio", "btpo", "btbo"
 841 emitArmV7Test(operands)
 842 $asm.puts "bvs #{operands[-1].asmLabel}"
 843 when "btis", "btps", "btbs"
 844 emitArmV7Test(operands)
 845 $asm.puts "bmi #{operands[-1].asmLabel}"
 846 when "jmp"
 847 if operands[0].label?
 848 $asm.puts "b #{operands[0].asmLabel}"
 849 else
 850 $asm.puts "mov pc, #{operands[0].armV7Operand}"
 851 end
 852 when "call"
 853 if operands[0].label?
 854 $asm.puts "blx #{operands[0].asmLabel}"
 855 else
 856 $asm.puts "blx #{operands[0].armV7Operand}"
 857 end
 858 when "break"
 859 $asm.puts "bkpt"
 860 when "ret"
 861 $asm.puts "bx lr"
 862 when "cieq", "cpeq"
 863 emitArmV7Compare(operands, "eq")
 864 when "cineq", "cpneq"
 865 emitArmV7Compare(operands, "ne")
 866 when "cia", "cpa"
 867 emitArmV7Compare(operands, "hi")
 868 when "ciaeq", "cpaeq"
 869 emitArmV7Compare(operands, "hs")
 870 when "cib", "cpb"
 871 emitArmV7Compare(operands, "lo")
 872 when "cibeq", "cpbeq"
 873 emitArmV7Compare(operands, "ls")
 874 when "cigt", "cpgt"
 875 emitArmV7Compare(operands, "gt")
 876 when "cigteq", "cpgteq"
 877 emitArmV7Compare(operands, "ge")
 878 when "cilt", "cplt"
 879 emitArmV7Compare(operands, "lt")
 880 when "cilteq", "cplteq"
 881 emitArmV7Compare(operands, "le")
 882 when "tio", "tbo"
 883 emitArmV7TestSet(operands, "vs")
 884 when "tis", "tbs"
 885 emitArmV7TestSet(operands, "mi")
 886 when "tiz", "tbz"
 887 emitArmV7TestSet(operands, "eq")
 888 when "tinz", "tbnz"
 889 emitArmV7TestSet(operands, "ne")
 890 when "peek"
 891 $asm.puts "ldr #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
 892 when "poke"
 893 $asm.puts "str #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
 894 when "fii2d"
 895 $asm.puts "vmov #{operands[2].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
 896 when "fd2ii"
 897 $asm.puts "vmov #{operands[1].armV7Operand}, #{operands[2].armV7Operand}, #{operands[0].armV7Operand}"
 898 when "bo"
 899 $asm.puts "bvs #{operands[0].asmLabel}"
 900 when "bs"
 901 $asm.puts "bmi #{operands[0].asmLabel}"
 902 when "bz"
 903 $asm.puts "beq #{operands[0].asmLabel}"
 904 when "bnz"
 905 $asm.puts "bne #{operands[0].asmLabel}"
 906 end
 907 end
 908end
 909
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 "self_hash"
 33require "settings"
 34require "transform"
 35
 36class Assembler
 37 def initialize(outp)
 38 @outp = outp
 39 @state = :cpp
 40 end
 41
 42 def enterAsm
 43 @outp.puts "asm ("
 44 @state = :asm
 45 end
 46
 47 def leaveAsm
 48 @outp.puts ");"
 49 @state = :cpp
 50 end
 51
 52 def inAsm
 53 enterAsm
 54 yield
 55 leaveAsm
 56 end
 57
 58 def puts(*line)
 59 raise unless @state == :asm
 60 @outp.puts("\"\\t" + line.join('') + "\\n\"")
 61 end
 62
 63 def print(line)
 64 raise unless @state == :asm
 65 @outp.print("\"" + line + "\"")
 66 end
 67
 68 def putsLabel(labelName)
 69 raise unless @state == :asm
 70 @outp.puts("\".globl \" SYMBOL_STRING(#{labelName}) \"\\n\"")
 71 @outp.puts("HIDE_SYMBOL(#{labelName}) \"\\n\"")
 72 @outp.puts("SYMBOL_STRING(#{labelName}) \":\\n\"")
 73 end
 74
 75 def putsLocalLabel(labelName)
 76 raise unless @state == :asm
 77 @outp.puts("LOCAL_LABEL_STRING(#{labelName}) \":\\n\"")
 78 end
 79
 80 def self.labelReference(labelName)
 81 "\" SYMBOL_STRING(#{labelName}) \""
 82 end
 83
 84 def self.localLabelReference(labelName)
 85 "\" LOCAL_LABEL_STRING(#{labelName}) \""
 86 end
 87
 88 def comment(text)
 89 @outp.puts "// #{text}"
 90 end
 91end
 92
 93asmFile = ARGV.shift
 94offsetsFile = ARGV.shift
 95outputFlnm = ARGV.shift
 96
 97$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
 98
 99offsetsList, configIndex = offsetsAndConfigurationIndex(offsetsFile)
 100inputData = IO::read(asmFile)
 101
 102inputHash =
 103 "// offlineasm input hash: " + Digest::SHA1.hexdigest(inputData) +
 104 " " + Digest::SHA1.hexdigest((offsetsList + [configIndex]).join(' ')) +
 105 " " + selfHash
 106
 107if FileTest.exist? outputFlnm
 108 File.open(outputFlnm, "r") {
 109 | inp |
 110 firstLine = inp.gets
 111 if firstLine and firstLine.chomp == inputHash
 112 $stderr.puts "offlineasm: Nothing changed."
 113 exit 0
 114 end
 115 }
 116end
 117
 118File.open(outputFlnm, "w") {
 119 | outp |
 120 $output = outp
 121 $output.puts inputHash
 122
 123 $asm = Assembler.new($output)
 124
 125 ast = parse(lex(inputData))
 126
 127 forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
 128 | concreteSettings, lowLevelAST, backend |
 129 assertConfiguration(concreteSettings)
 130 lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
 131 emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
 132 $asm.inAsm {
 133 lowLevelAST.lower(backend)
 134 }
 135 }
 136 }
 137}
 138
 139$stderr.puts "offlineasm: Assembly file #{outputFlnm} successfully generated."
 140
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# Base utility types for the AST.
 26#
 27
 28# Valid methods for Node:
 29#
 30# node.children -> Returns an array of immediate children.
 31#
 32# node.descendents -> Returns an array of all strict descendants (children
 33# and children of children, transitively).
 34#
 35# node.flatten -> Returns an array containing the strict descendants and
 36# the node itself.
 37#
 38# node.filter(type) -> Returns an array containing those elements in
 39# node.flatten that are of the given type (is_a? type returns true).
 40#
 41# node.mapChildren{|v| ...} -> Returns a new node with all children
 42# replaced according to the given block.
 43#
 44# Examples:
 45#
 46# node.filter(Setting).uniq -> Returns all of the settings that the AST's
 47# IfThenElse blocks depend on.
 48#
 49# node.filter(StructOffset).uniq -> Returns all of the structure offsets
 50# that the AST depends on.
 51
 52class Node
 53 attr_reader :codeOrigin
 54
 55 def initialize(codeOrigin)
 56 @codeOrigin = codeOrigin
 57 end
 58
 59 def codeOriginString
 60 "line number #{@codeOrigin}"
 61 end
 62
 63 def descendants
 64 children.collect{|v| v.flatten}.flatten
 65 end
 66
 67 def flatten
 68 [self] + descendants
 69 end
 70
 71 def filter(type)
 72 flatten.select{|v| v.is_a? type}
 73 end
 74end
 75
 76class NoChildren < Node
 77 def initialize(codeOrigin)
 78 super(codeOrigin)
 79 end
 80
 81 def children
 82 []
 83 end
 84
 85 def mapChildren
 86 self
 87 end
 88end
 89
 90class StructOffsetKey
 91 attr_reader :struct, :field
 92
 93 def initialize(struct, field)
 94 @struct = struct
 95 @field = field
 96 end
 97
 98 def hash
 99 @struct.hash + @field.hash * 3
 100 end
 101
 102 def eql?(other)
 103 @struct == other.struct and @field == other.field
 104 end
 105end
 106
 107#
 108# AST nodes.
 109#
 110
 111class StructOffset < NoChildren
 112 attr_reader :struct, :field
 113
 114 def initialize(codeOrigin, struct, field)
 115 super(codeOrigin)
 116 @struct = struct
 117 @field = field
 118 end
 119
 120 @@mapping = {}
 121
 122 def self.forField(codeOrigin, struct, field)
 123 key = StructOffsetKey.new(struct, field)
 124
 125 unless @@mapping[key]
 126 @@mapping[key] = StructOffset.new(codeOrigin, struct, field)
 127 end
 128 @@mapping[key]
 129 end
 130
 131 def dump
 132 "#{struct}::#{field}"
 133 end
 134
 135 def <=>(other)
 136 if @struct != other.struct
 137 return @struct <=> other.struct
 138 end
 139 @field <=> other.field
 140 end
 141
 142 def address?
 143 false
 144 end
 145
 146 def label?
 147 false
 148 end
 149
 150 def immediate?
 151 true
 152 end
 153
 154 def register?
 155 false
 156 end
 157end
 158
 159class Sizeof < NoChildren
 160 attr_reader :struct
 161
 162 def initialize(codeOrigin, struct)
 163 super(codeOrigin)
 164 @struct = struct
 165 end
 166
 167 @@mapping = {}
 168
 169 def self.forName(codeOrigin, struct)
 170 unless @@mapping[struct]
 171 @@mapping[struct] = Sizeof.new(codeOrigin, struct)
 172 end
 173 @@mapping[struct]
 174 end
 175
 176 def dump
 177 "sizeof #{@struct}"
 178 end
 179
 180 def <=>(other)
 181 @struct <=> other.struct
 182 end
 183
 184 def address?
 185 false
 186 end
 187
 188 def label?
 189 false
 190 end
 191
 192 def immediate?
 193 true
 194 end
 195
 196 def register?
 197 false
 198 end
 199end
 200
 201class Immediate < NoChildren
 202 attr_reader :value
 203
 204 def initialize(codeOrigin, value)
 205 super(codeOrigin)
 206 @value = value
 207 raise "Bad immediate value #{value.inspect} at #{codeOriginString}" unless value.is_a? Integer
 208 end
 209
 210 def dump
 211 "#{value}"
 212 end
 213
 214 def ==(other)
 215 other.is_a? Immediate and other.value == @value
 216 end
 217
 218 def address?
 219 false
 220 end
 221
 222 def label?
 223 false
 224 end
 225
 226 def address?
 227 false
 228 end
 229
 230 def label?
 231 false
 232 end
 233
 234 def immediate?
 235 true
 236 end
 237
 238 def register?
 239 false
 240 end
 241end
 242
 243class AddImmediates < Node
 244 attr_reader :left, :right
 245
 246 def initialize(codeOrigin, left, right)
 247 super(codeOrigin)
 248 @left = left
 249 @right = right
 250 end
 251
 252 def children
 253 [@left, @right]
 254 end
 255
 256 def mapChildren
 257 AddImmediates.new(codeOrigin, (yield @left), (yield @right))
 258 end
 259
 260 def dump
 261 "(#{left.dump} + #{right.dump})"
 262 end
 263
 264 def address?
 265 false
 266 end
 267
 268 def label?
 269 false
 270 end
 271
 272 def immediate?
 273 true
 274 end
 275
 276 def register?
 277 false
 278 end
 279end
 280
 281class SubImmediates < Node
 282 attr_reader :left, :right
 283
 284 def initialize(codeOrigin, left, right)
 285 super(codeOrigin)
 286 @left = left
 287 @right = right
 288 end
 289
 290 def children
 291 [@left, @right]
 292 end
 293
 294 def mapChildren
 295 SubImmediates.new(codeOrigin, (yield @left), (yield @right))
 296 end
 297
 298 def dump
 299 "(#{left.dump} - #{right.dump})"
 300 end
 301
 302 def address?
 303 false
 304 end
 305
 306 def label?
 307 false
 308 end
 309
 310 def immediate?
 311 true
 312 end
 313
 314 def register?
 315 false
 316 end
 317end
 318
 319class MulImmediates < Node
 320 attr_reader :left, :right
 321
 322 def initialize(codeOrigin, left, right)
 323 super(codeOrigin)
 324 @left = left
 325 @right = right
 326 end
 327
 328 def children
 329 [@left, @right]
 330 end
 331
 332 def mapChildren
 333 MulImmediates.new(codeOrigin, (yield @left), (yield @right))
 334 end
 335
 336 def dump
 337 "(#{left.dump} * #{right.dump})"
 338 end
 339
 340 def address?
 341 false
 342 end
 343
 344 def label?
 345 false
 346 end
 347
 348 def immediate?
 349 true
 350 end
 351
 352 def register?
 353 false
 354 end
 355end
 356
 357class NegImmediate < Node
 358 attr_reader :child
 359
 360 def initialize(codeOrigin, child)
 361 super(codeOrigin)
 362 @child = child
 363 end
 364
 365 def children
 366 [@child]
 367 end
 368
 369 def mapChildren
 370 NegImmediate.new(codeOrigin, (yield @child))
 371 end
 372
 373 def dump
 374 "(-#{@child.dump})"
 375 end
 376
 377 def address?
 378 false
 379 end
 380
 381 def label?
 382 false
 383 end
 384
 385 def immediate?
 386 true
 387 end
 388
 389 def register?
 390 false
 391 end
 392end
 393
 394class RegisterID < NoChildren
 395 attr_reader :name
 396
 397 def initialize(codeOrigin, name)
 398 super(codeOrigin)
 399 @name = name
 400 end
 401
 402 @@mapping = {}
 403
 404 def self.forName(codeOrigin, name)
 405 unless @@mapping[name]
 406 @@mapping[name] = RegisterID.new(codeOrigin, name)
 407 end
 408 @@mapping[name]
 409 end
 410
 411 def dump
 412 name
 413 end
 414
 415 def address?
 416 false
 417 end
 418
 419 def label?
 420 false
 421 end
 422
 423 def immediate?
 424 false
 425 end
 426
 427 def register?
 428 true
 429 end
 430end
 431
 432class FPRegisterID < NoChildren
 433 attr_reader :name
 434
 435 def initialize(codeOrigin, name)
 436 super(codeOrigin)
 437 @name = name
 438 end
 439
 440 @@mapping = {}
 441
 442 def self.forName(codeOrigin, name)
 443 unless @@mapping[name]
 444 @@mapping[name] = FPRegisterID.new(codeOrigin, name)
 445 end
 446 @@mapping[name]
 447 end
 448
 449 def dump
 450 name
 451 end
 452
 453 def address?
 454 false
 455 end
 456
 457 def label?
 458 false
 459 end
 460
 461 def immediate?
 462 false
 463 end
 464
 465 def register?
 466 true
 467 end
 468end
 469
 470class Variable < NoChildren
 471 attr_reader :name
 472
 473 def initialize(codeOrigin, name)
 474 super(codeOrigin)
 475 @name = name
 476 end
 477
 478 @@mapping = {}
 479
 480 def self.forName(codeOrigin, name)
 481 unless @@mapping[name]
 482 @@mapping[name] = Variable.new(codeOrigin, name)
 483 end
 484 @@mapping[name]
 485 end
 486
 487 def dump
 488 name
 489 end
 490end
 491
 492class Address < Node
 493 attr_reader :base, :offset
 494
 495 def initialize(codeOrigin, base, offset)
 496 super(codeOrigin)
 497 @base = base
 498 @offset = offset
 499 raise "Bad base for address #{base.inspect} at #{codeOriginString}" unless base.is_a? Variable or base.register?
 500 raise "Bad offset for address #{offset.inspect} at #{codeOriginString}" unless offset.is_a? Variable or offset.immediate?
 501 end
 502
 503 def children
 504 [@base, @offset]
 505 end
 506
 507 def mapChildren
 508 Address.new(codeOrigin, (yield @base), (yield @offset))
 509 end
 510
 511 def dump
 512 "#{offset.dump}[#{base.dump}]"
 513 end
 514
 515 def address?
 516 true
 517 end
 518
 519 def label?
 520 false
 521 end
 522
 523 def immediate?
 524 false
 525 end
 526
 527 def register?
 528 false
 529 end
 530end
 531
 532class BaseIndex < Node
 533 attr_reader :base, :index, :scale, :offset
 534
 535 def initialize(codeOrigin, base, index, scale, offset)
 536 super(codeOrigin)
 537 @base = base
 538 @index = index
 539 @scale = scale
 540 raise unless [1, 2, 4, 8].member? @scale
 541 @offset = offset
 542 end
 543
 544 def children
 545 [@base, @index, @offset]
 546 end
 547
 548 def mapChildren
 549 BaseIndex.new(codeOrigin, (yield @base), (yield @index), @scale, (yield @offset))
 550 end
 551
 552 def dump
 553 "#{offset.dump}[#{base.dump}, #{index.dump}, #{scale}]"
 554 end
 555
 556 def address?
 557 true
 558 end
 559
 560 def label?
 561 false
 562 end
 563
 564 def immediate?
 565 false
 566 end
 567
 568 def register?
 569 false
 570 end
 571end
 572
 573class AbsoluteAddress < NoChildren
 574 attr_reader :address
 575
 576 def initialize(codeOrigin, address)
 577 super(codeOrigin)
 578 @address = address
 579 end
 580
 581 def dump
 582 "#{address.dump}[]"
 583 end
 584
 585 def address?
 586 true
 587 end
 588
 589 def label?
 590 false
 591 end
 592
 593 def immediate?
 594 false
 595 end
 596
 597 def register?
 598 false
 599 end
 600end
 601
 602class Instruction < Node
 603 attr_reader :opcode, :operands
 604
 605 def initialize(codeOrigin, opcode, operands)
 606 super(codeOrigin)
 607 @opcode = opcode
 608 @operands = operands
 609 end
 610
 611 def children
 612 operands
 613 end
 614
 615 def mapChildren(&proc)
 616 Instruction.new(codeOrigin, @opcode, @operands.map(&proc))
 617 end
 618
 619 def dump
 620 "\t" + opcode.to_s + " " + operands.collect{|v| v.dump}.join(", ")
 621 end
 622end
 623
 624class Error < NoChildren
 625 def initialize(codeOrigin)
 626 super(codeOrigin)
 627 end
 628
 629 def dump
 630 "\terror"
 631 end
 632end
 633
 634class ConstDecl < Node
 635 attr_reader :variable, :value
 636
 637 def initialize(codeOrigin, variable, value)
 638 super(codeOrigin)
 639 @variable = variable
 640 @value = value
 641 end
 642
 643 def children
 644 [@variable, @value]
 645 end
 646
 647 def mapChildren
 648 ConstDecl.new(codeOrigin, (yield @variable), (yield @value))
 649 end
 650
 651 def dump
 652 "const #{@variable.dump} = #{@value.dump}"
 653 end
 654end
 655
 656$labelMapping = {}
 657
 658class Label < NoChildren
 659 attr_reader :name
 660
 661 def initialize(codeOrigin, name)
 662 super(codeOrigin)
 663 @name = name
 664 end
 665
 666 def self.forName(codeOrigin, name)
 667 if $labelMapping[name]
 668 raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
 669 else
 670 $labelMapping[name] = Label.new(codeOrigin, name)
 671 end
 672 $labelMapping[name]
 673 end
 674
 675 def dump
 676 "#{name}:"
 677 end
 678end
 679
 680class LocalLabel < NoChildren
 681 attr_reader :name
 682
 683 def initialize(codeOrigin, name)
 684 super(codeOrigin)
 685 @name = name
 686 end
 687
 688 @@uniqueNameCounter = 0
 689
 690 def self.forName(codeOrigin, name)
 691 if $labelMapping[name]
 692 raise "Label name collision: #{name}" unless $labelMapping[name].is_a? LocalLabel
 693 else
 694 $labelMapping[name] = LocalLabel.new(codeOrigin, name)
 695 end
 696 $labelMapping[name]
 697 end
 698
 699 def self.unique(comment)
 700 newName = "_#{comment}"
 701 if $labelMapping[newName]
 702 while $labelMapping[newName = "_#{@@uniqueNameCounter}_#{comment}"]
 703 @@uniqueNameCounter += 1
 704 end
 705 end
 706 forName(nil, newName)
 707 end
 708
 709 def cleanName
 710 if name =~ /^\./
 711 "_" + name[1..-1]
 712 else
 713 name
 714 end
 715 end
 716
 717 def dump
 718 "#{name}:"
 719 end
 720end
 721
 722class LabelReference < Node
 723 attr_reader :label
 724
 725 def initialize(codeOrigin, label)
 726 super(codeOrigin)
 727 @label = label
 728 end
 729
 730 def children
 731 [@label]
 732 end
 733
 734 def mapChildren
 735 LabelReference.new(codeOrigin, (yield @label))
 736 end
 737
 738 def name
 739 label.name
 740 end
 741
 742 def dump
 743 label.name
 744 end
 745
 746 def address?
 747 false
 748 end
 749
 750 def label?
 751 true
 752 end
 753end
 754
 755class LocalLabelReference < NoChildren
 756 attr_reader :label
 757
 758 def initialize(codeOrigin, label)
 759 super(codeOrigin)
 760 @label = label
 761 end
 762
 763 def children
 764 [@label]
 765 end
 766
 767 def mapChildren
 768 LocalLabelReference.new(codeOrigin, (yield @label))
 769 end
 770
 771 def name
 772 label.name
 773 end
 774
 775 def dump
 776 label.name
 777 end
 778
 779 def address?
 780 false
 781 end
 782
 783 def label?
 784 true
 785 end
 786end
 787
 788class Sequence < Node
 789 attr_reader :list
 790
 791 def initialize(codeOrigin, list)
 792 super(codeOrigin)
 793 @list = list
 794 end
 795
 796 def children
 797 list
 798 end
 799
 800 def mapChildren(&proc)
 801 Sequence.new(codeOrigin, @list.map(&proc))
 802 end
 803
 804 def dump
 805 list.collect{|v| v.dump}.join("\n")
 806 end
 807end
 808
 809class True < NoChildren
 810 def initialize
 811 super(nil)
 812 end
 813
 814 @@instance = True.new
 815
 816 def self.instance
 817 @@instance
 818 end
 819
 820 def value
 821 true
 822 end
 823
 824 def dump
 825 "true"
 826 end
 827end
 828
 829class False < NoChildren
 830 def initialize
 831 super(nil)
 832 end
 833
 834 @@instance = False.new
 835
 836 def self.instance
 837 @@instance
 838 end
 839
 840 def value
 841 false
 842 end
 843
 844 def dump
 845 "false"
 846 end
 847end
 848
 849class TrueClass
 850 def asNode
 851 True.instance
 852 end
 853end
 854
 855class FalseClass
 856 def asNode
 857 False.instance
 858 end
 859end
 860
 861class Setting < NoChildren
 862 attr_reader :name
 863
 864 def initialize(codeOrigin, name)
 865 super(codeOrigin)
 866 @name = name
 867 end
 868
 869 @@mapping = {}
 870
 871 def self.forName(codeOrigin, name)
 872 unless @@mapping[name]
 873 @@mapping[name] = Setting.new(codeOrigin, name)
 874 end
 875 @@mapping[name]
 876 end
 877
 878 def dump
 879 name
 880 end
 881end
 882
 883class And < Node
 884 attr_reader :left, :right
 885
 886 def initialize(codeOrigin, left, right)
 887 super(codeOrigin)
 888 @left = left
 889 @right = right
 890 end
 891
 892 def children
 893 [@left, @right]
 894 end
 895
 896 def mapChildren
 897 And.new(codeOrigin, (yield @left), (yield @right))
 898 end
 899
 900 def dump
 901 "(#{left.dump} and #{right.dump})"
 902 end
 903end
 904
 905class Or < Node
 906 attr_reader :left, :right
 907
 908 def initialize(codeOrigin, left, right)
 909 super(codeOrigin)
 910 @left = left
 911 @right = right
 912 end
 913
 914 def children
 915 [@left, @right]
 916 end
 917
 918 def mapChildren
 919 Or.new(codeOrigin, (yield @left), (yield @right))
 920 end
 921
 922 def dump
 923 "(#{left.dump} or #{right.dump})"
 924 end
 925end
 926
 927class Not < Node
 928 attr_reader :child
 929
 930 def initialize(codeOrigin, child)
 931 super(codeOrigin)
 932 @child = child
 933 end
 934
 935 def children
 936 [@left, @right]
 937 end
 938
 939 def mapChildren
 940 Not.new(codeOrigin, (yield @child))
 941 end
 942
 943 def dump
 944 "(not #{child.dump})"
 945 end
 946end
 947
 948class Skip < NoChildren
 949 def initialize(codeOrigin)
 950 super(codeOrigin)
 951 end
 952
 953 def dump
 954 "\tskip"
 955 end
 956end
 957
 958class IfThenElse < Node
 959 attr_reader :predicate, :thenCase
 960 attr_accessor :elseCase
 961
 962 def initialize(codeOrigin, predicate, thenCase)
 963 super(codeOrigin)
 964 @predicate = predicate
 965 @thenCase = thenCase
 966 @elseCase = Skip.new(codeOrigin)
 967 end
 968
 969 def children
 970 if @elseCase
 971 [@predicate, @thenCase, @elseCase]
 972 else
 973 [@predicate, @thenCase]
 974 end
 975 end
 976
 977 def mapChildren
 978 IfThenElse.new(codeOrigin, (yield @predicate), (yield @thenCase), (yield @elseCase))
 979 end
 980
 981 def dump
 982 "if #{predicate.dump}\n" + thenCase.dump + "\nelse\n" + elseCase.dump + "\nend"
 983 end
 984end
 985
 986class Macro < Node
 987 attr_reader :name, :variables, :body
 988
 989 def initialize(codeOrigin, name, variables, body)
 990 super(codeOrigin)
 991 @name = name
 992 @variables = variables
 993 @body = body
 994 end
 995
 996 def children
 997 @variables + [@body]
 998 end
 999
 1000 def mapChildren
 1001 Macro.new(codeOrigin, @name, @variables.map{|v| yield v}, (yield @body))
 1002 end
 1003
 1004 def dump
 1005 "macro #{name}(" + variables.collect{|v| v.dump}.join(", ") + ")\n" + body.dump + "\nend"
 1006 end
 1007end
 1008
 1009class MacroCall < Node
 1010 attr_reader :name, :operands
 1011
 1012 def initialize(codeOrigin, name, operands)
 1013 super(codeOrigin)
 1014 @name = name
 1015 @operands = operands
 1016 raise unless @operands
 1017 @operands.each{|v| raise unless v}
 1018 end
 1019
 1020 def children
 1021 @operands
 1022 end
 1023
 1024 def mapChildren(&proc)
 1025 MacroCall.new(codeOrigin, @name, @operands.map(&proc))
 1026 end
 1027
 1028 def dump
 1029 "\t#{name}(" + operands.collect{|v| v.dump}.join(", ") + ")"
 1030 end
 1031end
 1032
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 "armv7"
 25require "ast"
 26require "x86"
 27
 28BACKENDS =
 29 [
 30 "X86",
 31 "ARMv7"
 32 ]
 33
 34# Keep the set of working backends separate from the set of backends that might be
 35# supported. This is great because the BACKENDS list is almost like a reserved
 36# words list, in that it causes settings resolution to treat those words specially.
 37# Hence this lets us set aside the name of a backend we might want to support in
 38# the future while not actually supporting the backend yet.
 39WORKING_BACKENDS =
 40 [
 41 "X86",
 42 "ARMv7"
 43 ]
 44
 45BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
 46
 47class Node
 48 def lower(name)
 49 send("lower" + name)
 50 end
 51end
 52
 53# Overrides for lower() for those nodes that are backend-agnostic
 54
 55class Label
 56 def lower(name)
 57 $asm.putsLabel(self.name[1..-1])
 58 end
 59end
 60
 61class LocalLabel
 62 def lower(name)
 63 $asm.putsLocalLabel "_offlineasm_#{self.name[1..-1]}"
 64 end
 65end
 66
 67class LabelReference
 68 def asmLabel
 69 Assembler.labelReference(name[1..-1])
 70 end
 71end
 72
 73class LocalLabelReference
 74 def asmLabel
 75 Assembler.localLabelReference("_offlineasm_"+name[1..-1])
 76 end
 77end
 78
 79class Skip
 80 def lower(name)
 81 end
 82end
 83
 84class Sequence
 85 def lower(name)
 86 if respond_to? "lower#{name}"
 87 send("lower#{name}")
 88 else
 89 @list.each {
 90 | node |
 91 node.lower(name)
 92 }
 93 end
 94 end
 95end
 96
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 "self_hash"
 33require "settings"
 34require "transform"
 35
 36inputFlnm = ARGV.shift
 37outputFlnm = ARGV.shift
 38
 39$stderr.puts "offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
 40
 41def emitMagicNumber
 42 OFFSET_MAGIC_NUMBERS.each {
 43 | number |
 44 $output.puts "#{number},"
 45 }
 46end
 47
 48inputData = IO::read(inputFlnm)
 49inputHash = "// offlineasm input hash: #{Digest::SHA1.hexdigest(inputData)} #{selfHash}"
 50
 51if FileTest.exist? outputFlnm
 52 File.open(outputFlnm, "r") {
 53 | inp |
 54 firstLine = inp.gets
 55 if firstLine and firstLine.chomp == inputHash
 56 $stderr.puts "offlineasm: Nothing changed."
 57 exit 0
 58 end
 59 }
 60end
 61
 62originalAST = parse(lex(inputData))
 63
 64File.open(outputFlnm, "w") {
 65 | outp |
 66 $output = outp
 67 outp.puts inputHash
 68 emitCodeInAllConfigurations(originalAST) {
 69 | settings, ast, backend, index |
 70 offsetsList = ast.filter(StructOffset).uniq.sort
 71 sizesList = ast.filter(Sizeof).uniq.sort
 72
 73 length = (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
 74
 75 outp.puts "static const unsigned extractorTable[#{length}] = {"
 76 emitMagicNumber
 77 outp.puts "#{index},"
 78 offsetsList.each {
 79 | offset |
 80 emitMagicNumber
 81 outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
 82 }
 83 sizesList.each {
 84 | offset |
 85 emitMagicNumber
 86 outp.puts "sizeof(#{offset.struct}),"
 87 }
 88 outp.puts "};"
 89 }
 90}
 91
 92$stderr.puts "offlineasm: offset extractor #{outputFlnm} successfully generated."
 93
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
 24# Interesting invariant, which we take advantage of: branching instructions
 25# always begin with "b", and no non-branching instructions begin with "b".
 26# Terminal instructions are "jmp" and "ret".
 27
 28MACRO_INSTRUCTIONS =
 29 [
 30 "addi",
 31 "andi",
 32 "lshifti",
 33 "muli",
 34 "negi",
 35 "noti",
 36 "ori",
 37 "rshifti",
 38 "urshifti",
 39 "subi",
 40 "xori",
 41 "loadi",
 42 "loadb",
 43 "loadbs",
 44 "loadh",
 45 "loadhs",
 46 "storei",
 47 "storeb",
 48 "loadd",
 49 "moved",
 50 "stored",
 51 "addd",
 52 "divd",
 53 "subd",
 54 "muld",
 55 "sqrtd",
 56 "ci2d",
 57 "fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr>
 58 "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
 59 "bdeq",
 60 "bdneq",
 61 "bdgt",
 62 "bdgteq",
 63 "bdlt",
 64 "bdlteq",
 65 "bdequn",
 66 "bdnequn",
 67 "bdgtun",
 68 "bdgtequn",
 69 "bdltun",
 70 "bdltequn",
 71 "btd2i",
 72 "td2i",
 73 "bcd2i",
 74 "movdz",
 75 "pop",
 76 "push",
 77 "move",
 78 "sxi2p",
 79 "zxi2p",
 80 "nop",
 81 "bieq",
 82 "bineq",
 83 "bia",
 84 "biaeq",
 85 "bib",
 86 "bibeq",
 87 "bigt",
 88 "bigteq",
 89 "bilt",
 90 "bilteq",
 91 "bbeq",
 92 "bbneq",
 93 "bba",
 94 "bbaeq",
 95 "bbb",
 96 "bbbeq",
 97 "bbgt",
 98 "bbgteq",
 99 "bblt",
 100 "bblteq",
 101 "btio",
 102 "btis",
 103 "btiz",
 104 "btinz",
 105 "btbo",
 106 "btbs",
 107 "btbz",
 108 "btbnz",
 109 "jmp",
 110 "baddio",
 111 "baddis",
 112 "baddiz",
 113 "baddinz",
 114 "bsubio",
 115 "bsubis",
 116 "bsubiz",
 117 "bsubinz",
 118 "bmulio",
 119 "bmulis",
 120 "bmuliz",
 121 "bmulinz",
 122 "borio",
 123 "boris",
 124 "boriz",
 125 "borinz",
 126 "break",
 127 "call",
 128 "ret",
 129 "cieq",
 130 "cineq",
 131 "cia",
 132 "ciaeq",
 133 "cib",
 134 "cibeq",
 135 "cigt",
 136 "cigteq",
 137 "cilt",
 138 "cilteq",
 139 "tio",
 140 "tis",
 141 "tiz",
 142 "tinz",
 143 "tbo",
 144 "tbs",
 145 "tbz",
 146 "tbnz",
 147 "peek",
 148 "poke",
 149 "bpeq",
 150 "bpneq",
 151 "bpa",
 152 "bpaeq",
 153 "bpb",
 154 "bpbeq",
 155 "bpgt",
 156 "bpgteq",
 157 "bplt",
 158 "bplteq",
 159 "addp",
 160 "andp",
 161 "orp",
 162 "subp",
 163 "xorp",
 164 "loadp",
 165 "cpeq",
 166 "cpneq",
 167 "cpa",
 168 "cpaeq",
 169 "cpb",
 170 "cpbeq",
 171 "cpgt",
 172 "cpgteq",
 173 "cplt",
 174 "cplteq",
 175 "storep",
 176 "btpo",
 177 "btps",
 178 "btpz",
 179 "btpnz",
 180 "baddpo",
 181 "baddps",
 182 "baddpz",
 183 "baddpnz",
 184 "bo",
 185 "bs",
 186 "bz",
 187 "bnz"
 188 ]
 189
 190X86_INSTRUCTIONS =
 191 [
 192 "cdqi",
 193 "idivi"
 194 ]
 195
 196INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS
 197
 198INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
 199
 200def isBranch(instruction)
 201 instruction =~ /^b/
 202end
 203
 204def hasFallThrough(instruction)
 205 instruction != "ret" and instruction != "jmp"
 206end
 207
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# offsetsList(ast)
 31# sizesList(ast)
 32#
 33# Returns a list of offsets and sizes used by the AST.
 34#
 35
 36def offsetsList(ast)
 37 ast.filter(StructOffset).uniq.sort
 38end
 39
 40def sizesList(ast)
 41 ast.filter(Sizeof).uniq.sort
 42end
 43
 44#
 45# offsetsAndConfigurationIndex(ast, file) ->
 46# [offsets, index]
 47#
 48# Parses the offsets from a file and returns a list of offsets and the
 49# index of the configuration that is valid in this build target.
 50#
 51
 52def offsetsAndConfigurationIndex(file)
 53 index = nil
 54 offsets = []
 55 endiannessMarkerBytes = nil
 56
 57 def readInt(endianness, inp)
 58 bytes = []
 59 4.times {
 60 bytes << inp.getbyte
 61 }
 62
 63 if endianness == :little
 64 # Little endian
 65 (bytes[0] << 0 |
 66 bytes[1] << 8 |
 67 bytes[2] << 16 |
 68 bytes[3] << 24)
 69 else
 70 # Big endian
 71 (bytes[0] << 24 |
 72 bytes[1] << 16 |
 73 bytes[2] << 8 |
 74 bytes[3] << 0)
 75 end
 76 end
 77
 78 [:little, :big].each {
 79 | endianness |
 80 magicBytes = []
 81 MAGIC_NUMBERS.each {
 82 | number |
 83 currentBytes = []
 84 4.times {
 85 currentBytes << (number & 0xff)
 86 number >>= 8
 87 }
 88 if endianness == :big
 89 currentBytes.reverse!
 90 end
 91 magicBytes += currentBytes
 92 }
 93
 94 File.open(file, "r") {
 95 | inp |
 96 whereInMarker = 0
 97 loop {
 98 byte = inp.getbyte
 99 break unless byte
 100 if byte == magicBytes[whereInMarker]
 101 whereInMarker += 1
 102 if whereInMarker == magicBytes.size
 103 # We have a match! If we have not yet read the endianness marker and index,
 104 # then read those now; otherwise read an offset.
 105
 106 if not index
 107 index = readInt(endianness, inp)
 108 else
 109 offsets << readInt(endianness, inp)
 110 end
 111
 112 whereInMarker = 0
 113 end
 114 else
 115 whereInMarker = 0
 116 end
 117 }
 118 }
 119
 120 break if index
 121 }
 122
 123 raise unless index
 124
 125 [offsets, index]
 126end
 127
 128#
 129# buildOffsetsMap(ast, offsetsList) -> [offsets, sizes]
 130#
 131# Builds a mapping between StructOffset nodes and their values.
 132#
 133
 134def buildOffsetsMap(ast, offsetsList)
 135 offsetsMap = {}
 136 sizesMap = {}
 137 astOffsetsList = offsetsList(ast)
 138 astSizesList = sizesList(ast)
 139 raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
 140 offsetsList(ast).each_with_index {
 141 | structOffset, index |
 142 offsetsMap[structOffset] = offsetsList.shift
 143 }
 144 sizesList(ast).each_with_index {
 145 | sizeof, index |
 146 sizesMap[sizeof] = offsetsList.shift
 147 }
 148 [offsetsMap, sizesMap]
 149end
 150
0

Source/JavaScriptCore/offlineasm/opt.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# "Optimization" passes. These are used to lower the representation for
 28# backends that cannot handle some of our higher-level instructions.
 29#
 30
 31#
 32# A temporary - a variable that will be allocated to a register after we're
 33# done.
 34#
 35
 36class Node
 37 def replaceTemporariesWithRegisters(kind)
 38 mapChildren {
 39 | node |
 40 node.replaceTemporariesWithRegisters(kind)
 41 }
 42 end
 43end
 44
 45class Tmp < NoChildren
 46 attr_reader :firstMention, :lastMention
 47 attr_reader :kind
 48 attr_accessor :register
 49
 50 def initialize(codeOrigin, kind)
 51 super(codeOrigin)
 52 @kind = kind
 53 end
 54
 55 def dump
 56 "$tmp#{object_id}"
 57 end
 58
 59 def mention!(position)
 60 if not @firstMention or position < @firstMention
 61 @firstMention = position
 62 end
 63 if not @lastMention or position > @lastMention
 64 @lastMention = position
 65 end
 66 end
 67
 68 def replaceTemporariesWithRegisters(kind)
 69 if @kind == kind
 70 raise "Did not allocate register to temporary at #{codeOriginString}" unless @register
 71 @register
 72 else
 73 self
 74 end
 75 end
 76
 77 def address?
 78 false
 79 end
 80
 81 def label?
 82 false
 83 end
 84
 85 def immediate?
 86 false
 87 end
 88
 89 def register?
 90 true
 91 end
 92end
 93
 94# Assign registers to temporaries, by finding which temporaries interfere
 95# with each other. Note that this relies on temporary live ranges not crossing
 96# basic block boundaries.
 97
 98def assignRegistersToTemporaries(list, kind, registers)
 99 list.each_with_index {
 100 | node, index |
 101 node.filter(Tmp).uniq.each {
 102 | tmp |
 103 if tmp.kind == kind
 104 tmp.mention! index
 105 end
 106 }
 107 }
 108
 109 freeRegisters = registers.dup
 110 list.each_with_index {
 111 | node, index |
 112 tmpList = node.filter(Tmp).uniq
 113 tmpList.each {
 114 | tmp |
 115 if tmp.kind == kind and tmp.firstMention == index
 116 raise "Could not allocate register to temporary at #{node.codeOrginString}" if freeRegisters.empty?
 117 tmp.register = freeRegisters.pop
 118 end
 119 }
 120 tmpList.each {
 121 | tmp |
 122 if tmp.kind == kind and tmp.lastMention == index
 123 freeRegisters.push tmp.register
 124 raise "Register allocation inconsistency at #{node.codeOriginString}" if freeRegisters.size > registers.size
 125 end
 126 }
 127 }
 128
 129 list.map {
 130 | node |
 131 node.replaceTemporariesWithRegisters(kind)
 132 }
 133end
 134
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# The lexer. Takes a string and returns an array of tokens.
 63#
 64
 65def lex(str)
 66 result = []
 67 lineNumber = 1
 68 while not str.empty?
 69 case str
 70 when /\A\#([^\n]*)/
 71 # comment, ignore
 72 when /\A\n/
 73 result << Token.new(lineNumber, $&)
 74 lineNumber += 1
 75 when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
 76 result << Token.new(lineNumber, $&)
 77 when /\A\.([a-zA-Z0-9_]*)/
 78 result << Token.new(lineNumber, $&)
 79 when /\A_([a-zA-Z0-9_]*)/
 80 result << Token.new(lineNumber, $&)
 81 when /\A([ \t]+)/
 82 # whitespace, ignore
 83 when /\A0x([0-9a-fA-F]+)/
 84 result << Token.new(lineNumber, $&.hex.to_s)
 85 when /\A0([0-7]+)/
 86 result << Token.new(lineNumber, $&.oct.to_s)
 87 when /\A([0-9]+)/
 88 result << Token.new(lineNumber, $&)
 89 when /\A::/
 90 result << Token.new(lineNumber, $&)
 91 when /\A[:,\(\)\[\]=\+\-*]/
 92 result << Token.new(lineNumber, $&)
 93 else
 94 raise "Lexer error at line number #{lineNumber}, unexpected sequence #{str[0..20].inspect}"
 95 end
 96 str = $~.post_match
 97 end
 98 result
 99end
 100
 101#
 102# Token identification.
 103#
 104
 105def isRegister(token)
 106 token =~ REGISTER_PATTERN
 107end
 108
 109def isInstruction(token)
 110 token =~ INSTRUCTION_PATTERN
 111end
 112
 113def isKeyword(token)
 114 token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error))\Z/ or
 115 token =~ REGISTER_PATTERN or
 116 token =~ INSTRUCTION_PATTERN
 117end
 118
 119def isIdentifier(token)
 120 token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
 121end
 122
 123def isLabel(token)
 124 token =~ /\A_([a-zA-Z0-9_]*)\Z/
 125end
 126
 127def isLocalLabel(token)
 128 token =~ /\A\.([a-zA-Z0-9_]*)\Z/
 129end
 130
 131def isVariable(token)
 132 isIdentifier(token) or isRegister(token)
 133end
 134
 135def isInteger(token)
 136 token =~ /\A[0-9]/
 137end
 138
 139#
 140# The parser. Takes an array of tokens and returns an AST. Methods
 141# other than parse(tokens) are not for public consumption.
 142#
 143
 144class Parser
 145 def initialize(tokens)
 146 @tokens = tokens
 147 @idx = 0
 148 end
 149
 150 def parseError(*comment)
 151 if @tokens[@idx]
 152 @tokens[@idx].parseError(*comment)
 153 else
 154 if comment.empty?
 155 raise "Parse error at end of file"
 156 else
 157 raise "Parse error at end of file: #{comment[0]}"
 158 end
 159 end
 160 end
 161
 162 def consume(regexp)
 163 if regexp
 164 parseError unless @tokens[@idx] =~ regexp
 165 else
 166 parseError unless @idx == @tokens.length
 167 end
 168 @idx += 1
 169 end
 170
 171 def skipNewLine
 172 while @tokens[@idx] == "\n"
 173 @idx += 1
 174 end
 175 end
 176
 177 def parsePredicateAtom
 178 if @tokens[@idx] == "not"
 179 @idx += 1
 180 parsePredicateAtom
 181 elsif @tokens[@idx] == "("
 182 @idx += 1
 183 skipNewLine
 184 result = parsePredicate
 185 parseError unless @tokens[@idx] == ")"
 186 @idx += 1
 187 result
 188 elsif @tokens[@idx] == "true"
 189 result = True.instance
 190 @idx += 1
 191 result
 192 elsif @tokens[@idx] == "false"
 193 result = False.instance
 194 @idx += 1
 195 result
 196 elsif isIdentifier @tokens[@idx]
 197 result = Setting.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 198 @idx += 1
 199 result
 200 else
 201 parseError
 202 end
 203 end
 204
 205 def parsePredicateAnd
 206 result = parsePredicateAtom
 207 while @tokens[@idx] == "and"
 208 codeOrigin = @tokens[@idx].codeOrigin
 209 @idx += 1
 210 skipNewLine
 211 right = parsePredicateAtom
 212 result = And.new(codeOrigin, result, right)
 213 end
 214 result
 215 end
 216
 217 def parsePredicate
 218 # some examples of precedence:
 219 # not a and b -> (not a) and b
 220 # a and b or c -> (a and b) or c
 221 # a or b and c -> a or (b and c)
 222
 223 result = parsePredicateAnd
 224 while @tokens[@idx] == "or"
 225 codeOrigin = @tokens[@idx].codeOrigin
 226 @idx += 1
 227 skipNewLine
 228 right = parsePredicateAnd
 229 result = Or.new(codeOrigin, result, right)
 230 end
 231 result
 232 end
 233
 234 def parseVariable
 235 if isRegister(@tokens[@idx])
 236 if @tokens[@idx] =~ FPR_PATTERN
 237 result = FPRegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 238 else
 239 result = RegisterID.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 240 end
 241 elsif isIdentifier(@tokens[@idx])
 242 result = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 243 else
 244 parseError
 245 end
 246 @idx += 1
 247 result
 248 end
 249
 250 def parseAddress(offset)
 251 parseError unless @tokens[@idx] == "["
 252 codeOrigin = @tokens[@idx].codeOrigin
 253
 254 # Three possibilities:
 255 # [] -> AbsoluteAddress
 256 # [a] -> Address
 257 # [a,b] -> BaseIndex with scale = 1
 258 # [a,b,c] -> BaseIndex
 259
 260 @idx += 1
 261 if @tokens[@idx] == "]"
 262 @idx += 1
 263 return AbsoluteAddress.new(codeOrigin, offset)
 264 end
 265 a = parseVariable
 266 if @tokens[@idx] == "]"
 267 result = Address.new(codeOrigin, a, offset)
 268 else
 269 parseError unless @tokens[@idx] == ","
 270 @idx += 1
 271 b = parseVariable
 272 if @tokens[@idx] == "]"
 273 result = BaseIndex.new(codeOrigin, a, b, 1, offset)
 274 else
 275 parseError unless @tokens[@idx] == ","
 276 @idx += 1
 277 parseError unless ["1", "2", "4", "8"].member? @tokens[@idx].string
 278 c = @tokens[@idx].string.to_i
 279 @idx += 1
 280 parseError unless @tokens[@idx] == "]"
 281 result = BaseIndex.new(codeOrigin, a, b, c, offset)
 282 end
 283 end
 284 @idx += 1
 285 result
 286 end
 287
 288 def parseColonColon
 289 skipNewLine
 290 codeOrigin = @tokens[@idx].codeOrigin
 291 parseError unless isIdentifier @tokens[@idx]
 292 names = [@tokens[@idx].string]
 293 @idx += 1
 294 while @tokens[@idx] == "::"
 295 @idx += 1
 296 parseError unless isIdentifier @tokens[@idx]
 297 names << @tokens[@idx].string
 298 @idx += 1
 299 end
 300 raise if names.empty?
 301 [codeOrigin, names]
 302 end
 303
 304 def parseExpressionAtom
 305 skipNewLine
 306 if @tokens[@idx] == "-"
 307 @idx += 1
 308 NegImmediate.new(@tokens[@idx - 1].codeOrigin, parseExpressionAtom)
 309 elsif @tokens[@idx] == "("
 310 @idx += 1
 311 result = parseExpression
 312 parseError unless @tokens[@idx] == ")"
 313 @idx += 1
 314 result
 315 elsif isInteger @tokens[@idx]
 316 result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
 317 @idx += 1
 318 result
 319 elsif isIdentifier @tokens[@idx]
 320 codeOrigin, names = parseColonColon
 321 if names.size > 1
 322 StructOffset.forField(codeOrigin, names[0..-2].join('::'), names[-1])
 323 else
 324 Variable.forName(codeOrigin, names[0])
 325 end
 326 elsif isRegister @tokens[@idx]
 327 parseVariable
 328 elsif @tokens[@idx] == "sizeof"
 329 @idx += 1
 330 codeOrigin, names = parseColonColon
 331 Sizeof.forName(codeOrigin, names.join('::'))
 332 else
 333 parseError
 334 end
 335 end
 336
 337 def parseExpressionMul
 338 skipNewLine
 339 result = parseExpressionAtom
 340 while @tokens[@idx] == "*"
 341 if @tokens[@idx] == "*"
 342 @idx += 1
 343 result = MulImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionAtom)
 344 else
 345 raise
 346 end
 347 end
 348 result
 349 end
 350
 351 def couldBeExpression
 352 @tokens[@idx] == "-" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
 353 end
 354
 355 def parseExpression
 356 skipNewLine
 357 result = parseExpressionMul
 358 while @tokens[@idx] == "+" or @tokens[@idx] == "-"
 359 if @tokens[@idx] == "+"
 360 @idx += 1
 361 result = AddImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
 362 elsif @tokens[@idx] == "-"
 363 @idx += 1
 364 result = SubImmediates.new(@tokens[@idx - 1].codeOrigin, result, parseExpressionMul)
 365 else
 366 raise
 367 end
 368 end
 369 result
 370 end
 371
 372 def parseOperand(comment)
 373 if couldBeExpression
 374 expr = parseExpression
 375 if @tokens[@idx] == "["
 376 parseAddress(expr)
 377 else
 378 expr
 379 end
 380 elsif @tokens[@idx] == "["
 381 parseAddress(Immediate.new(@tokens[@idx].codeOrigin, 0))
 382 elsif isLabel @tokens[@idx]
 383 result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
 384 @idx += 1
 385 result
 386 elsif isLocalLabel @tokens[@idx]
 387 result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
 388 @idx += 1
 389 result
 390 else
 391 parseError(comment)
 392 end
 393 end
 394
 395 def parseMacroVariables
 396 skipNewLine
 397 consume(/\A\(\Z/)
 398 variables = []
 399 loop {
 400 skipNewLine
 401 if @tokens[@idx] == ")"
 402 @idx += 1
 403 break
 404 elsif isIdentifier(@tokens[@idx])
 405 variables << Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 406 @idx += 1
 407 skipNewLine
 408 if @tokens[@idx] == ")"
 409 @idx += 1
 410 break
 411 elsif @tokens[@idx] == ","
 412 @idx += 1
 413 else
 414 parseError
 415 end
 416 else
 417 parseError
 418 end
 419 }
 420 variables
 421 end
 422
 423 def parseSequence(final, comment)
 424 firstCodeOrigin = @tokens[@idx].codeOrigin
 425 list = []
 426 loop {
 427 if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
 428 break
 429 elsif @tokens[@idx] == "\n"
 430 # ignore
 431 @idx += 1
 432 elsif @tokens[@idx] == "const"
 433 @idx += 1
 434 parseError unless isVariable @tokens[@idx]
 435 variable = Variable.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string)
 436 @idx += 1
 437 parseError unless @tokens[@idx] == "="
 438 @idx += 1
 439 value = parseOperand("while inside of const #{variable.name}")
 440 list << ConstDecl.new(@tokens[@idx].codeOrigin, variable, value)
 441 elsif @tokens[@idx] == "error"
 442 list << Error.new(@tokens[@idx].codeOrigin)
 443 @idx += 1
 444 elsif @tokens[@idx] == "if"
 445 codeOrigin = @tokens[@idx].codeOrigin
 446 @idx += 1
 447 skipNewLine
 448 predicate = parsePredicate
 449 consume(/\A((then)|(\n))\Z/)
 450 skipNewLine
 451 ifThenElse = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
 452 list << ifThenElse
 453 while @tokens[@idx] == "elsif"
 454 codeOrigin = @tokens[@idx].codeOrigin
 455 @idx += 1
 456 skipNewLine
 457 predicate = parsePredicate
 458 consume(/\A((then)|(\n))\Z/)
 459 skipNewLine
 460 elseCase = IfThenElse.new(codeOrigin, predicate, parseSequence(/\A((else)|(end)|(elsif))\Z/, "while inside of \"if #{predicate.dump}\""))
 461 ifThenElse.elseCase = elseCase
 462 ifThenElse = elseCase
 463 end
 464 if @tokens[@idx] == "else"
 465 @idx += 1
 466 ifThenElse.elseCase = parseSequence(/\Aend\Z/, "while inside of else case for \"if #{predicate.dump}\"")
 467 @idx += 1
 468 else
 469 parseError unless @tokens[@idx] == "end"
 470 @idx += 1
 471 end
 472 elsif @tokens[@idx] == "macro"
 473 codeOrigin = @tokens[@idx].codeOrigin
 474 @idx += 1
 475 skipNewLine
 476 parseError unless isIdentifier(@tokens[@idx])
 477 name = @tokens[@idx].string
 478 @idx += 1
 479 variables = parseMacroVariables
 480 body = parseSequence(/\Aend\Z/, "while inside of macro #{name}")
 481 @idx += 1
 482 list << Macro.new(codeOrigin, name, variables, body)
 483 elsif isInstruction @tokens[@idx]
 484 codeOrigin = @tokens[@idx].codeOrigin
 485 name = @tokens[@idx].string
 486 @idx += 1
 487 if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
 488 # Zero operand instruction, and it's the last one.
 489 list << Instruction.new(codeOrigin, name, [])
 490 break
 491 elsif @tokens[@idx] == "\n"
 492 # Zero operand instruction.
 493 list << Instruction.new(codeOrigin, name, [])
 494 @idx += 1
 495 else
 496 # It's definitely an instruction, and it has at least one operand.
 497 operands = []
 498 endOfSequence = false
 499 loop {
 500 operands << parseOperand("while inside of instruction #{name}")
 501 if (not final and @idx == @tokens.size) or (final and @tokens[@idx] =~ final)
 502 # The end of the instruction and of the sequence.
 503 endOfSequence = true
 504 break
 505 elsif @tokens[@idx] == ","
 506 # Has another operand.
 507 @idx += 1
 508 elsif @tokens[@idx] == "\n"
 509 # The end of the instruction.
 510 @idx += 1
 511 break
 512 else
 513 parseError("Expected a comma, newline, or #{final} after #{operands.last.dump}")
 514 end
 515 }
 516 list << Instruction.new(codeOrigin, name, operands)
 517 if endOfSequence
 518 break
 519 end
 520 end
 521 elsif isIdentifier @tokens[@idx]
 522 codeOrigin = @tokens[@idx].codeOrigin
 523 name = @tokens[@idx].string
 524 @idx += 1
 525 if @tokens[@idx] == "("
 526 # Macro invocation.
 527 @idx += 1
 528 operands = []
 529 skipNewLine
 530 if @tokens[@idx] == ")"
 531 @idx += 1
 532 else
 533 loop {
 534 skipNewLine
 535 if @tokens[@idx] == "macro"
 536 # It's a macro lambda!
 537 codeOriginInner = @tokens[@idx].codeOrigin
 538 @idx += 1
 539 variables = parseMacroVariables
 540 body = parseSequence(/\Aend\Z/, "while inside of anonymous macro passed as argument to #{name}")
 541 @idx += 1
 542 operands << Macro.new(codeOriginInner, nil, variables, body)
 543 else
 544 operands << parseOperand("while inside of macro call to #{name}")
 545 end
 546 skipNewLine
 547 if @tokens[@idx] == ")"
 548 @idx += 1
 549 break
 550 elsif @tokens[@idx] == ","
 551 @idx += 1
 552 else
 553 parseError "Unexpected #{@tokens[@idx].string.inspect} while parsing invocation of macro #{name}"
 554 end
 555 }
 556 end
 557 list << MacroCall.new(codeOrigin, name, operands)
 558 else
 559 parseError "Expected \"(\" after #{name}"
 560 end
 561 elsif isLabel @tokens[@idx] or isLocalLabel @tokens[@idx]
 562 codeOrigin = @tokens[@idx].codeOrigin
 563 name = @tokens[@idx].string
 564 @idx += 1
 565 parseError unless @tokens[@idx] == ":"
 566 # It's a label.
 567 if isLabel name
 568 list << Label.forName(codeOrigin, name)
 569 else
 570 list << LocalLabel.forName(codeOrigin, name)
 571 end
 572 @idx += 1
 573 else
 574 parseError "Expecting terminal #{final} #{comment}"
 575 end
 576 }
 577 Sequence.new(firstCodeOrigin, list)
 578 end
 579end
 580
 581def parse(tokens)
 582 parser = Parser.new(tokens)
 583 parser.parseSequence(nil, "")
 584end
 585
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 "lr"
 38 ]
 39
 40FPRS =
 41 [
 42 "ft0",
 43 "ft1",
 44 "ft2",
 45 "ft3",
 46 "ft4",
 47 "ft5",
 48 "fa0",
 49 "fa1",
 50 "fa2",
 51 "fa3",
 52 "fr"
 53 ]
 54
 55REGISTERS = GPRS + FPRS
 56
 57GPR_PATTERN = Regexp.new('\\A((' + GPRS.join(')|(') + '))\\Z')
 58FPR_PATTERN = Regexp.new('\\A((' + FPRS.join(')|(') + '))\\Z')
 59
 60REGISTER_PATTERN = Regexp.new('\\A((' + REGISTERS.join(')|(') + '))\\Z')
0

Source/JavaScriptCore/offlineasm/self_hash.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
 26require "digest/sha1"
 27require "pathname"
 28
 29#
 30# selfHash -> SHA1 hexdigest
 31#
 32# Returns a hash of the offlineasm source code. This allows dependency
 33# tracking for not just changes in input, but also changes in the assembler
 34# itself.
 35#
 36
 37def selfHash
 38 contents = ""
 39 myPath = Pathname.new(__FILE__).dirname
 40 Dir.foreach(myPath) {
 41 | entry |
 42 if entry =~ /\.rb$/
 43 contents += IO::read(myPath + entry)
 44 end
 45 }
 46 return Digest::SHA1.hexdigest(contents)
 47end
 48
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# computeSettingsCombinations(ast) -> settingsCombiations
 31#
 32# Computes an array of settings maps, where a settings map constitutes
 33# a configuration for the assembly code being generated. The map
 34# contains key value pairs where keys are settings names (strings) and
 35# the values are booleans (true for enabled, false for disabled).
 36#
 37
 38def computeSettingsCombinations(ast)
 39 settingsCombinations = []
 40
 41 def settingsCombinator(settingsCombinations, mapSoFar, remaining)
 42 if remaining.empty?
 43 settingsCombinations << mapSoFar
 44 return
 45 end
 46
 47 newMap = mapSoFar.dup
 48 newMap[remaining[0]] = true
 49 settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
 50
 51 newMap = mapSoFar.dup
 52 newMap[remaining[0]] = false
 53 settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
 54 end
 55
 56 settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + ["X86", "ARMv7"]).uniq)
 57
 58 settingsCombinations
 59end
 60
 61#
 62# forSettings(concreteSettings, ast) {
 63# | concreteSettings, lowLevelAST, backend | ... }
 64#
 65# Determines if the settings combination is valid, and if so, calls
 66# the block with the information you need to generate code.
 67#
 68
 69def forSettings(concreteSettings, ast)
 70 # Check which architectures this combinator claims to support.
 71 numClaimedBackends = 0
 72 selectedBackend = nil
 73 BACKENDS.each {
 74 | backend |
 75 isSupported = concreteSettings[backend]
 76 raise unless isSupported != nil
 77 numClaimedBackends += if isSupported then 1 else 0 end
 78 if isSupported
 79 selectedBackend = backend
 80 end
 81 }
 82
 83 return if numClaimedBackends > 1
 84
 85 # Resolve the AST down to a low-level form (no macros or conditionals).
 86 lowLevelAST = ast.resolveSettings(concreteSettings)
 87
 88 yield concreteSettings, lowLevelAST, selectedBackend
 89end
 90
 91#
 92# forEachValidSettingsCombination(ast) {
 93# | concreteSettings, ast, backend, index | ... }
 94#
 95# forEachValidSettingsCombination(ast, settingsCombinations) {
 96# | concreteSettings, ast, backend, index | ... }
 97#
 98# Executes the given block for each valid settings combination in the
 99# settings map. The ast passed into the block is resolved
 100# (ast.resolve) against the settings.
 101#
 102# The first form will call computeSettingsCombinations(ast) for you.
 103#
 104
 105def forEachValidSettingsCombination(ast, *optionalSettingsCombinations)
 106 raise if optionalSettingsCombinations.size > 1
 107
 108 if optionalSettingsCombinations.empty?
 109 settingsCombinations = computeSettingsCombinations(ast)
 110 else
 111 settingsCombinations = optionalSettingsCombiations[0]
 112 end
 113
 114 settingsCombinations.each_with_index {
 115 | concreteSettings, index |
 116 forSettings(concreteSettings, ast) {
 117 | concreteSettings_, lowLevelAST, backend |
 118 yield concreteSettings, lowLevelAST, backend, index
 119 }
 120 }
 121end
 122
 123#
 124# cppSettingsTest(concreteSettings)
 125#
 126# Returns the C++ code used to test if we are in a configuration that
 127# corresponds to the given concrete settings.
 128#
 129
 130def cppSettingsTest(concreteSettings)
 131 "#if " + concreteSettings.to_a.collect{
 132 | pair |
 133 (if pair[1]
 134 ""
 135 else
 136 "!"
 137 end) + "OFFLINE_ASM_" + pair[0]
 138 }.join(" && ")
 139end
 140
 141#
 142# isASTErroneous(ast)
 143#
 144# Tests to see if the AST claims that there is an error - i.e. if the
 145# user's code, after settings resolution, has Error nodes.
 146#
 147
 148def isASTErroneous(ast)
 149 not ast.filter(Error).empty?
 150end
 151
 152#
 153# assertConfiguration(concreteSettings)
 154#
 155# Emits a check that asserts that we're using the given configuration.
 156#
 157
 158def assertConfiguration(concreteSettings)
 159 $output.puts cppSettingsTest(concreteSettings)
 160 $output.puts "#else"
 161 $output.puts "#error \"Configuration mismatch.\""
 162 $output.puts "#endif"
 163end
 164
 165#
 166# emitCodeInConfiguration(concreteSettings, ast, backend) {
 167# | concreteSettings, ast, backend | ... }
 168#
 169# Emits all relevant guards to see if the configuration holds and
 170# calls the block if the configuration is not erroneous.
 171#
 172
 173def emitCodeInConfiguration(concreteSettings, ast, backend)
 174 $output.puts cppSettingsTest(concreteSettings)
 175
 176 if isASTErroneous(ast)
 177 $output.puts "#error \"Invalid configuration.\""
 178 elsif not WORKING_BACKENDS.include? backend
 179 $output.puts "#error \"This backend is not supported yet.\""
 180 else
 181 yield concreteSettings, ast, backend
 182 end
 183
 184 $output.puts "#endif"
 185end
 186
 187#
 188# emitCodeInAllConfigurations(ast) {
 189# | concreteSettings, ast, backend, index | ... }
 190#
 191# Emits guard codes for all valid configurations, and calls the block
 192# for those configurations that are valid and not erroneous.
 193#
 194
 195def emitCodeInAllConfigurations(ast)
 196 forEachValidSettingsCombination(ast) {
 197 | concreteSettings, lowLevelAST, backend, index |
 198 $output.puts cppSettingsTest(concreteSettings)
 199 yield concreteSettings, lowLevelAST, backend, index
 200 $output.puts "#endif"
 201 }
 202end
 203
 204
 205
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# node.resolveSettings(settings)
 28#
 29# Construct a new AST that does not have any IfThenElse nodes by
 30# substituting concrete boolean values for each Setting.
 31#
 32
 33class Node
 34 def resolveSettings(settings)
 35 mapChildren {
 36 | child |
 37 child.resolveSettings(settings)
 38 }
 39 end
 40end
 41
 42class True
 43 def resolveSettings(settings)
 44 self
 45 end
 46end
 47
 48class False
 49 def resolveSettings(settings)
 50 self
 51 end
 52end
 53
 54class Setting
 55 def resolveSettings(settings)
 56 settings[@name].asNode
 57 end
 58end
 59
 60class And
 61 def resolveSettings(settings)
 62 (@left.resolveSettings(settings).value and @right.resolveSettings(settings).value).asNode
 63 end
 64end
 65
 66class Or
 67 def resolveSettings(settings)
 68 (@left.resolveSettings(settings).value or @right.resolveSettings(settings).value).asNode
 69 end
 70end
 71
 72class Not
 73 def resolveSettings(settings)
 74 (not @child.resolveSettings(settings).value).asNode
 75 end
 76end
 77
 78class IfThenElse
 79 def resolveSettings(settings)
 80 if @predicate.resolveSettings(settings).value
 81 @thenCase.resolveSettings(settings)
 82 else
 83 @elseCase.resolveSettings(settings)
 84 end
 85 end
 86end
 87
 88class Sequence
 89 def resolveSettings(settings)
 90 newList = []
 91 @list.each {
 92 | item |
 93 item = item.resolveSettings(settings)
 94 if item.is_a? Sequence
 95 newList += item.list
 96 else
 97 newList << item
 98 end
 99 }
 100 Sequence.new(codeOrigin, newList)
 101 end
 102end
 103
 104#
 105# node.demacroify(macros)
 106# node.substitute(mapping)
 107#
 108# demacroify() constructs a new AST that does not have any Macro
 109# nodes, while substitute() replaces Variable nodes with the given
 110# nodes in the mapping.
 111#
 112
 113class Node
 114 def demacroify(macros)
 115 mapChildren {
 116 | child |
 117 child.demacroify(macros)
 118 }
 119 end
 120
 121 def substitute(mapping)
 122 mapChildren {
 123 | child |
 124 child.substitute(mapping)
 125 }
 126 end
 127
 128 def substituteLabels(mapping)
 129 mapChildren {
 130 | child |
 131 child.substituteLabels(mapping)
 132 }
 133 end
 134end
 135
 136class Macro
 137 def substitute(mapping)
 138 myMapping = {}
 139 mapping.each_pair {
 140 | key, value |
 141 unless @variables.include? key
 142 myMapping[key] = value
 143 end
 144 }
 145 mapChildren {
 146 | child |
 147 child.substitute(myMapping)
 148 }
 149 end
 150end
 151
 152class Variable
 153 def substitute(mapping)
 154 if mapping[self]
 155 mapping[self]
 156 else
 157 self
 158 end
 159 end
 160end
 161
 162class LocalLabel
 163 def substituteLabels(mapping)
 164 if mapping[self]
 165 mapping[self]
 166 else
 167 self
 168 end
 169 end
 170end
 171
 172class Sequence
 173 def substitute(constants)
 174 newList = []
 175 myConstants = constants.dup
 176 @list.each {
 177 | item |
 178 if item.is_a? ConstDecl
 179 myConstants[item.variable] = item.value.substitute(myConstants)
 180 else
 181 newList << item.substitute(myConstants)
 182 end
 183 }
 184 Sequence.new(codeOrigin, newList)
 185 end
 186
 187 def renameLabels(comment)
 188 mapping = {}
 189
 190 @list.each {
 191 | item |
 192 if item.is_a? LocalLabel
 193 mapping[item] = LocalLabel.unique(if comment then comment + "_" else "" end + item.cleanName)
 194 end
 195 }
 196
 197 substituteLabels(mapping)
 198 end
 199
 200 def demacroify(macros)
 201 myMacros = macros.dup
 202 @list.each {
 203 | item |
 204 if item.is_a? Macro
 205 myMacros[item.name] = item
 206 end
 207 }
 208 newList = []
 209 @list.each {
 210 | item |
 211 if item.is_a? Macro
 212 # Ignore.
 213 elsif item.is_a? MacroCall
 214 mapping = {}
 215 myMyMacros = myMacros.dup
 216 raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros[item.name]
 217 raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
 218 item.operands.size.times {
 219 | idx |
 220 if item.operands[idx].is_a? Variable and myMacros[item.operands[idx].name]
 221 myMyMacros[myMacros[item.name].variables[idx].name] = myMacros[item.operands[idx].name]
 222 mapping[myMacros[item.name].variables[idx].name] = nil
 223 elsif item.operands[idx].is_a? Macro
 224 myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx]
 225 mapping[myMacros[item.name].variables[idx].name] = nil
 226 else
 227 myMyMacros[myMacros[item.name].variables[idx]] = nil
 228 mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
 229 end
 230 }
 231 newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
 232 else
 233 newList << item.demacroify(myMacros)
 234 end
 235 }
 236 Sequence.new(codeOrigin, newList).substitute({})
 237 end
 238end
 239
 240#
 241# node.resolveOffsets(offsets, sizes)
 242#
 243# Construct a new AST that has offset values instead of symbolic
 244# offsets.
 245#
 246
 247class Node
 248 def resolveOffsets(offsets, sizes)
 249 mapChildren {
 250 | child |
 251 child.resolveOffsets(offsets, sizes)
 252 }
 253 end
 254end
 255
 256class StructOffset
 257 def resolveOffsets(offsets, sizes)
 258 if offsets[self]
 259 Immediate.new(codeOrigin, offsets[self])
 260 else
 261 self
 262 end
 263 end
 264end
 265
 266class Sizeof
 267 def resolveOffsets(offsets, sizes)
 268 if sizes[self]
 269 Immediate.new(codeOrigin, sizes[self])
 270 else
 271 puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
 272 puts "sizes = #{sizes.inspect}"
 273 self
 274 end
 275 end
 276end
 277
 278#
 279# node.fold
 280#
 281# Resolve constant references and compute arithmetic expressions.
 282#
 283
 284class Node
 285 def fold
 286 mapChildren {
 287 | child |
 288 child.fold
 289 }
 290 end
 291end
 292
 293class AddImmediates
 294 def fold
 295 @left = @left.fold
 296 @right = @right.fold
 297 return self unless @left.is_a? Immediate
 298 return self unless @right.is_a? Immediate
 299 Immediate.new(codeOrigin, @left.value + @right.value)
 300 end
 301end
 302
 303class SubImmediates
 304 def fold
 305 @left = @left.fold
 306 @right = @right.fold
 307 return self unless @left.is_a? Immediate
 308 return self unless @right.is_a? Immediate
 309 Immediate.new(codeOrigin, @left.value - @right.value)
 310 end
 311end
 312
 313class MulImmediates
 314 def fold
 315 @left = @left.fold
 316 @right = @right.fold
 317 return self unless @left.is_a? Immediate
 318 return self unless @right.is_a? Immediate
 319 Immediate.new(codeOrigin, @left.value * @right.value)
 320 end
 321end
 322
 323class NegImmediate
 324 def fold
 325 @child = @child.fold
 326 return self unless @child.is_a? Immediate
 327 Immediate.new(codeOrigin, -@child.value)
 328 end
 329end
 330
 331#
 332# node.resolveAfterSettings(offsets, sizes)
 333#
 334# Compile assembly against a set of offsets.
 335#
 336
 337class Node
 338 def resolve(offsets, sizes)
 339 demacroify({}).resolveOffsets(offsets, sizes).fold
 340 end
 341end
 342
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 "Bad register #{name} for X86 at #{codeOriginString}"
 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 "Bad register #{name} for X86 at #{codeOriginString}"
 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 x86CallOperand(kind)
 201 asmLabel
 202 end
 203end
 204
 205class LocalLabelReference
 206 def x86CallOperand(kind)
 207 asmLabel
 208 end
 209end
 210
 211class Instruction
 212 def x86Operands(*kinds)
 213 raise unless kinds.size == operands.size
 214 result = []
 215 kinds.size.times {
 216 | idx |
 217 result << operands[idx].x86Operand(kinds[idx])
 218 }
 219 result.join(", ")
 220 end
 221
 222 def x86Suffix(kind)
 223 case kind
 224 when :byte
 225 "b"
 226 when :half
 227 "w"
 228 when :int
 229 "l"
 230 when :double
 231 "sd"
 232 else
 233 raise
 234 end
 235 end
 236
 237 def handleX86OpWithNumOperands(opcode, kind, numOperands)
 238 if numOperands == 3
 239 if operands[0] == operands[2]
 240 $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 241 elsif operands[1] == operands[2]
 242 $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 243 else
 244 $asm.puts "mov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 245 $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
 246 end
 247 else
 248 $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
 249 end
 250 end
 251
 252 def handleX86Op(opcode, kind)
 253 handleX86OpWithNumOperands(opcode, kind, operands.size)
 254 end
 255
 256 def handleX86Shift(opcode, kind)
 257 if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
 258 $asm.puts "#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
 259 else
 260 $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
 261 $asm.puts "#{opcode} %cl, #{operands[1].x86Operand(kind)}"
 262 $asm.puts "xchgl #{operands[0].x86Operand(:int)}, %ecx"
 263 end
 264 end
 265
 266 def handleX86DoubleBranch(branchOpcode, mode)
 267 case mode
 268 when :normal
 269 $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
 270 when :reverse
 271 $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 272 else
 273 raise mode.inspect
 274 end
 275 $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
 276 end
 277
 278 def handleX86IntCompare(opcodeSuffix, kind)
 279 if operands[0].is_a? Immediate and operands[0].value == 0 and operands[1].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
 280 $asm.puts "test#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}"
 281 elsif operands[1].is_a? Immediate and operands[1].value == 0 and operands[0].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
 282 $asm.puts "test#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}"
 283 else
 284 $asm.puts "cmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
 285 end
 286 end
 287
 288 def handleX86IntBranch(branchOpcode, kind)
 289 handleX86IntCompare(branchOpcode[1..-1], kind)
 290 $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
 291 end
 292
 293 def handleX86Set(setOpcode, operand)
 294 if operand.supports8BitOnX86
 295 $asm.puts "#{setOpcode} #{operand.x86Operand(:byte)}"
 296 $asm.puts "movzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
 297 else
 298 $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
 299 $asm.puts "#{setOpcode} %al"
 300 $asm.puts "movzbl %al, %eax"
 301 $asm.puts "xchgl #{operand.x86Operand(:int)}, %eax"
 302 end
 303 end
 304
 305 def handleX86IntCompareSet(setOpcode, kind)
 306 handleX86IntCompare(setOpcode[3..-1], kind)
 307 handleX86Set(setOpcode, operands[2])
 308 end
 309
 310 def handleX86Test(kind)
 311 value = operands[0]
 312 case operands.size
 313 when 2
 314 mask = Immediate.new(codeOrigin, -1)
 315 when 3
 316 mask = operands[1]
 317 else
 318 raise "Expected 2 or 3 operands, but got #{operands.size} at #{codeOriginString}"
 319 end
 320
 321 if mask.is_a? Immediate and mask.value == -1
 322 if value.is_a? RegisterID
 323 $asm.puts "test#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
 324 else
 325 $asm.puts "cmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
 326 end
 327 else
 328 $asm.puts "test#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
 329 end
 330 end
 331
 332 def handleX86BranchTest(branchOpcode, kind)
 333 handleX86Test(kind)
 334 $asm.puts "#{branchOpcode} #{operands.last.asmLabel}"
 335 end
 336
 337 def handleX86SetTest(setOpcode, kind)
 338 handleX86Test(kind)
 339 handleX86Set(setOpcode, operands.last)
 340 end
 341
 342 def handleX86OpBranch(opcode, branchOpcode, kind)
 343 handleX86OpWithNumOperands(opcode, kind, operands.size - 1)
 344 case operands.size
 345 when 4
 346 jumpTarget = operands[3]
 347 when 3
 348 jumpTarget = operands[2]
 349 else
 350 raise self.inspect
 351 end
 352 $asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
 353 end
 354
 355 def handleX86SubBranch(branchOpcode, kind)
 356 if operands.size == 4 and operands[1] == operands[2]
 357 $asm.puts "negl #{operands[2].x86Operand(:int)}"
 358 $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 359 else
 360 handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
 361 end
 362 case operands.size
 363 when 4
 364 jumpTarget = operands[3]
 365 when 3
 366 jumpTarget = operands[2]
 367 else
 368 raise self.inspect
 369 end
 370 $asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
 371 end
 372
 373 def lowerX86
 374 $asm.comment codeOriginString
 375 case opcode
 376 when "addi", "addp"
 377 if operands.size == 3 and operands[0].is_a? Immediate
 378 raise unless operands[1].is_a? RegisterID
 379 raise unless operands[2].is_a? RegisterID
 380 if operands[0].value == 0
 381 unless operands[1] == operands[2]
 382 $asm.puts "movl #{operands[1].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 383 end
 384 else
 385 $asm.puts "leal #{operands[0].value}(#{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
 386 end
 387 elsif operands.size == 3 and operands[0].is_a? RegisterID
 388 raise unless operands[1].is_a? RegisterID
 389 raise unless operands[2].is_a? RegisterID
 390 $asm.puts "leal (#{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}), #{operands[2].x86Operand(:int)}"
 391 else
 392 unless Immediate.new(nil, 0) == operands[0]
 393 $asm.puts "addl #{x86Operands(:int, :int)}"
 394 end
 395 end
 396 when "andi", "andp"
 397 handleX86Op("andl", :int)
 398 when "lshifti"
 399 handleX86Shift("sall", :int)
 400 when "muli"
 401 if operands.size == 3 and operands[0].is_a? Immediate
 402 $asm.puts "imull #{x86Operands(:int, :int, :int)}"
 403 else
 404 # FIXME: could do some peephole in case the left operand is immediate and it's
 405 # a power of two.
 406 handleX86Op("imull", :int)
 407 end
 408 when "negi"
 409 $asm.puts "negl #{x86Operands(:int)}"
 410 when "noti"
 411 $asm.puts "notl #{x86Operands(:int)}"
 412 when "ori", "orp"
 413 handleX86Op("orl", :int)
 414 when "rshifti"
 415 handleX86Shift("sarl", :int)
 416 when "urshifti"
 417 handleX86Shift("shrl", :int)
 418 when "subi", "subp"
 419 if operands.size == 3 and operands[1] == operands[2]
 420 $asm.puts "negl #{operands[2].x86Operand(:int)}"
 421 $asm.puts "addl #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:int)}"
 422 else
 423 handleX86Op("subl", :int)
 424 end
 425 when "xori", "xorp"
 426 handleX86Op("xorl", :int)
 427 when "loadi", "storei", "loadp", "storep"
 428 $asm.puts "movl #{x86Operands(:int, :int)}"
 429 when "loadb"
 430 $asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
 431 when "loadbs"
 432 $asm.puts "movsbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
 433 when "loadh"
 434 $asm.puts "movzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
 435 when "loadhs"
 436 $asm.puts "movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
 437 when "storeb"
 438 $asm.puts "movb #{x86Operands(:byte, :byte)}"
 439 when "loadd", "moved", "stored"
 440 $asm.puts "movsd #{x86Operands(:double, :double)}"
 441 when "addd"
 442 $asm.puts "addsd #{x86Operands(:double, :double)}"
 443 when "divd"
 444 $asm.puts "divsd #{x86Operands(:double, :double)}"
 445 when "subd"
 446 $asm.puts "subsd #{x86Operands(:double, :double)}"
 447 when "muld"
 448 $asm.puts "mulsd #{x86Operands(:double, :double)}"
 449 when "sqrtd"
 450 $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 451 when "ci2d"
 452 $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
 453 when "bdeq"
 454 isUnordered = LocalLabel.unique("bdeq")
 455 $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 456 $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
 457 $asm.puts "je #{LabelReference.new(codeOrigin, operands[2]).asmLabel}"
 458 isUnordered.lower("X86")
 459 when "bdneq"
 460 handleX86DoubleBranch("jne", :normal)
 461 when "bdgt"
 462 handleX86DoubleBranch("ja", :normal)
 463 when "bdgteq"
 464 handleX86DoubleBranch("jae", :normal)
 465 when "bdlt"
 466 handleX86DoubleBranch("ja", :reverse)
 467 when "bdlteq"
 468 handleX86DoubleBranch("jae", :reverse)
 469 when "bdequn"
 470 handleX86DoubleBranch("je", :normal)
 471 when "bdnequn"
 472 isUnordered = LocalLabel.unique("bdnequn")
 473 isEqual = LocalLabel.unique("bdnequn")
 474 $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
 475 $asm.puts "jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
 476 $asm.puts "je #{LabelReference.new(codeOrigin, isEqual).asmLabel}"
 477 isUnordered.lower("X86")
 478 $asm.puts "jmp #{operands[2].asmLabel}"
 479 isEqual.lower("X86")
 480 when "bdgtun"
 481 handleX86DoubleBranch("jb", :reverse)
 482 when "bdgtequn"
 483 handleX86DoubleBranch("jbe", :reverse)
 484 when "bdltun"
 485 handleX86DoubleBranch("jb", :normal)
 486 when "bdltequn"
 487 handleX86DoubleBranch("jbe", :normal)
 488 when "btd2i"
 489 $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 490 $asm.puts "cmpl $0x80000000 #{operands[1].x86Operand(:int)}"
 491 $asm.puts "je #{operands[2].asmLabel}"
 492 when "td2i"
 493 $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 494 when "bcd2i"
 495 $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 496 $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
 497 $asm.puts "je #{operands[2].asmLabel}"
 498 $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
 499 $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
 500 $asm.puts "jp #{operands[2].asmLabel}"
 501 $asm.puts "jne #{operands[2].asmLabel}"
 502 when "movdz"
 503 $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
 504 when "pop"
 505 $asm.puts "pop #{operands[0].x86Operand(:int)}"
 506 when "push"
 507 $asm.puts "push #{operands[0].x86Operand(:int)}"
 508 when "move", "sxi2p", "zxi2p"
 509 if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
 510 $asm.puts "xorl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
 511 elsif operands[0] != operands[1]
 512 $asm.puts "movl #{x86Operands(:int, :int)}"
 513 end
 514 when "nop"
 515 $asm.puts "nop"
 516 when "bieq", "bpeq"
 517 handleX86IntBranch("je", :int)
 518 when "bineq", "bpneq"
 519 handleX86IntBranch("jne", :int)
 520 when "bia", "bpa"
 521 handleX86IntBranch("ja", :int)
 522 when "biaeq", "bpaeq"
 523 handleX86IntBranch("jae", :int)
 524 when "bib", "bpb"
 525 handleX86IntBranch("jb", :int)
 526 when "bibeq", "bpbeq"
 527 handleX86IntBranch("jbe", :int)
 528 when "bigt", "bpgt"
 529 handleX86IntBranch("jg", :int)
 530 when "bigteq", "bpgteq"
 531 handleX86IntBranch("jge", :int)
 532 when "bilt", "bplt"
 533 handleX86IntBranch("jl", :int)
 534 when "bilteq", "bplteq"
 535 handleX86IntBranch("jle", :int)
 536 when "bbeq"
 537 handleX86IntBranch("je", :byte)
 538 when "bbneq"
 539 handleX86IntBranch("jne", :byte)
 540 when "bba"
 541 handleX86IntBranch("ja", :byte)
 542 when "bbaeq"
 543 handleX86IntBranch("jae", :byte)
 544 when "bbb"
 545 handleX86IntBranch("jb", :byte)
 546 when "bbbeq"
 547 handleX86IntBranch("jbe", :byte)
 548 when "bbgt"
 549 handleX86IntBranch("jg", :byte)
 550 when "bbgteq"
 551 handleX86IntBranch("jge", :byte)
 552 when "bblt"
 553 handleX86IntBranch("jl", :byte)
 554 when "bblteq"
 555 handleX86IntBranch("jlteq", :byte)
 556 when "btio", "btpo"
 557 handleX86BranchTest("jo", :int)
 558 when "btis", "btps"
 559 handleX86BranchTest("js", :int)
 560 when "btiz", "btpz"
 561 handleX86BranchTest("jz", :int)
 562 when "btinz", "btpnz"
 563 handleX86BranchTest("jnz", :int)
 564 when "btbo"
 565 handleX86BranchTest("jo", :byte)
 566 when "btbs"
 567 handleX86BranchTest("js", :byte)
 568 when "btbz"
 569 handleX86BranchTest("jz", :byte)
 570 when "btbnz"
 571 handleX86BranchTest("jnz", :byte)
 572 when "jmp"
 573 $asm.puts "jmp #{operands[0].x86CallOperand(:int)}"
 574 when "baddio", "baddpo"
 575 handleX86OpBranch("addl", "jo", :int)
 576 when "baddis", "baddps"
 577 handleX86OpBranch("addl", "js", :int)
 578 when "baddiz", "baddpz"
 579 handleX86OpBranch("addl", "jz", :int)
 580 when "baddinz", "baddpnz"
 581 handleX86OpBranch("addl", "jnz", :int)
 582 when "bsubio"
 583 handleX86SubBranch("jo", :int)
 584 when "bsubis"
 585 handleX86SubBranch("js", :int)
 586 when "bsubiz"
 587 handleX86SubBranch("jz", :int)
 588 when "bsubinz"
 589 handleX86SubBranch("jnz", :int)
 590 when "bmulio"
 591 handleX86OpBranch("imull", "jo", :int)
 592 when "bmulis"
 593 handleX86OpBranch("imull", "js", :int)
 594 when "bmuliz"
 595 handleX86OpBranch("imull", "jz", :int)
 596 when "bmulinz"
 597 handleX86OpBranch("imull", "jnz", :int)
 598 when "borio"
 599 handleX86OpBranch("orl", "jo", :int)
 600 when "boris"
 601 handleX86OpBranch("orl", "js", :int)
 602 when "boriz"
 603 handleX86OpBranch("orl", "jz", :int)
 604 when "borinz"
 605 handleX86OpBranch("orl", "jnz", :int)
 606 when "break"
 607 $asm.puts "int $3"
 608 when "call"
 609 $asm.puts "call #{operands[0].x86CallOperand(:int)}"
 610 when "ret"
 611 $asm.puts "ret"
 612 when "cieq", "cpeq"
 613 handleX86IntCompareSet("sete", :int)
 614 when "cineq", "cpneq"
 615 handleX86IntCompareSet("setne", :int)
 616 when "cia", "cpa"
 617 handleX86IntCompareSet("seta", :int)
 618 when "ciaeq", "cpaeq"
 619 handleX86IntCompareSet("setae", :int)
 620 when "cib", "cpb"
 621 handleX86IntCompareSet("setb", :int)
 622 when "cibeq", "cpbeq"
 623 handleX86IntCompareSet("setbe", :int)
 624 when "cigt", "cpgt"
 625 handleX86IntCompareSet("setg", :int)
 626 when "cigteq", "cpgteq"
 627 handleX86IntCompareSet("setge", :int)
 628 when "cilt", "cplt"
 629 handleX86IntCompareSet("setl", :int)
 630 when "cilteq", "cplteq"
 631 handleX86IntCompareSet("setle", :int)
 632 when "tio"
 633 handleX86SetTest("seto", :int)
 634 when "tis"
 635 handleX86SetTest("sets", :int)
 636 when "tiz"
 637 handleX86SetTest("setz", :int)
 638 when "tinz"
 639 handleX86SetTest("setnz", :int)
 640 when "tbo"
 641 handleX86SetTest("seto", :byte)
 642 when "tbs"
 643 handleX86SetTest("sets", :byte)
 644 when "tbz"
 645 handleX86SetTest("setz", :byte)
 646 when "tbnz"
 647 handleX86SetTest("setnz", :byte)
 648 when "peek"
 649 $asm.puts "movl #{operands[0].value * 4}(%esp), #{operands[1].x86Operand(:int)}"
 650 when "poke"
 651 $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].value * 4}(%esp)"
 652 when "cdqi"
 653 $asm.puts "cdq"
 654 when "idivi"
 655 $asm.puts "idivl #{operands[0].x86Operand(:int)}"
 656 when "fii2d"
 657 $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
 658 $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
 659 $asm.puts "psllq $32, %xmm7"
 660 $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
 661 when "fd2ii"
 662 $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
 663 $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
 664 $asm.puts "psrlq $32, %xmm7"
 665 $asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}"
 666 when "bo"
 667 $asm.puts "jo #{operands[0].asmLabel}"
 668 when "bs"
 669 $asm.puts "js #{operands[0].asmLabel}"
 670 when "bz"
 671 $asm.puts "jz #{operands[0].asmLabel}"
 672 when "bnz"
 673 $asm.puts "jnz #{operands[0].asmLabel}"
 674 else
 675 raise "Bad opcode: #{opcode}"
 676 end
 677 end
 678end
 679
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()
106297

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
106297

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)
106297

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);
106297

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:
106297

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 };
106297

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&);
106297

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}
106297

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();
106297

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);
106297

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 {
270271 JSObject(JSGlobalData&, Structure*, PropertyStorage inlineStorage);
271272
272273 private:
 274 friend class LLIntOffsetsExtractor;
 275
273276 // Nobody should ever ask any of these questions on something already known to be a JSObject.
274277 using JSCell::isAPIValueWrapper;
275278 using JSCell::isGetterSetter;

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

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;
106297

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;
106297

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
106297

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
106297

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>);
106297

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;
106297

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);
106297

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;
106297

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
106297

Source/JavaScriptCore/runtime/Structure.cpp

@@Structure* Structure::addPropertyTransit
322322 transition->growPropertyStorageCapacity();
323323 return transition;
324324 }
325 
 325
326326 Structure* transition = create(globalData, structure);
327327
328328 transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get());
106297

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*);
106297

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;
106297

Source/JavaScriptCore/wtf/InlineASM.h

7070#define HIDE_SYMBOL(name)
7171#endif
7272
 73// FIXME: figure out how this works on all the platforms. I know that
 74// on Linux, the preferred form is ".Lstuff" as opposed to "Lstuff".
 75// Don't know about any of the others.
 76#if PLATFORM(MAC)
 77#define LOCAL_LABEL_STRING(name) "L" #name
 78#endif
 79
7380#endif // InlineASM_h
106297

Source/JavaScriptCore/wtf/Platform.h

923923#define ENABLE_JIT 1
924924#endif
925925
 926/* On some of the platforms where we have a JIT, we want to also have the
 927 low-level interpreter. */
 928#if !defined(ENABLE_LLINT) && ENABLE(JIT) && OS(DARWIN) && (CPU(X86) || CPU(ARM_THUMB2)) && USE(JSVALUE32_64)
 929#define ENABLE_LLINT 1
 930#endif
 931
 932/* If we have LLInt enabled and the JIT enabled, we also enable OSRing from
 933 LLInt to the JIT. */
 934#if !defined(ENABLE_LLINT_OSR_TO_JIT) && ENABLE(JIT) && ENABLE(LLINT)
 935#define ENABLE_LLINT_OSR_TO_JIT 0
 936#endif
 937
926938#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
927939/* Enable the DFG JIT on X86 and X86_64. Only tested on Mac and GNU/Linux. */
928940#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
106297

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;
106297

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,
106297

Source/WebCore/ChangeLog

 12012-01-26 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 Changed EFL's build system to include a new directory in JavaScriptCore.
 10
 11 No new tests because no behavior changed.
 12
 13 * CMakeLists.txt:
 14
1152012-01-30 Levi Weintraub <leviw@chromium.org>
216
317 !m_insideRegionPaint assertion in RenderRegion.cpp is invalid
106297

Source/WebCore/CMakeLists.txt

@@SET(WebCore_INCLUDE_DIRECTORIES
7474 "${JAVASCRIPTCORE_DIR}/debugger"
7575 "${JAVASCRIPTCORE_DIR}/interpreter"
7676 "${JAVASCRIPTCORE_DIR}/jit"
 77 "${JAVASCRIPTCORE_DIR}/llint"
7778 "${JAVASCRIPTCORE_DIR}/parser"
7879 "${JAVASCRIPTCORE_DIR}/profiler"
7980 "${JAVASCRIPTCORE_DIR}/runtime"
106297

Source/WebKit/ChangeLog

 12012-01-26 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 Changed EFL's build system to include a new directory in JavaScriptCore.
 10
 11 * CMakeLists.txt:
 12
1132012-01-11 Jacky Jiang <zhajiang@rim.com>
214
315 [BlackBerry] ASSERT failure in BackingStorePrivate::blitVisibleContents()
106297

Source/WebKit/CMakeLists.txt

@@SET(WebKit_INCLUDE_DIRECTORIES
4444 "${JAVASCRIPTCORE_DIR}/debugger"
4545 "${JAVASCRIPTCORE_DIR}/interpreter"
4646 "${JAVASCRIPTCORE_DIR}/jit"
 47 "${JAVASCRIPTCORE_DIR}/llint"
4748 "${JAVASCRIPTCORE_DIR}/parser"
4849 "${JAVASCRIPTCORE_DIR}/profiler"
4950 "${JAVASCRIPTCORE_DIR}/runtime"
106297

Tools/ChangeLog

 12012-01-27 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 Changed EFL's build system to include a new directory in JavaScriptCore.
 10
 11 * DumpRenderTree/efl/CMakeLists.txt:
 12
1132012-01-30 Ojan Vafai <ojan@chromium.org>
214
315 Parsing test_expecations.txt + Skipped lists takes too long
106297

Tools/DumpRenderTree/efl/CMakeLists.txt

@@SET(DumpRenderTree_INCLUDE_DIRECTORIES
6868 ${JAVASCRIPTCORE_DIR}
6969 ${JAVASCRIPTCORE_DIR}/API
7070 ${JAVASCRIPTCORE_DIR}/assembler
 71 ${JAVASCRIPTCORE_DIR}/bytecode
7172 ${JAVASCRIPTCORE_DIR}/dfg
7273 ${JAVASCRIPTCORE_DIR}/heap
7374 ${JAVASCRIPTCORE_DIR}/interpreter
7475 ${JAVASCRIPTCORE_DIR}/jit
 76 ${JAVASCRIPTCORE_DIR}/llint
7577 ${JAVASCRIPTCORE_DIR}/runtime
7678 ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
7779 ${JAVASCRIPTCORE_DIR}/wtf
106297