Source/JavaScriptCore/ChangeLog

1 2012-01-18 Roland Takacs <takacs.roland@stud.u-szeged.hu>
 12012-01-17 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 WORK IN PROGRESS. It appears to work, but the tiering logic is not
 10 completely glued together yet.
 11
 12 Implemented an interpreter that uses the JIT's calling convention. This
 13 interpreter is called LLInt, or the Low Level Interpreter. JSC will now
 14 will start by executing code in LLInt and will only tier up to the old
 15 JIT after the code is proven hot.
 16
 17 LLInt is written in a modified form of our macro assembly. This new macro
 18 assembly is compiled by an offline assembler (see offlineasm), which
 19 implements many modern conveniences such as a Turing-complete CPS-based
 20 macro language and direct access to relevant C++ type information
 21 (basically offsets of fields and sizes of structs/classes).
 22
 23 Code executing in LLInt appears to the rest of the JSC world "as if" it
 24 were executing in the old JIT. Hence, things like exception handling and
 25 cross-execution-engine calls just work and require pretty much no
 26 additional overhead.
 27
 28 This interpreter is 2-2.5x faster than our old interpreter on SunSpider,
 29 V8, and Kraken. This is the "first attempt" performance - no work has been
 30 done to diagnose any potential bottlenecks. Many obvious ones exist, like
 31 reducing the number of instructions implemented as slow calls to C++ code
 32 and making property access caching more aggressive.
 33
 34 As an additional change, this patch makes bytecode dumping and JSValue
 35 dumping work in release builds, since debugging some of the nastier
 36 aspects of this patch would have been impossible without that. And I
 37 don't believe that we care about the miniscule code bloat that this
 38 introduces.
 39
 40 * DerivedSources.make:
 41 * JavaScriptCore.xcodeproj/project.pbxproj:
 42 * assembler/LinkBuffer.h:
 43 * bytecode/BytecodeConventions.h: Added.
 44 * bytecode/CodeBlock.cpp:
 45 (JSC::CodeBlock::dump):
 46 (JSC::CodeBlock::CodeBlock):
 47 (JSC::CodeBlock::~CodeBlock):
 48 (JSC::CodeBlock::finalizeUnconditionally):
 49 (JSC::CodeBlock::stronglyVisitStrongReferences):
 50 (JSC::CodeBlock::unlinkCalls):
 51 (JSC::CodeBlock::unlinkIncomingCalls):
 52 (JSC::CodeBlock::bytecodeOffset):
 53 (JSC::ProgramCodeBlock::jettison):
 54 (JSC::EvalCodeBlock::jettison):
 55 (JSC::FunctionCodeBlock::jettison):
 56 (JSC::ProgramCodeBlock::jitCompile):
 57 (JSC::EvalCodeBlock::jitCompile):
 58 (JSC::FunctionCodeBlock::jitCompile):
 59 * bytecode/CodeBlock.h:
 60 (JSC::CodeBlock::baselineVersion):
 61 (JSC::CodeBlock::linkIncomingCall):
 62 (JSC::CodeBlock::bytecodeOffset):
 63 (JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
 64 (JSC::CodeBlock::hasOptimizedReplacement):
 65 (JSC::CodeBlock::addLLIntCallLinkInfo):
 66 (JSC::CodeBlock::addFrequentExitSite):
 67 (JSC::CodeBlock::dontJITAnytimeSoon):
 68 (JSC::CodeBlock::jitAfterWarmUp):
 69 (JSC::CodeBlock::jitSoon):
 70 (JSC::CodeBlock::llintExecuteCounter):
 71 * bytecode/Instruction.h:
 72 (JSC::Instruction::Instruction):
 73 * bytecode/LLIntCallLinkInfo.h: Added.
 74 (JSC::LLIntCallLinkInfo::LLIntCallLinkInfo):
 75 (JSC::LLIntCallLinkInfo::~LLIntCallLinkInfo):
 76 (JSC::LLIntCallLinkInfo::isLinked):
 77 (JSC::LLIntCallLinkInfo::unlink):
 78 * bytecode/Opcode.h:
 79 * bytecompiler/BytecodeGenerator.cpp:
 80 (JSC::BytecodeGenerator::setDumpsGeneratedCode):
 81 (JSC::BytecodeGenerator::dumpsGeneratedCode):
 82 (JSC::BytecodeGenerator::generate):
 83 (JSC::BytecodeGenerator::emitResolve):
 84 (JSC::BytecodeGenerator::emitResolveWithBase):
 85 (JSC::BytecodeGenerator::emitResolveWithThis):
 86 (JSC::BytecodeGenerator::emitGetById):
 87 (JSC::BytecodeGenerator::emitPutById):
 88 (JSC::BytecodeGenerator::emitDirectPutById):
 89 (JSC::BytecodeGenerator::emitCall):
 90 (JSC::BytecodeGenerator::emitConstruct):
 91 (JSC::BytecodeGenerator::emitCatch):
 92 * dfg/DFGByteCodeParser.cpp:
 93 (JSC::DFG::ByteCodeParser::parseBlock):
 94 * dfg/DFGCapabilities.h:
 95 (JSC::DFG::canCompileOpcode):
 96 * dfg/DFGOperations.cpp:
 97 * heap/AllocationSpace.h:
 98 * heap/Heap.cpp:
 99 (JSC::Heap::collect):
 100 * heap/Heap.h:
 101 * heap/MarkedSpace.h:
 102 * interpreter/CallFrame.h:
 103 (JSC::ExecState::currentVPC):
 104 * interpreter/Interpreter.cpp:
 105 (JSC::Interpreter::~Interpreter):
 106 (JSC::Interpreter::initialize):
 107 (JSC::Interpreter::isOpcode):
 108 (JSC::Interpreter::unwindCallFrame):
 109 (JSC::Interpreter::retrieveLastCaller):
 110 * interpreter/Interpreter.h:
 111 (JSC::Interpreter::getOpcode):
 112 (JSC::Interpreter::getOpcodeID):
 113 (JSC::Interpreter::enabled):
 114 * interpreter/RegisterFile.h:
 115 * jit/HostCallReturnValue.cpp: Added.
 116 (JSC::getHostCallReturnValueWithExecState):
 117 * jit/HostCallReturnValue.h: Added.
 118 * jit/JIT.cpp:
 119 (JSC::JIT::privateCompileMainPass):
 120 (JSC::JIT::privateCompileSlowCases):
 121 (JSC::JIT::privateCompile):
 122 * jit/JITCode.h:
 123 (JSC::JITCode::isOptimizingJIT):
 124 (JSC::JITCode::isBaselineCode):
 125 (JSC::JITCode::JITCode):
 126 * jit/JITDriver.h:
 127 (JSC::jitCompileIfAppropriate):
 128 (JSC::jitCompileFunctionIfAppropriate):
 129 * jit/JITExceptions.cpp:
 130 (JSC::jitThrow):
 131 * jit/JITStubs.cpp:
 132 (JSC::DEFINE_STUB_FUNCTION):
 133 * jit/JSInterfaceJIT.h:
 134 * llint: Added.
 135 * llint/LLIntCommon.h: Added.
 136 * llint/LLIntData.cpp: Added.
 137 (JSC::LLInt::Data::Data):
 138 (JSC::LLInt::Data::~Data):
 139 * llint/LLIntData.h: Added.
 140 (JSC::LLInt::Data::exceptionInstructions):
 141 (JSC::LLInt::Data::opcodeMap):
 142 * llint/LLIntEntrypoints.cpp: Added.
 143 (JSC::LLInt::getFunctionEntrypoint):
 144 (JSC::LLInt::getEvalEntrypoint):
 145 (JSC::LLInt::getProgramEntrypoint):
 146 * llint/LLIntEntrypoints.h: Added.
 147 (JSC::LLInt::getEntrypoint):
 148 * llint/LLIntExceptions.cpp: Added.
 149 (JSC::LLInt::interpreterThrow):
 150 (JSC::LLInt::returnToThrowForThrownException):
 151 (JSC::LLInt::returnToThrow):
 152 (JSC::LLInt::callToThrow):
 153 * llint/LLIntExceptions.h: Added.
 154 * llint/LLIntHelpers.cpp: Added.
 155 (JSC::LLInt::llint_trace_operand):
 156 (JSC::LLInt::llint_trace_value):
 157 (JSC::LLInt::LLINT_HELPER_DECL):
 158 (JSC::LLInt::traceFunctionPrologue):
 159 (JSC::LLInt::shouldJIT):
 160 (JSC::LLInt::getByVal):
 161 (JSC::LLInt::handleHostCall):
 162 (JSC::LLInt::setUpCall):
 163 (JSC::LLInt::genericCall):
 164 * llint/LLIntHelpers.h: Added.
 165 * llint/LLIntOfflineAsmConfig.h: Added.
 166 * llint/LLIntOffsetsExtractor.cpp: Added.
 167 (JSC::LLIntOffsetsExtractor::dummy):
 168 (main):
 169 * llint/LLIntThunks.cpp: Added.
 170 (JSC::LLInt::generateThunkWithJumpTo):
 171 (JSC::LLInt::functionForCallEntryThunkGenerator):
 172 (JSC::LLInt::functionForConstructEntryThunkGenerator):
 173 (JSC::LLInt::functionForCallArityCheckThunkGenerator):
 174 (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
 175 (JSC::LLInt::evalEntryThunkGenerator):
 176 (JSC::LLInt::programEntryThunkGenerator):
 177 * llint/LLIntThunks.h: Added.
 178 * llint/LowLevelInterpreter.asm: Added.
 179 * llint/LowLevelInterpreter.cpp: Added.
 180 * llint/LowLevelInterpreter.h: Added.
 181 * offlineasm: Added.
 182 * offlineasm/armv7.rb: Added.
 183 * offlineasm/asm.rb: Added.
 184 * offlineasm/ast.rb: Added.
 185 * offlineasm/backends.rb: Added.
 186 * offlineasm/generate_offset_extractor.rb: Added.
 187 * offlineasm/instructions.rb: Added.
 188 * offlineasm/offset_extractor_constants.rb: Added.
 189 * offlineasm/offsets.rb: Added.
 190 * offlineasm/parser.rb: Added.
 191 * offlineasm/registers.rb: Added.
 192 * offlineasm/settings.rb: Added.
 193 * offlineasm/transform.rb: Added.
 194 * offlineasm/x86.rb: Added.
 195 * runtime/CodeSpecializationKind.h: Added.
 196 * runtime/CommonSlowPaths.h:
 197 (JSC::CommonSlowPaths::arityCheckFor):
 198 * runtime/Executable.cpp:
 199 (JSC::jettisonCodeBlock):
 200 (JSC::EvalExecutable::jitCompile):
 201 (JSC::samplingDescription):
 202 (JSC::EvalExecutable::compileInternal):
 203 (JSC::ProgramExecutable::jitCompile):
 204 (JSC::ProgramExecutable::compileInternal):
 205 (JSC::FunctionExecutable::baselineCodeBlockFor):
 206 (JSC::FunctionExecutable::jitCompileForCall):
 207 (JSC::FunctionExecutable::jitCompileForConstruct):
 208 (JSC::FunctionExecutable::compileForCallInternal):
 209 (JSC::FunctionExecutable::compileForConstructInternal):
 210 * runtime/Executable.h:
 211 (JSC::FunctionExecutable::jitCompileFor):
 212 * runtime/ExecutionHarness.h: Added.
 213 (JSC::prepareForExecution):
 214 (JSC::prepareFunctionForExecution):
 215 * runtime/JSActivation.h:
 216 (JSC::JSActivation::tearOff):
 217 * runtime/JSArray.h:
 218 * runtime/JSCell.h:
 219 * runtime/JSFunction.h:
 220 * runtime/JSGlobalData.cpp:
 221 (JSC::JSGlobalData::JSGlobalData):
 222 * runtime/JSGlobalData.h:
 223 * runtime/JSGlobalObject.h:
 224 * runtime/JSObject.h:
 225 * runtime/JSPropertyNameIterator.h:
 226 * runtime/JSString.h:
 227 * runtime/JSTypeInfo.h:
 228 * runtime/JSValue.cpp:
 229 (JSC::JSValue::description):
 230 * runtime/JSValue.h:
 231 * runtime/JSVariableObject.h:
 232 * runtime/Options.cpp:
 233 (JSC::Options::initializeOptions):
 234 * runtime/Options.h:
 235 * runtime/ScopeChain.h:
 236 * runtime/Structure.h:
 237 * runtime/StructureChain.h:
 238 * wtf/Platform.h:
 239 * wtf/text/StringImpl.h:
 240
 24112-01-18 Roland Takacs <takacs.roland@stud.u-szeged.hu>
2242
3243 Cross-platform processor core counter fix
4244 https://bugs.webkit.org/show_bug.cgi?id=76540
105309

Source/JavaScriptCore/DerivedSources.make

1 # Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
 1# Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
22#
33# Redistribution and use in source and binary forms, with or without
44# modification, are permitted provided that the following conditions

@@all : \
6060 StringConstructor.lut.h \
6161 StringPrototype.lut.h \
6262 docs/bytecode.html \
 63 LLIntAssembly.h.PHONY \
6364#
6465
6566# lookup tables for classes

@@HeaderDetection.h :
104105 echo > $@
105106
106107endif
 108
 109# Assembly for the LowLevelInterpreter
 110
 111# This builds every time because there is no easy way to describe
 112# the dependencies using make. Instead, the assembler will decide on
 113# its own whether or not it did anything that would lead to a change.
 114LLIntAssembly.h.PHONY:
 115 ruby $(JavaScriptCore)/offlineasm/asm.rb $(JavaScriptCore)/llint/LowLevelInterpreter.asm $(BUILT_PRODUCTS_DIR)/JSCLLIntOffsetsExtractor > LLIntAssembly.h
105309

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

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

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

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

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

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

375408 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
376409 86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
377410 86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
378  86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
 411 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
379412 86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
380413 86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; };
381414 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; };

738771/* End PBXBuildFile section */
739772
740773/* Begin PBXContainerItemProxy section */
 774 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */ = {
 775 isa = PBXContainerItemProxy;
 776 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 777 proxyType = 1;
 778 remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
 779 remoteInfo = "LLInt Offsets";
 780 };
 781 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */ = {
 782 isa = PBXContainerItemProxy;
 783 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
 784 proxyType = 1;
 785 remoteGlobalIDString = 0F46808E14BA7E5E00BFE272;
 786 remoteInfo = JSCLLIntOffsetsExtractor;
 787 };
741788 141214BE0A49190E00480255 /* PBXContainerItemProxy */ = {
742789 isa = PBXContainerItemProxy;
743790 containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;

783830/* End PBXContainerItemProxy section */
784831
785832/* Begin PBXCopyFilesBuildPhase section */
 833 0F46808D14BA7E5E00BFE272 /* CopyFiles */ = {
 834 isa = PBXCopyFilesBuildPhase;
 835 buildActionMask = 2147483647;
 836 dstPath = /usr/share/man/man1/;
 837 dstSubfolderSpec = 0;
 838 files = (
 839 );
 840 runOnlyForDeploymentPostprocessing = 1;
 841 };
786842 5DBB1511131D0B130056AD36 /* Copy Support Script */ = {
787843 isa = PBXCopyFilesBuildPhase;
788844 buildActionMask = 12;

823879 0BAC949E1338728400CF135B /* ThreadRestrictionVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadRestrictionVerifier.h; sourceTree = "<group>"; };
824880 0BCD83541485841200EA2003 /* TemporaryChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryChange.h; sourceTree = "<group>"; };
825881 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
 882 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoints.cpp; path = llint/LLIntEntrypoints.cpp; sourceTree = "<group>"; };
 883 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoints.h; path = llint/LLIntEntrypoints.h; sourceTree = "<group>"; };
 884 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntThunks.cpp; path = llint/LLIntThunks.cpp; sourceTree = "<group>"; };
 885 0F0B839814BCF45A00885B4F /* LLIntThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntThunks.h; path = llint/LLIntThunks.h; sourceTree = "<group>"; };
826886 0F0B83A514BCF50400885B4F /* CodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeType.h; sourceTree = "<group>"; };
827887 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandlerInfo.h; sourceTree = "<group>"; };
828888 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionRangeInfo.h; sourceTree = "<group>"; };

833893 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodCallLinkInfo.h; sourceTree = "<group>"; };
834894 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalResolveInfo.h; sourceTree = "<group>"; };
835895 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallReturnOffsetToBytecodeOffset.h; sourceTree = "<group>"; };
 896 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
836897 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
837898 0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
838899 0F21C26614BE5F5E00ADC64B /* JITDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDriver.h; sourceTree = "<group>"; };
 900 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeSpecializationKind.h; sourceTree = "<group>"; };
 901 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; };
 902 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; };
839903 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
840904 0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
841905 0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };

846910 0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
847911 0F46807F14BA572700BFE272 /* JITExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITExceptions.cpp; sourceTree = "<group>"; };
848912 0F46808014BA572700BFE272 /* JITExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITExceptions.h; sourceTree = "<group>"; };
 913 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
 914 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntExceptions.cpp; path = llint/LLIntExceptions.cpp; sourceTree = "<group>"; };
 915 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntExceptions.h; path = llint/LLIntExceptions.h; sourceTree = "<group>"; };
 916 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntHelpers.cpp; path = llint/LLIntHelpers.cpp; sourceTree = "<group>"; };
 917 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntHelpers.h; path = llint/LLIntHelpers.h; sourceTree = "<group>"; };
 918 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntOffsetsExtractor.cpp; path = llint/LLIntOffsetsExtractor.cpp; sourceTree = "<group>"; };
 919 0F4680C514BBB16900BFE272 /* LLIntCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCommon.h; path = llint/LLIntCommon.h; sourceTree = "<group>"; };
 920 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOfflineAsmConfig.h; path = llint/LLIntOfflineAsmConfig.h; sourceTree = "<group>"; };
 921 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LowLevelInterpreter.cpp; path = llint/LowLevelInterpreter.cpp; sourceTree = "<group>"; };
 922 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LowLevelInterpreter.h; path = llint/LowLevelInterpreter.h; sourceTree = "<group>"; };
 923 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntData.cpp; path = llint/LLIntData.cpp; sourceTree = "<group>"; };
 924 0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
 925 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
 926 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
849927 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
850928 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
851929 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; };

15511629/* End PBXFileReference section */
15521630
15531631/* Begin PBXFrameworksBuildPhase section */
 1632 0F46808C14BA7E5E00BFE272 /* Frameworks */ = {
 1633 isa = PBXFrameworksBuildPhase;
 1634 buildActionMask = 2147483647;
 1635 files = (
 1636 );
 1637 runOnlyForDeploymentPostprocessing = 0;
 1638 };
15541639 1412111E0A48793C00480255 /* Frameworks */ = {
15551640 isa = PBXFrameworksBuildPhase;
15561641 buildActionMask = 2147483647;

16091694 141211200A48793C00480255 /* minidom */,
16101695 14BD59BF0A3E8F9000BAF59C /* testapi */,
16111696 6511230514046A4C002B101D /* testRegExp */,
 1697 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
16121698 );
16131699 name = Products;
16141700 sourceTree = "<group>";

16391725 F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
16401726 45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
16411727 F68EBB8C0255D4C601FF60F7 /* config.h */,
 1728 0F46809C14BA7F4D00BFE272 /* llint */,
16421729 1432EBD70A34CAD400717B9F /* API */,
16431730 9688CB120ED12B4E001D649F /* assembler */,
16441731 969A078F0ED1D3AE00F1F681 /* bytecode */,

16771764 tabWidth = 4;
16781765 usesTabs = 0;
16791766 };
 1767 0F46809C14BA7F4D00BFE272 /* llint */ = {
 1768 isa = PBXGroup;
 1769 children = (
 1770 0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
 1771 0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
 1772 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
 1773 0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
 1774 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
 1775 0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
 1776 0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
 1777 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
 1778 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
 1779 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
 1780 0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
 1781 0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
 1782 0F46809F14BA7F8200BFE272 /* LLIntHelpers.cpp */,
 1783 0F4680A014BA7F8200BFE272 /* LLIntHelpers.h */,
 1784 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
 1785 );
 1786 name = llint;
 1787 sourceTree = "<group>";
 1788 };
16801789 141211000A48772600480255 /* tests */ = {
16811790 isa = PBXGroup;
16821791 children = (

17091818 1429D92C0ED22D7000B89619 /* jit */ = {
17101819 isa = PBXGroup;
17111820 children = (
 1821 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
 1822 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
17121823 0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
17131824 0F46808014BA572700BFE272 /* JITExceptions.h */,
17141825 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,

21322243 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
21332244 isa = PBXGroup;
21342245 children = (
 2246 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
 2247 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
21352248 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
21362249 BCF605110E203EF800B9A64D /* ArgList.cpp */,
21372250 BCF605120E203EF800B9A64D /* ArgList.h */,

24922605 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
24932606 isa = PBXGroup;
24942607 children = (
 2608 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
 2609 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
24952610 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
24962611 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */,
24972612 0F0B83B214BCF85E00885B4F /* MethodCallLinkInfo.cpp */,

30303145 86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
30313146 86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
30323147 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
 3148 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
 3149 0F4680A514BA7F8D00BFE272 /* LLIntHelpers.h in Headers */,
30333150 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
 3151 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
 3152 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
 3153 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
 3154 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
 3155 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
 3156 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
 3157 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
30343158 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
30353159 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
30363160 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,

30393163 0F0B83B514BCF86200885B4F /* MethodCallLinkInfo.h in Headers */,
30403164 0F0B83B714BCF8E100885B4F /* GlobalResolveInfo.h in Headers */,
30413165 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
 3166 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
30423167 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
 3168 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
 3169 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
 3170 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
30433171 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
30443172 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
30453173 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,

30523180/* End PBXHeadersBuildPhase section */
30533181
30543182/* Begin PBXNativeTarget section */
 3183 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */ = {
 3184 isa = PBXNativeTarget;
 3185 buildConfigurationList = 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */;
 3186 buildPhases = (
 3187 0F46808B14BA7E5E00BFE272 /* Sources */,
 3188 0F46808C14BA7E5E00BFE272 /* Frameworks */,
 3189 0F46808D14BA7E5E00BFE272 /* CopyFiles */,
 3190 );
 3191 buildRules = (
 3192 );
 3193 dependencies = (
 3194 0F4680B214BA811500BFE272 /* PBXTargetDependency */,
 3195 );
 3196 name = JSCLLIntOffsetsExtractor;
 3197 productName = JSCLLIntOffsetsExtractor;
 3198 productReference = 0F46808F14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3199 productType = "com.apple.product-type.tool";
 3200 };
30553201 1412111F0A48793C00480255 /* minidom */ = {
30563202 isa = PBXNativeTarget;
30573203 buildConfigurationList = 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */;

31783324 14BD59BE0A3E8F9000BAF59C /* testapi */,
31793325 932F5BDA0822A1C700736975 /* jsc */,
31803326 651122F714046A4C002B101D /* testRegExp */,
 3327 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */,
 3328 0F4680A914BA7FD900BFE272 /* LLInt Offsets */,
31813329 );
31823330 };
31833331/* End PBXProject section */
31843332
31853333/* Begin PBXShellScriptBuildPhase section */
 3334 0F4680AA14BA7FD900BFE272 /* Generate Derived Sources */ = {
 3335 isa = PBXShellScriptBuildPhase;
 3336 buildActionMask = 2147483647;
 3337 files = (
 3338 );
 3339 inputPaths = (
 3340 "$(SRCROOT)/llint/LowLevelAssembler.asm",
 3341 );
 3342 name = "Generate Derived Sources";
 3343 outputPaths = (
 3344 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets/LLIntDesiredOffsets.h",
 3345 );
 3346 runOnlyForDeploymentPostprocessing = 0;
 3347 shellPath = /bin/sh;
 3348 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";
 3349 };
31863350 3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */ = {
31873351 isa = PBXShellScriptBuildPhase;
31883352 buildActionMask = 2147483647;

33233487/* End PBXShellScriptBuildPhase section */
33243488
33253489/* Begin PBXSourcesBuildPhase section */
 3490 0F46808B14BA7E5E00BFE272 /* Sources */ = {
 3491 isa = PBXSourcesBuildPhase;
 3492 buildActionMask = 2147483647;
 3493 files = (
 3494 0F4680A714BA7FA100BFE272 /* LLIntOffsetsExtractor.cpp in Sources */,
 3495 );
 3496 runOnlyForDeploymentPostprocessing = 0;
 3497 };
33263498 1412111D0A48793C00480255 /* Sources */ = {
33273499 isa = PBXSourcesBuildPhase;
33283500 buildActionMask = 2147483647;

35803752 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
35813753 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
35823754 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
 3755 0F4680A414BA7F8D00BFE272 /* LLIntHelpers.cpp in Sources */,
 3756 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
35833757 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
 3758 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
 3759 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
 3760 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
 3761 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
 3762 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
35843763 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
35853764 0F0B83B414BCF86000885B4F /* MethodCallLinkInfo.cpp in Sources */,
35863765 F69E86C314C6E551002C2C62 /* NumberOfCores.cpp in Sources */,

35983777/* End PBXSourcesBuildPhase section */
35993778
36003779/* Begin PBXTargetDependency section */
 3780 0F4680B214BA811500BFE272 /* PBXTargetDependency */ = {
 3781 isa = PBXTargetDependency;
 3782 target = 0F4680A914BA7FD900BFE272 /* LLInt Offsets */;
 3783 targetProxy = 0F4680B114BA811500BFE272 /* PBXContainerItemProxy */;
 3784 };
 3785 0F4680B414BA821400BFE272 /* PBXTargetDependency */ = {
 3786 isa = PBXTargetDependency;
 3787 target = 0F46808E14BA7E5E00BFE272 /* JSCLLIntOffsetsExtractor */;
 3788 targetProxy = 0F4680B314BA821400BFE272 /* PBXContainerItemProxy */;
 3789 };
36013790 141214BF0A49190E00480255 /* PBXTargetDependency */ = {
36023791 isa = PBXTargetDependency;
36033792 target = 1412111F0A48793C00480255 /* minidom */;

36313820/* End PBXTargetDependency section */
36323821
36333822/* Begin XCBuildConfiguration section */
 3823 0F46809614BA7E5E00BFE272 /* Debug */ = {
 3824 isa = XCBuildConfiguration;
 3825 buildSettings = {
 3826 ALWAYS_SEARCH_USER_PATHS = NO;
 3827 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3828 COPY_PHASE_STRIP = NO;
 3829 GCC_C_LANGUAGE_STANDARD = gnu99;
 3830 GCC_DYNAMIC_NO_PIC = NO;
 3831 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3832 GCC_OPTIMIZATION_LEVEL = 0;
 3833 GCC_PREPROCESSOR_DEFINITIONS = (
 3834 "DEBUG=1",
 3835 "$(inherited)",
 3836 );
 3837 GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 3838 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3839 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3840 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3841 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3842 GCC_WARN_UNUSED_VARIABLE = YES;
 3843 "HEADER_SEARCH_PATHS[arch=*]" = (
 3844 .,
 3845 icu,
 3846 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3847 "$(HEADER_SEARCH_PATHS)",
 3848 );
 3849 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3850 ONLY_ACTIVE_ARCH = YES;
 3851 PRODUCT_NAME = "$(TARGET_NAME)";
 3852 SDKROOT = macosx;
 3853 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3854 };
 3855 name = Debug;
 3856 };
 3857 0F46809714BA7E5E00BFE272 /* Release */ = {
 3858 isa = XCBuildConfiguration;
 3859 buildSettings = {
 3860 ALWAYS_SEARCH_USER_PATHS = NO;
 3861 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3862 COPY_PHASE_STRIP = YES;
 3863 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3864 GCC_C_LANGUAGE_STANDARD = gnu99;
 3865 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3866 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3867 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3868 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3869 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3870 GCC_WARN_UNUSED_VARIABLE = YES;
 3871 "HEADER_SEARCH_PATHS[arch=*]" = (
 3872 .,
 3873 icu,
 3874 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets$(HEADER_SEARCH_PATHS)",
 3875 );
 3876 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3877 PRODUCT_NAME = "$(TARGET_NAME)";
 3878 SDKROOT = macosx;
 3879 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3880 };
 3881 name = Release;
 3882 };
 3883 0F46809814BA7E5E00BFE272 /* Profiling */ = {
 3884 isa = XCBuildConfiguration;
 3885 buildSettings = {
 3886 ALWAYS_SEARCH_USER_PATHS = NO;
 3887 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3888 COPY_PHASE_STRIP = YES;
 3889 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3890 GCC_C_LANGUAGE_STANDARD = gnu99;
 3891 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3892 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3893 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3894 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3895 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3896 GCC_WARN_UNUSED_VARIABLE = YES;
 3897 "HEADER_SEARCH_PATHS[arch=*]" = (
 3898 .,
 3899 icu,
 3900 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3901 "$(HEADER_SEARCH_PATHS)",
 3902 );
 3903 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3904 PRODUCT_NAME = "$(TARGET_NAME)";
 3905 SDKROOT = macosx;
 3906 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3907 };
 3908 name = Profiling;
 3909 };
 3910 0F46809914BA7E5E00BFE272 /* Production */ = {
 3911 isa = XCBuildConfiguration;
 3912 buildSettings = {
 3913 ALWAYS_SEARCH_USER_PATHS = NO;
 3914 ARCHS = "$(ARCHS_STANDARD_64_BIT)";
 3915 COPY_PHASE_STRIP = YES;
 3916 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 3917 GCC_C_LANGUAGE_STANDARD = gnu99;
 3918 GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 3919 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 3920 GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 3921 GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 3922 GCC_WARN_ABOUT_RETURN_TYPE = YES;
 3923 GCC_WARN_UNUSED_VARIABLE = YES;
 3924 "HEADER_SEARCH_PATHS[arch=*]" = (
 3925 .,
 3926 icu,
 3927 "$(BUILT_PRODUCTS_DIR)/LLIntOffsets",
 3928 "$(HEADER_SEARCH_PATHS)",
 3929 );
 3930 MACOSX_DEPLOYMENT_TARGET = 10.7;
 3931 PRODUCT_NAME = "$(TARGET_NAME)";
 3932 SDKROOT = macosx;
 3933 USER_HEADER_SEARCH_PATHS = ". icu $(BUILT_PRODUCTS_DIR)/LLIntOffsets $(HEADER_SEARCH_PATHS)";
 3934 };
 3935 name = Production;
 3936 };
 3937 0F4680AD14BA7FD900BFE272 /* Debug */ = {
 3938 isa = XCBuildConfiguration;
 3939 buildSettings = {
 3940 PRODUCT_NAME = "Derived Sources copy";
 3941 };
 3942 name = Debug;
 3943 };
 3944 0F4680AE14BA7FD900BFE272 /* Release */ = {
 3945 isa = XCBuildConfiguration;
 3946 buildSettings = {
 3947 PRODUCT_NAME = "Derived Sources copy";
 3948 };
 3949 name = Release;
 3950 };
 3951 0F4680AF14BA7FD900BFE272 /* Profiling */ = {
 3952 isa = XCBuildConfiguration;
 3953 buildSettings = {
 3954 PRODUCT_NAME = "Derived Sources copy";
 3955 };
 3956 name = Profiling;
 3957 };
 3958 0F4680B014BA7FD900BFE272 /* Production */ = {
 3959 isa = XCBuildConfiguration;
 3960 buildSettings = {
 3961 PRODUCT_NAME = "Derived Sources copy";
 3962 };
 3963 name = Production;
 3964 };
36343965 1412113A0A48798400480255 /* Debug */ = {
36353966 isa = XCBuildConfiguration;
36363967 buildSettings = {

38724203/* End XCBuildConfiguration section */
38734204
38744205/* Begin XCConfigurationList section */
 4206 0F46809A14BA7E5F00BFE272 /* Build configuration list for PBXNativeTarget "JSCLLIntOffsetsExtractor" */ = {
 4207 isa = XCConfigurationList;
 4208 buildConfigurations = (
 4209 0F46809614BA7E5E00BFE272 /* Debug */,
 4210 0F46809714BA7E5E00BFE272 /* Release */,
 4211 0F46809814BA7E5E00BFE272 /* Profiling */,
 4212 0F46809914BA7E5E00BFE272 /* Production */,
 4213 );
 4214 defaultConfigurationIsVisible = 0;
 4215 defaultConfigurationName = Production;
 4216 };
 4217 0F4680AC14BA7FD900BFE272 /* Build configuration list for PBXAggregateTarget "LLInt Offsets" */ = {
 4218 isa = XCConfigurationList;
 4219 buildConfigurations = (
 4220 0F4680AD14BA7FD900BFE272 /* Debug */,
 4221 0F4680AE14BA7FD900BFE272 /* Release */,
 4222 0F4680AF14BA7FD900BFE272 /* Profiling */,
 4223 0F4680B014BA7FD900BFE272 /* Production */,
 4224 );
 4225 defaultConfigurationIsVisible = 0;
 4226 defaultConfigurationName = Production;
 4227 };
38754228 141211390A48798400480255 /* Build configuration list for PBXNativeTarget "minidom" */ = {
38764229 isa = XCConfigurationList;
38774230 buildConfigurations = (
105309

Source/JavaScriptCore/assembler/LinkBuffer.h

3131#define DUMP_LINK_STATISTICS 0
3232#define DUMP_CODE 0
3333
34 #include <MacroAssembler.h>
 34#include "MacroAssembler.h"
3535#include <wtf/Noncopyable.h>
3636
3737namespace JSC {
105309

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/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
890889 printPutByIdOp(exec, location, it, "put_by_id_transition");
891890 break;
892891 }
 892 case op_put_by_id_transition_direct: {
 893 printPutByIdOp(exec, location, it, "put_by_id_transition_direct");
 894 break;
 895 }
 896 case op_put_by_id_transition_normal: {
 897 printPutByIdOp(exec, location, it, "put_by_id_transition_normal");
 898 break;
 899 }
893900 case op_put_by_id_generic: {
894901 printPutByIdOp(exec, location, it, "put_by_id_generic");
895902 break;

@@void CodeBlock::dump(ExecState* exec, co
12811288 }
12821289}
12831290
1284 #endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
1285 
12861291#if DUMP_CODE_BLOCK_STATISTICS
12871292static HashSet<CodeBlock*> liveCodeBlockSet;
12881293#endif

@@CodeBlock::CodeBlock(CopyParsedBlockTag,
14491454{
14501455 setNumParameters(other.numParameters());
14511456 optimizeAfterWarmUp();
 1457 jitAfterWarmUp();
14521458
14531459 if (other.m_rareData) {
14541460 createRareDataIfNecessary();

@@CodeBlock::CodeBlock(ScriptExecutable* o
14971503 ASSERT(m_source);
14981504
14991505 optimizeAfterWarmUp();
 1506 jitAfterWarmUp();
15001507
15011508#if DUMP_CODE_BLOCK_STATISTICS
15021509 liveCodeBlockSet.add(this);

@@CodeBlock::~CodeBlock()
15141521#if ENABLE(VERBOSE_VALUE_PROFILE)
15151522 dumpValueProfiles();
15161523#endif
1517 
 1524
 1525#if ENABLE(LLINT)
 1526 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 1527 m_incomingLLIntCalls.begin()->remove();
 1528#endif // ENABLE(LLINT)
15181529#if ENABLE(JIT)
15191530 // We may be destroyed before any CodeBlocks that refer to us are destroyed.
15201531 // Consider that two CodeBlocks become unreachable at the same time. There

@@void CodeBlock::finalizeUnconditionally(
17261737#else
17271738 static const bool verboseUnlinking = false;
17281739#endif
1729 #endif
 1740#endif // ENABLE(JIT)
17301741
 1742#if ENABLE(LLINT)
 1743 Interpreter* interpreter = m_globalData->interpreter;
 1744 if (!interpreter->enabled()) {
 1745 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
 1746 Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
 1747 switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
 1748 case op_get_by_id:
 1749 case op_put_by_id:
 1750 if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
 1751 break;
 1752 curInstruction[4].u.structure.clear();
 1753 curInstruction[5].u.operand = 0;
 1754 break;
 1755 case op_put_by_id_transition_direct:
 1756 case op_put_by_id_transition_normal:
 1757 if (Heap::isMarked(curInstruction[4].u.structure.get())
 1758 && Heap::isMarked(curInstruction[6].u.structure.get())
 1759 && Heap::isMarked(curInstruction[7].u.structureChain.get()))
 1760 break;
 1761 curInstruction[4].u.structure.clear();
 1762 curInstruction[6].u.structure.clear();
 1763 curInstruction[7].u.structureChain.clear();
 1764 curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
 1765 break;
 1766 default:
 1767 ASSERT_NOT_REACHED();
 1768 }
 1769 }
 1770 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) {
 1771 Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]];
 1772 ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global
 1773 || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic);
 1774 if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get()))
 1775 continue;
 1776 curInstruction[3].u.structure.clear();
 1777 curInstruction[4].u.operand = 0;
 1778 }
 1779 for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
 1780 if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
 1781 if (verboseUnlinking)
 1782 printf("Clearing LLInt call from %p.\n", this);
 1783 m_llintCallLinkInfos[i].unlink();
 1784 }
 1785 }
 1786 }
 1787#endif // ENABLE(LLINT)
 1788
17311789#if ENABLE(DFG_JIT)
17321790 // Check if we're not live. If we are, then jettison.
17331791 if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {

@@void CodeBlock::stronglyVisitStrongRefer
18481906 for (size_t i = 0; i < m_functionDecls.size(); ++i)
18491907 visitor.append(&m_functionDecls[i]);
18501908#if ENABLE(INTERPRETER)
1851  for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
1852  visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
1853  for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1854  visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1909 if (m_globalData->interpreter->enabled()) {
 1910 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
 1911 visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
 1912 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
 1913 visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
 1914 }
18551915#endif
18561916
18571917#if ENABLE(DFG_JIT)

@@void CodeBlock::unlinkCalls()
20602120{
20612121 if (!!m_alternative)
20622122 m_alternative->unlinkCalls();
 2123#if ENABLE(LLINT)
 2124 for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
 2125 if (m_llintCallLinkInfos[i].isLinked())
 2126 m_llintCallLinkInfos[i].unlink();
 2127 }
 2128#endif
20632129 if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
20642130 return;
20652131 if (!m_globalData->canUseJIT())

@@void CodeBlock::unlinkCalls()
20742140
20752141void CodeBlock::unlinkIncomingCalls()
20762142{
 2143 while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
 2144 m_incomingLLIntCalls.begin()->unlink();
20772145 RepatchBuffer repatchBuffer(this);
20782146 while (m_incomingCalls.begin() != m_incomingCalls.end())
20792147 m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
20802148}
 2149
 2150unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
 2151{
 2152#if ENABLE(LLINT)
 2153 if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
 2154 && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
 2155 ASSERT(exec->codeBlock());
 2156 ASSERT(exec->codeBlock() == this);
 2157 ASSERT(JITCode::isBaselineCode(getJITType()));
 2158 Instruction* instruction = exec->currentVPC();
 2159 ASSERT(instruction);
 2160 return bytecodeOffset(instruction);
 2161 }
 2162#else
 2163 UNUSED_PARAM(exec);
 2164#endif
 2165 if (!m_rareData)
 2166 return 1;
 2167 Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
 2168 if (!callIndices.size())
 2169 return 1;
 2170 return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
 2171}
20812172#endif
20822173
20832174void CodeBlock::clearEvalCache()

@@bool FunctionCodeBlock::canCompileWithDF
21732264
21742265void ProgramCodeBlock::jettison()
21752266{
2176  ASSERT(getJITType() != JITCode::BaselineJIT);
 2267 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21772268 ASSERT(this == replacement());
21782269 static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21792270}
21802271
21812272void EvalCodeBlock::jettison()
21822273{
2183  ASSERT(getJITType() != JITCode::BaselineJIT);
 2274 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21842275 ASSERT(this == replacement());
21852276 static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
21862277}
21872278
21882279void FunctionCodeBlock::jettison()
21892280{
2190  ASSERT(getJITType() != JITCode::BaselineJIT);
 2281 ASSERT(JITCode::isOptimizingJIT(getJITType()));
21912282 ASSERT(this == replacement());
21922283 static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
21932284}
 2285
 2286void ProgramCodeBlock::jitCompile(ExecState* exec)
 2287{
 2288 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2289 ASSERT(this == replacement());
 2290 static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);
 2291}
 2292
 2293void EvalCodeBlock::jitCompile(ExecState* exec)
 2294{
 2295 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2296 ASSERT(this == replacement());
 2297 static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);
 2298}
 2299
 2300void FunctionCodeBlock::jitCompile(ExecState* exec)
 2301{
 2302 ASSERT(getJITType() == JITCode::InterpreterThunk);
 2303 ASSERT(this == replacement());
 2304 static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall);
 2305}
21942306#endif
21952307
21962308#if ENABLE(VALUE_PROFILER)
105309

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 {
356351 }
357352 void handleBytecodeDiscardingOpportunity()
358353 {
 354#if !ENABLE(OPCODE_SAMPLING) && !ENABLE(LLINT)
 355 if (BytecodeGenerator::dumpsGeneratedCode())
 356 return;
359357 if (!!alternative())
360358 discardBytecode();
361359 else
362360 discardBytecodeLater();
 361#endif
363362 }
364363
365 #ifndef NDEBUG
366364 bool usesOpcode(OpcodeID);
367 #endif
368365
369366 unsigned instructionCount() { return m_instructionCount; }
370367 void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }

@@namespace JSC {
387384 ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
388385 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
389386 virtual void jettison() = 0;
 387 virtual void jitCompile(ExecState*) = 0;
390388 virtual CodeBlock* replacement() = 0;
391389 virtual bool canCompileWithDFG() = 0;
392390 bool hasOptimizedReplacement()
393391 {
394  ASSERT(getJITType() == JITCode::BaselineJIT);
 392 ASSERT(JITCode::isBaselineCode(getJITType()));
395393 bool result = replacement()->getJITType() > getJITType();
396394#if !ASSERT_DISABLED
397395 if (result)
398396 ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
399397 else {
400  ASSERT(replacement()->getJITType() == JITCode::BaselineJIT);
 398 ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
401399 ASSERT(replacement() == this);
402400 }
403401#endif

@@namespace JSC {
456454
457455 void clearEvalCache();
458456
459 #if ENABLE(INTERPRETER)
460457 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
461458 {
462  if (!m_globalData->canUseJIT())
463  m_propertyAccessInstructions.append(propertyAccessInstruction);
 459 m_propertyAccessInstructions.append(propertyAccessInstruction);
464460 }
465461 void addGlobalResolveInstruction(unsigned globalResolveInstruction)
466462 {
467  if (!m_globalData->canUseJIT())
468  m_globalResolveInstructions.append(globalResolveInstruction);
 463 m_globalResolveInstructions.append(globalResolveInstruction);
469464 }
470465 bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
 466#if ENABLE(LLINT)
 467 LLIntCallLinkInfo* addLLIntCallLinkInfo()
 468 {
 469 m_llintCallLinkInfos.append(LLIntCallLinkInfo());
 470 return &m_llintCallLinkInfos.last();
 471 }
471472#endif
472473#if ENABLE(JIT)
473474 void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }

@@namespace JSC {
476477
477478 void addGlobalResolveInfo(unsigned globalResolveInstruction)
478479 {
479  if (m_globalData->canUseJIT())
480  m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
 480 m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction));
481481 }
482482 GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
483483 bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);

@@namespace JSC {
672672
673673 bool addFrequentExitSite(const DFG::FrequentExitSite& site)
674674 {
675  ASSERT(getJITType() == JITCode::BaselineJIT);
 675 ASSERT(JITCode::isBaselineCode(getJITType()));
676676 return m_exitProfile.add(site);
677677 }
678678

@@namespace JSC {
777777 void copyPostParseDataFrom(CodeBlock* alternative);
778778 void copyPostParseDataFromAlternative();
779779
 780 // Functions for controlling when JITting kicks in, in a mixed mode
 781 // execution world.
 782
 783 void dontJITAnytimeSoon()
 784 {
 785 m_llintExecuteCounter = Options::executionCounterValueForDontJITAnytimeSoon;
 786 }
 787
 788 void jitAfterWarmUp()
 789 {
 790 m_llintExecuteCounter = Options::executionCounterValueForJITAfterWarmUp;
 791 }
 792
 793 void jitSoon()
 794 {
 795 m_llintExecuteCounter = Options::executionCounterValueForJITSoon;
 796 }
 797
 798 int32_t llintExecuteCounter() const
 799 {
 800 return m_llintExecuteCounter;
 801 }
 802
780803 // Functions for controlling when tiered compilation kicks in. This
781804 // controls both when the optimizing compiler is invoked and when OSR
782805 // entry happens. Two triggers exist: the loop trigger and the return

@@namespace JSC {
9811004 void tallyFrequentExitSites() { }
9821005#endif
9831006
984 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
9851007 void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
9861008
9871009 CString registerName(ExecState*, int r) const;

@@namespace JSC {
9911013 void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
9921014 void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
9931015 void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
994 #endif
9951016 void visitStructures(SlotVisitor&, Instruction* vPC) const;
9961017
9971018#if ENABLE(DFG_JIT)

@@namespace JSC {
10521073 RefPtr<SourceProvider> m_source;
10531074 unsigned m_sourceOffset;
10541075
1055 #if ENABLE(INTERPRETER)
10561076 Vector<unsigned> m_propertyAccessInstructions;
10571077 Vector<unsigned> m_globalResolveInstructions;
 1078#if ENABLE(LLINT)
 1079 SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
 1080 SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
10581081#endif
10591082#if ENABLE(JIT)
10601083 Vector<StructureStubInfo> m_structureStubInfos;

@@namespace JSC {
10651088 MacroAssemblerCodePtr m_jitCodeWithArityCheck;
10661089 SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
10671090#endif
1068 #if ENABLE(DFG_JIT)
 1091#if ENABLE(DFG_JIT) || ENABLE(LLINT)
10691092 OwnPtr<CompactJITCodeMap> m_jitCodeMap;
1070 
 1093#endif
 1094#if ENABLE(DFG_JIT)
10711095 struct WeakReferenceTransition {
10721096 WeakReferenceTransition() { }
10731097

@@namespace JSC {
11301154
11311155 OwnPtr<CodeBlock> m_alternative;
11321156
 1157 int32_t m_llintExecuteCounter;
 1158
11331159 int32_t m_jitExecuteCounter;
11341160 uint32_t m_speculativeSuccessCounter;
11351161 uint32_t m_speculativeFailCounter;
11361162 uint8_t m_optimizationDelayCounter;
11371163 uint8_t m_reoptimizationRetryCounter;
1138 
 1164
11391165 struct RareData {
11401166 WTF_MAKE_FAST_ALLOCATED;
11411167 public:

@@namespace JSC {
12081234 protected:
12091235 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12101236 virtual void jettison();
 1237 virtual void jitCompile(ExecState*);
12111238 virtual CodeBlock* replacement();
12121239 virtual bool canCompileWithDFG();
12131240#endif

@@namespace JSC {
12421269 protected:
12431270 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12441271 virtual void jettison();
 1272 virtual void jitCompile(ExecState*);
12451273 virtual CodeBlock* replacement();
12461274 virtual bool canCompileWithDFG();
12471275#endif

@@namespace JSC {
12791307 protected:
12801308 virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
12811309 virtual void jettison();
 1310 virtual void jitCompile(ExecState*);
12821311 virtual CodeBlock* replacement();
12831312 virtual bool canCompileWithDFG();
12841313#endif
105309

Source/JavaScriptCore/bytecode/Instruction.h

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

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

@@namespace JSC {
180186 }
181187
182188 Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
 189
 190 Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; }
183191
184192 union {
185193 Opcode opcode;

@@namespace JSC {
188196 WriteBarrierBase<StructureChain> structureChain;
189197 WriteBarrierBase<JSCell> jsCell;
190198 PropertySlot::GetValueFunc getterFunc;
 199 LLIntCallLinkInfo* callLinkInfo;
 200 void* pointer;
191201 } u;
192202
193203 private:
105309

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 MacroAssemblerCodePtr machineCodeTarget;
 60};
 61
 62} // namespace JSC
 63
 64#endif // LLIntCallLinkInfo_h
 65
0

Source/JavaScriptCore/bytecode/Opcode.h

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

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

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

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
12641253#if ENABLE(JIT)
12651254 m_codeBlock->addGlobalResolveInfo(instructions().size());
12661255#endif
1267 #if ENABLE(INTERPRETER)
12681256 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1269 #endif
12701257 emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
12711258 instructions().append(dst->index());
12721259 instructions().append(addConstant(property));

@@RegisterID* BytecodeGenerator::emitResol
14191406#if ENABLE(JIT)
14201407 m_codeBlock->addGlobalResolveInfo(instructions().size());
14211408#endif
1422 #if ENABLE(INTERPRETER)
14231409 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1424 #endif
14251410 emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
14261411 instructions().append(propDst->index());
14271412 instructions().append(addConstant(property));

@@RegisterID* BytecodeGenerator::emitResol
14661451#if ENABLE(JIT)
14671452 m_codeBlock->addGlobalResolveInfo(instructions().size());
14681453#endif
1469 #if ENABLE(INTERPRETER)
14701454 m_codeBlock->addGlobalResolveInstruction(instructions().size());
1471 #endif
14721455 emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
14731456 instructions().append(propDst->index());
14741457 instructions().append(addConstant(property));

@@void BytecodeGenerator::emitMethodCheck(
14861469
14871470RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
14881471{
1489 #if ENABLE(INTERPRETER)
14901472 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1491 #endif
14921473
14931474 emitOpcode(op_get_by_id);
14941475 instructions().append(dst->index());

@@RegisterID* BytecodeGenerator::emitGetAr
15131494
15141495RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
15151496{
1516 #if ENABLE(INTERPRETER)
15171497 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1518 #endif
15191498
15201499 emitOpcode(op_put_by_id);
15211500 instructions().append(base->index());

@@RegisterID* BytecodeGenerator::emitPutBy
15311510
15321511RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
15331512{
1534 #if ENABLE(INTERPRETER)
15351513 m_codeBlock->addPropertyAccessInstruction(instructions().size());
1536 #endif
15371514
15381515 emitOpcode(op_put_by_id);
15391516 instructions().append(base->index());

@@RegisterID* BytecodeGenerator::emitCall(
18211798 instructions().append(func->index()); // func
18221799 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
18231800 instructions().append(callArguments.registerOffset()); // registerOffset
 1801#if ENABLE(LLINT)
 1802 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1803#else
18241804 instructions().append(0);
 1805#endif
18251806 instructions().append(0);
18261807 if (dst != ignoredResult()) {
18271808 emitOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitConst
19231904 instructions().append(func->index()); // func
19241905 instructions().append(callArguments.argumentCountIncludingThis()); // argCount
19251906 instructions().append(callArguments.registerOffset()); // registerOffset
 1907#if ENABLE(LLINT)
 1908 instructions().append(m_codeBlock->addLLIntCallLinkInfo());
 1909#else
19261910 instructions().append(0);
 1911#endif
19271912 instructions().append(0);
19281913 if (dst != ignoredResult()) {
19291914 emitOpcode(op_call_put_result);

@@RegisterID* BytecodeGenerator::emitCatch
21832168{
21842169 m_usesExceptions = true;
21852170#if ENABLE(JIT)
 2171#if ENABLE(LLINT)
 2172 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel(bitwise_cast<void*>(&llint_op_catch)) };
 2173#else
21862174 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
 2175#endif
21872176#else
21882177 HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
21892178#endif
105309

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@bool ByteCodeParser::parseBlock(unsigned
18461846 NEXT_OPCODE(op_get_by_id);
18471847 }
18481848
1849  case op_put_by_id: {
 1849 case op_put_by_id:
 1850 case op_put_by_id_transition_direct:
 1851 case op_put_by_id_transition_normal: {
18501852 NodeIndex value = get(currentInstruction[3].u.operand);
18511853 NodeIndex base = get(currentInstruction[1].u.operand);
18521854 unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
105309

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

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
564565 return JSValue::strictEqual(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
565566}
566567
567 EncodedJSValue DFG_OPERATION getHostCallReturnValue();
568 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState*);
569 
570 #if CPU(X86_64)
571 asm (
572 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
573 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
574  "mov -40(%r13), %r13\n"
575  "mov %r13, %rdi\n"
576  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
577 );
578 #elif CPU(X86)
579 asm (
580 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
581 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
582  "mov -40(%edi), %edi\n"
583  "mov %edi, 4(%esp)\n"
584  "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
585 );
586 #elif CPU(ARM_THUMB2)
587 asm (
588 ".text" "\n"
589 ".align 2" "\n"
590 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
591 HIDE_SYMBOL(getHostCallReturnValue) "\n"
592 ".thumb" "\n"
593 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
594 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
595  "ldr r5, [r5, #-40]" "\n"
596  "cpy r0, r5" "\n"
597  "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
598 );
599 #endif
600 
601 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)
602 {
603  return JSValue::encode(exec->globalData().hostCallReturnValue);
604 }
605 
606568static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
607569{
608570 ExecState* exec = execCallee->callerFrame();
105309

Source/JavaScriptCore/heap/AllocationSpace.h

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

@@public:
6869 void shrink();
6970
7071private:
 72 friend class LLIntOffsetsExtractor;
 73
7174 enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
7275
7376 void* allocate(MarkedSpace::SizeClass&);
105309

Source/JavaScriptCore/heap/Heap.cpp

@@void Heap::collect(SweepToggle sweepTogg
829829 m_objectSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
830830 }
831831 JAVASCRIPTCORE_GC_END();
832 
 832
833833 (*m_activityCallback)();
834834}
835835
105309

Source/JavaScriptCore/heap/Heap.h

@@namespace JSC {
4646 class JSGlobalData;
4747 class JSValue;
4848 class LiveObjectIterator;
 49 class LLIntOffsetsExtractor;
4950 class MarkedArgumentBuffer;
5051 class RegisterFile;
5152 class UString;

@@namespace JSC {
129130 void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
130131
131132 private:
132  friend class MarkedBlock;
133133 friend class AllocationSpace;
134  friend class SlotVisitor;
135134 friend class CodeBlock;
 135 friend class LLIntOffsetsExtractor;
 136 friend class MarkedBlock;
 137 friend class SlotVisitor;
136138
137139 static const size_t minExtraCost = 256;
138140 static const size_t maxExtraCost = 1024 * 1024;
105309

Source/JavaScriptCore/heap/MarkStack.cpp

@@ALWAYS_INLINE static void visitChildren(
301301#endif
302302
303303 ASSERT(Heap::isMarked(cell));
304 
 304
305305 if (isJSString(cell)) {
306306 JSString::visitChildren(const_cast<JSCell*>(cell), visitor);
307307 return;
105309

Source/JavaScriptCore/heap/MarkedSpace.h

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

@@public:
7980 template<typename Functor> typename Functor::ReturnType forEachBlock();
8081
8182private:
 83 friend class LLIntOffsetsExtractor;
 84
8285 // [ 32... 256 ]
8386 static const size_t preciseStep = MarkedBlock::atomSize;
8487 static const size_t preciseCutoff = 256;
105309

Source/JavaScriptCore/interpreter/CallFrame.h

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

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#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
 561#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
 562 // Having LLInt enabled, but not being able to use the JIT, and not having
 563 // a computed goto interpreter, is not supported. Not because we cannot
 564 // support it, but because I decided to draw the line at the number of
 565 // permutations of execution engines that I wanted this code to grok.
 566 ASSERT(canUseJIT);
 567#endif
553568 if (canUseJIT) {
 569#if ENABLE(LLINT)
 570 m_opcodeTable = llintData->opcodeMap();
 571 for (int i = 0; i < numOpcodeIDs; ++i)
 572 m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
 573#else
554574 // If the JIT is present, don't use jump destinations for opcodes.
555575
556576 for (int i = 0; i < numOpcodeIDs; ++i) {
557577 Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
558578 m_opcodeTable[i] = opcode;
559579 }
 580#endif
560581 } else {
 582#if ENABLE(LLINT)
 583 m_opcodeTable = new Opcode[numOpcodeIDs];
 584#endif
561585 privateExecute(InitializeAndReturn, 0, 0);
562586
563587 for (int i = 0; i < numOpcodeIDs; ++i)

@@void Interpreter::dumpRegisters(CallFram
667691
668692bool Interpreter::isOpcode(Opcode opcode)
669693{
670 #if ENABLE(COMPUTED_GOTO_INTERPRETER)
 694#if ENABLE(COMPUTED_GOTO_INTERPRETER) || ENABLE(LLINT)
 695#if !ENABLE(LLINT)
671696 if (!m_enabled)
672697 return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
 698#endif
673699 return opcode != HashTraits<Opcode>::emptyValue()
674700 && !HashTraits<Opcode>::isDeletedValue(opcode)
675701 && m_opcodeIDTable.contains(opcode);

@@NEVER_INLINE bool Interpreter::unwindCal
726752 // have to subtract 1.
727753#if ENABLE(JIT) && ENABLE(INTERPRETER)
728754 if (callerFrame->globalData().canUseJIT())
729  bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
 755 bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
730756 else
731757 bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
732758#elif ENABLE(JIT)
733  bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
 759 bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
734760#else
735761 bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
736762#endif

@@void Interpreter::retrieveLastCaller(Cal
51705196 bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
51715197#if ENABLE(JIT)
51725198 else
5173  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5199 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51745200#endif
51755201#else
5176  bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
 5202 bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
51775203#endif
51785204 lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
51795205 sourceID = callerCodeBlock->ownerExecutable()->sourceID();
105309

Source/JavaScriptCore/interpreter/Interpreter.h

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

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

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

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

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

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

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

Source/JavaScriptCore/jit/HostCallReturnValue.cpp

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

Source/JavaScriptCore/jit/HostCallReturnValue.h

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

Source/JavaScriptCore/jit/JIT.cpp

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

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

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

@@JITCode JIT::privateCompile(CodePtr* fun
690696 info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
691697 }
692698
693 #if ENABLE(DFG_JIT)
 699#if ENABLE(DFG_JIT) || ENABLE(LLINT)
694700 if (m_canBeOptimized) {
695701 CompactJITCodeMap::Encoder jitCodeMapEncoder;
696702 for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
105309

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
105309

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(ExecState* exec, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType)
4142{
 43 if (jitType == codeBlock->getJITType())
 44 return true;
 45
4246 if (!exec->globalData().canUseJIT())
4347 return true;
4448
 49 codeBlock->unlinkIncomingCalls();
 50
4551 bool dfgCompiled = false;
4652 if (jitType == JITCode::DFGJIT)
4753 dfgCompiled = DFG::tryCompile(exec, codeBlock.get(), jitCode);

@@inline bool jitCompileIfAppropriate(Exec
5561 }
5662 jitCode = JIT::compile(&exec->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(Exec
6669
6770inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType)
6871{
 72 if (jitType == codeBlock->getJITType())
 73 return true;
 74
6975 JSGlobalData& globalData = exec->globalData();
7076 if (!globalData.canUseJIT())
7177 return true;
7278
 79 codeBlock->unlinkIncomingCalls();
 80
7381 bool dfgCompiled = false;
7482 if (jitType == JITCode::DFGJIT)
7583 dfgCompiled = DFG::tryCompileFunction(exec, codeBlock.get(), jitCode, jitCodeWithArityCheck);

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

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

Source/JavaScriptCore/jit/JITStubs.cpp

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

@@DEFINE_STUB_FUNCTION(void*, op_construct
22212189
22222190 CallFrame* callFrame = stackFrame.callFrame;
22232191
2224  CallFrame* newCallFrame = arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
 2192 CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
22252193 if (!newCallFrame)
22262194 return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
22272195
105309

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

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

Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h

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

Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

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

Source/JavaScriptCore/llint/LLIntThunks.cpp

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

Source/JavaScriptCore/llint/LowLevelInterpreter.asm

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

Source/JavaScriptCore/offlineasm/armv7.rb

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

Source/JavaScriptCore/offlineasm/asm.rb

 1#!/usr/bin/env ruby
 2
 3# Copyright (C) 2011 Apple Inc. All rights reserved.
 4#
 5# Redistribution and use in source and binary forms, with or without
 6# modification, are permitted provided that the following conditions
 7# are met:
 8# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24# THE POSSIBILITY OF SUCH DAMAGE.
 25
 26$: << File.dirname(__FILE__)
 27
 28require "backends"
 29require "offsets"
 30require "parser"
 31require "settings"
 32require "transform"
 33
 34class Assembler
 35 def initialize(outp)
 36 @outp = outp
 37 @state = :cpp
 38 end
 39
 40 def enterAsm
 41 @outp.puts "asm ("
 42 @state = :asm
 43 end
 44
 45 def leaveAsm
 46 @outp.puts ");"
 47 @state = :cpp
 48 end
 49
 50 def inAsm
 51 enterAsm
 52 yield
 53 leaveAsm
 54 end
 55
 56 def puts(line)
 57 raise unless @state == :asm
 58 @outp.puts((line + "\n").inspect)
 59 end
 60
 61 def comment(text)
 62 @outp.puts "// #{text}"
 63 end
 64end
 65
 66$asm = Assembler.new($stdout)
 67
 68asmFile = ARGV.shift
 69offsetsFile = ARGV.shift
 70
 71ast = parse(lex(IO::read(asmFile)))
 72offsetsList, configIndex = offsetsAndConfigurationIndex(offsetsFile)
 73
 74forSettings(computeSettingsCombinations(ast)[configIndex], ast) {
 75 | concreteSettings, lowLevelAST, backend |
 76 assertConfiguration(concreteSettings)
 77 lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
 78 emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
 79 $asm.inAsm {
 80 lowLevelAST.lower(backend)
 81 }
 82 }
 83}
0

Source/JavaScriptCore/offlineasm/ast.rb

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

Source/JavaScriptCore/offlineasm/backends.rb

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

Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb

 1#!/usr/bin/env ruby
 2
 3# Copyright (C) 2011 Apple Inc. All rights reserved.
 4#
 5# Redistribution and use in source and binary forms, with or without
 6# modification, are permitted provided that the following conditions
 7# are met:
 8# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24# THE POSSIBILITY OF SUCH DAMAGE.
 25
 26$: << File.dirname(__FILE__)
 27
 28require "backends"
 29require "offsets"
 30require "parser"
 31require "settings"
 32require "transform"
 33
 34def emitMagicNumber
 35 OFFSET_MAGIC_NUMBERS.each {
 36 | number |
 37 puts "#{number},"
 38 }
 39end
 40
 41originalAST = parse(lex($stdin.read))
 42
 43emitCodeInAllConfigurations(originalAST) {
 44 | settings, ast, backend, index |
 45 offsetsList = ast.filter(StructOffset).uniq.sort
 46 sizesList = ast.filter(Sizeof).uniq.sort
 47
 48 length = (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
 49
 50 puts "static const unsigned extractorTable[#{length}] = {"
 51 emitMagicNumber
 52 puts "#{index},"
 53 offsetsList.each {
 54 | offset |
 55 emitMagicNumber
 56 puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
 57 }
 58 sizesList.each {
 59 | offset |
 60 emitMagicNumber
 61 puts "sizeof(#{offset.struct}),"
 62 }
 63 puts "};"
 64}
 65
0

Source/JavaScriptCore/offlineasm/instructions.rb

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

Source/JavaScriptCore/offlineasm/offset_extractor_constants.rb

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

Source/JavaScriptCore/offlineasm/offsets.rb

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

Source/JavaScriptCore/offlineasm/parser.rb

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

Source/JavaScriptCore/offlineasm/registers.rb

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

Source/JavaScriptCore/offlineasm/settings.rb

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

Source/JavaScriptCore/offlineasm/transform.rb

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

Source/JavaScriptCore/offlineasm/x86.rb

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

Source/JavaScriptCore/runtime/CodeSpecializationKind.h

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

Source/JavaScriptCore/runtime/CommonSlowPaths.h

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

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

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(ExecState* exec)
 172{
 173 bool result = jitCompileIfAppropriate(exec, 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(exec, m_evalCodeBlock, m_jitCodeForCall, jitType))
 235 if (!prepareForExecution(exec, m_evalCodeBlock, m_jitCodeForCall, jitType))
214236 return 0;
215237#endif
216238

@@JSObject* ProgramExecutable::compileOpti
295317 return error;
296318}
297319
 320void ProgramExecutable::jitCompile(ExecState* exec)
 321{
 322 bool result = jitCompileIfAppropriate(exec, 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(exec, m_programCodeBlock, m_jitCodeForCall, jitType))
 367 if (!prepareForExecution(exec, 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(ExecState* exec)
 470{
 471 bool result = jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, JITCode::bottomTierJIT());
 472 ASSERT_UNUSED(result, result);
 473}
 474
 475void FunctionExecutable::jitCompileForConstruct(ExecState* exec)
 476{
 477 bool result = jitCompileFunctionIfAppropriate(exec, 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, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType))
 547 if (!prepareFunctionForExecution(exec, 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, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType))
 589 if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, CodeForConstruct))
550590 return 0;
551591#endif
552592
105309

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(ExecState*);
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(ExecState*);
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(ExecState*);
511518#endif
512519
513520 bool isGeneratedForCall() const

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

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

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(ExecState* exec, 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(exec->globalData(), codeBlock.get(), jitCode);
 45 codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
 46 return true;
 47 }
 48#endif // ENABLE(LLINT)
 49 return jitCompileIfAppropriate(exec, codeBlock, jitCode, jitType);
 50}
 51
 52inline bool prepareFunctionForExecution(ExecState* exec, 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(exec->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(exec, 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);
105309

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 {
124125 };
125126
126127 class JSArray : public JSNonFinalObject {
 128 friend class LLIntOffsetsExtractor;
127129 friend class Walker;
128130
129131 protected:
105309

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 {
165166 static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
166167
167168 private:
 169 friend class LLIntOffsetsExtractor;
 170
168171 const ClassInfo* m_classInfo;
169172 WriteBarrier<Structure> m_structure;
170173 };
105309

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

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
218220 jitStubs = adoptPtr(new JITThunks(this));
219221#endif
220222
221  interpreter->initialize(this->canUseJIT());
 223 interpreter->initialize(&llintData, this->canUseJIT());
222224
223225 heap.notifyIsSafeToCollect();
224226}
105309

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 {
248250 Heap heap;
249251
250252 JSValue exception;
 253
 254 const ClassInfo* const jsArrayClassInfo;
 255 const ClassInfo* const jsFinalObjectClassInfo;
 256
 257 LLInt::Data llintData;
 258
251259#if ENABLE(JIT)
252260 ReturnAddressPtr exceptionLocation;
253261 JSValue hostCallReturnValue;

@@namespace JSC {
353361#undef registerTypedArrayFunction
354362
355363 private:
 364 friend class LLIntOffsetsExtractor;
 365
356366 JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
357367 static JSGlobalData*& sharedInstanceInternal();
358368 void createNativeThunk();
105309

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

Source/JavaScriptCore/runtime/JSObject.h

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

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

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

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

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 {
241242 static void visitChildren(JSCell*, SlotVisitor&);
242243
243244 private:
 245 friend class LLIntOffsetsExtractor;
 246
244247 JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
245248 void resolveRopeSlowCase8(LChar*) const;
246249 void resolveRopeSlowCase(UChar*) const;
105309

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
105309

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
105309

Source/JavaScriptCore/runtime/JSValue.h

@@namespace JSC {
233233 JSCell* asCell() const;
234234 JS_EXPORT_PRIVATE bool isValidCallee();
235235
236 #ifndef NDEBUG
237236 char* description();
238 #endif
239237
240238 private:
241239 template <class T> JSValue(WriteBarrierBase<T>);
105309

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

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

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

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
105309

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

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

Source/JavaScriptCore/wtf/Platform.h

918918#define ENABLE_JIT 1
919919#endif
920920
 921/* On some of the platforms where we have a JIT, we want to also have the
 922 low-level interpreter. */
 923#if ENABLE(JIT) && PLATFORM(MAC) && USE(JSVALUE32_64)
 924#define ENABLE_LLINT 1
 925#endif
 926
921927#if !defined(ENABLE_DFG_JIT) && ENABLE(JIT)
922928/* Enable the DFG JIT on X86 and X86_64. Only tested on Mac and GNU/Linux. */
923929#if (CPU(X86) || CPU(X86_64)) && (PLATFORM(MAC) || OS(LINUX))
105309

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 {
7071 friend struct WTF::HashAndUTF8CharactersTranslator;
7172 friend struct WTF::UCharBufferTranslator;
7273 friend class AtomicStringImpl;
73 
 74 friend class JSC::LLIntOffsetsExtractor;
 75
7476private:
7577 enum BufferOwnership {
7678 BufferInternal,
105309