Home | History | Annotate | Download | only in jit
      1 /*
      2  * Copyright (C) 2008 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 JIT_h
     27 #define JIT_h
     28 
     29 #if ENABLE(JIT)
     30 
     31 // We've run into some problems where changing the size of the class JIT leads to
     32 // performance fluctuations.  Try forcing alignment in an attempt to stabalize this.
     33 #if COMPILER(GCC)
     34 #define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32)))
     35 #else
     36 #define JIT_CLASS_ALIGNMENT
     37 #endif
     38 
     39 #define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(expected), static_cast<int>(actual));
     40 
     41 #include "CodeBlock.h"
     42 #include "Interpreter.h"
     43 #include "JSInterfaceJIT.h"
     44 #include "Opcode.h"
     45 #include "Profiler.h"
     46 #include <bytecode/SamplingTool.h>
     47 
     48 namespace JSC {
     49 
     50     class CodeBlock;
     51     class JIT;
     52     class JSPropertyNameIterator;
     53     class Interpreter;
     54     class Register;
     55     class RegisterFile;
     56     class ScopeChainNode;
     57     class StructureChain;
     58 
     59     struct CallLinkInfo;
     60     struct Instruction;
     61     struct OperandTypes;
     62     struct PolymorphicAccessStructureList;
     63     struct SimpleJumpTable;
     64     struct StringJumpTable;
     65     struct StructureStubInfo;
     66 
     67     struct CallRecord {
     68         MacroAssembler::Call from;
     69         unsigned bytecodeOffset;
     70         void* to;
     71 
     72         CallRecord()
     73         {
     74         }
     75 
     76         CallRecord(MacroAssembler::Call from, unsigned bytecodeOffset, void* to = 0)
     77             : from(from)
     78             , bytecodeOffset(bytecodeOffset)
     79             , to(to)
     80         {
     81         }
     82     };
     83 
     84     struct JumpTable {
     85         MacroAssembler::Jump from;
     86         unsigned toBytecodeOffset;
     87 
     88         JumpTable(MacroAssembler::Jump f, unsigned t)
     89             : from(f)
     90             , toBytecodeOffset(t)
     91         {
     92         }
     93     };
     94 
     95     struct SlowCaseEntry {
     96         MacroAssembler::Jump from;
     97         unsigned to;
     98         unsigned hint;
     99 
    100         SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0)
    101             : from(f)
    102             , to(t)
    103             , hint(h)
    104         {
    105         }
    106     };
    107 
    108     struct SwitchRecord {
    109         enum Type {
    110             Immediate,
    111             Character,
    112             String
    113         };
    114 
    115         Type type;
    116 
    117         union {
    118             SimpleJumpTable* simpleJumpTable;
    119             StringJumpTable* stringJumpTable;
    120         } jumpTable;
    121 
    122         unsigned bytecodeOffset;
    123         unsigned defaultOffset;
    124 
    125         SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset, Type type)
    126             : type(type)
    127             , bytecodeOffset(bytecodeOffset)
    128             , defaultOffset(defaultOffset)
    129         {
    130             this->jumpTable.simpleJumpTable = jumpTable;
    131         }
    132 
    133         SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset)
    134             : type(String)
    135             , bytecodeOffset(bytecodeOffset)
    136             , defaultOffset(defaultOffset)
    137         {
    138             this->jumpTable.stringJumpTable = jumpTable;
    139         }
    140     };
    141 
    142     struct PropertyStubCompilationInfo {
    143         MacroAssembler::Call callReturnLocation;
    144         MacroAssembler::Label hotPathBegin;
    145     };
    146 
    147     struct StructureStubCompilationInfo {
    148         MacroAssembler::DataLabelPtr hotPathBegin;
    149         MacroAssembler::Call hotPathOther;
    150         MacroAssembler::Call callReturnLocation;
    151     };
    152 
    153     struct MethodCallCompilationInfo {
    154         MethodCallCompilationInfo(unsigned propertyAccessIndex)
    155             : propertyAccessIndex(propertyAccessIndex)
    156         {
    157         }
    158 
    159         MacroAssembler::DataLabelPtr structureToCompare;
    160         unsigned propertyAccessIndex;
    161     };
    162 
    163     // Near calls can only be patched to other JIT code, regular calls can be patched to JIT code or relinked to stub functions.
    164     void ctiPatchNearCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
    165     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
    166     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction);
    167 
    168     class JIT : private JSInterfaceJIT {
    169         friend class JITStubCall;
    170 
    171         using MacroAssembler::Jump;
    172         using MacroAssembler::JumpList;
    173         using MacroAssembler::Label;
    174 
    175         static const int patchGetByIdDefaultStructure = -1;
    176         // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
    177         // will compress the displacement, and we may not be able to fit a patched offset.
    178         static const int patchGetByIdDefaultOffset = 256;
    179 
    180     public:
    181         static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0, void* offsetBase = 0)
    182         {
    183             return JIT(globalData, codeBlock, offsetBase).privateCompile(functionEntryArityCheck);
    184         }
    185 
    186         static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
    187         {
    188             JIT jit(globalData, codeBlock);
    189             jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame);
    190         }
    191 
    192         static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
    193         {
    194             JIT jit(globalData, codeBlock);
    195             jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset);
    196         }
    197         static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
    198         {
    199             JIT jit(globalData, codeBlock);
    200             jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame);
    201         }
    202         static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
    203         {
    204             JIT jit(globalData, codeBlock);
    205             jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame);
    206         }
    207 
    208         static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
    209         {
    210             JIT jit(globalData, codeBlock);
    211             jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame);
    212         }
    213 
    214         static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
    215         {
    216             JIT jit(globalData, codeBlock);
    217             jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct);
    218         }
    219 
    220         static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, TrampolineStructure *trampolines)
    221         {
    222             if (!globalData->canUseJIT())
    223                 return;
    224             JIT jit(globalData, 0, 0);
    225             jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines);
    226         }
    227 
    228         static CodePtr compileCTINativeCall(JSGlobalData* globalData, PassRefPtr<ExecutablePool> executablePool, NativeFunction func)
    229         {
    230             if (!globalData->canUseJIT())
    231                 return CodePtr();
    232             JIT jit(globalData, 0, 0);
    233             return jit.privateCompileCTINativeCall(executablePool, globalData, func);
    234         }
    235 
    236         static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
    237         static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
    238         static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
    239 
    240         static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
    241         {
    242             JIT jit(globalData, codeBlock);
    243             return jit.privateCompilePatchGetArrayLength(returnAddress);
    244         }
    245 
    246         static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
    247         static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
    248 
    249     private:
    250         struct JSRInfo {
    251             DataLabelPtr storeLocation;
    252             Label target;
    253 
    254             JSRInfo(DataLabelPtr storeLocation, Label targetLocation)
    255                 : storeLocation(storeLocation)
    256                 , target(targetLocation)
    257             {
    258             }
    259         };
    260 
    261         JIT(JSGlobalData*, CodeBlock* = 0, void* = 0);
    262 
    263         void privateCompileMainPass();
    264         void privateCompileLinkPass();
    265         void privateCompileSlowCases();
    266         JITCode privateCompile(CodePtr* functionEntryArityCheck);
    267         void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
    268         void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset);
    269         void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
    270         void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
    271         void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
    272         void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct);
    273 
    274         void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines);
    275         Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false);
    276         CodePtr privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executablePool, JSGlobalData* data, NativeFunction func);
    277         void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
    278 
    279         void addSlowCase(Jump);
    280         void addSlowCase(JumpList);
    281         void addJump(Jump, int);
    282         void emitJumpSlowToHot(Jump, int);
    283 
    284         void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex);
    285         void compileOpCallVarargs(Instruction* instruction);
    286         void compileOpCallInitializeCallFrame();
    287         void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID);
    288         void compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter);
    289 
    290         enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
    291         void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
    292         bool isOperandConstantImmediateDouble(unsigned src);
    293 
    294         void emitLoadDouble(unsigned index, FPRegisterID value);
    295         void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
    296 
    297         void testPrototype(JSValue, JumpList& failureCases);
    298 
    299 #if USE(JSVALUE32_64)
    300         bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
    301 
    302         void emitLoadTag(unsigned index, RegisterID tag);
    303         void emitLoadPayload(unsigned index, RegisterID payload);
    304 
    305         void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload);
    306         void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
    307         void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2);
    308 
    309         void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
    310         void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister);
    311         void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false);
    312         void emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32 = false);
    313         void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
    314         void emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool = false);
    315         void emitStoreDouble(unsigned index, FPRegisterID value);
    316 
    317         bool isLabeled(unsigned bytecodeOffset);
    318         void map(unsigned bytecodeOffset, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload);
    319         void unmap(RegisterID);
    320         void unmap();
    321         bool isMapped(unsigned virtualRegisterIndex);
    322         bool getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload);
    323         bool getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag);
    324 
    325         void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex);
    326         void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag);
    327         void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, unsigned virtualRegisterIndex);
    328 
    329 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
    330         void compileGetByIdHotPath();
    331         void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
    332 #endif
    333         void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset);
    334         void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
    335         void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset);
    336         void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset);
    337 
    338         // Arithmetic opcode helpers
    339         void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
    340         void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
    341         void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);
    342 
    343 #if CPU(X86)
    344         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    345         static const int patchOffsetPutByIdStructure = 7;
    346         static const int patchOffsetPutByIdPropertyMapOffset1 = 22;
    347         static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
    348         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    349         static const int patchOffsetGetByIdStructure = 7;
    350         static const int patchOffsetGetByIdBranchToSlowCase = 13;
    351         static const int patchOffsetGetByIdPropertyMapOffset1 = 22;
    352         static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
    353         static const int patchOffsetGetByIdPutResult = 28;
    354 #if ENABLE(OPCODE_SAMPLING)
    355         static const int patchOffsetGetByIdSlowCaseCall = 37;
    356 #else
    357         static const int patchOffsetGetByIdSlowCaseCall = 27;
    358 #endif
    359         static const int patchOffsetOpCallCompareToJump = 6;
    360 
    361         static const int patchOffsetMethodCheckProtoObj = 11;
    362         static const int patchOffsetMethodCheckProtoStruct = 18;
    363         static const int patchOffsetMethodCheckPutFunction = 29;
    364 #elif CPU(ARM_TRADITIONAL)
    365         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    366         static const int patchOffsetPutByIdStructure = 4;
    367         static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
    368         static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
    369         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    370         static const int patchOffsetGetByIdStructure = 4;
    371         static const int patchOffsetGetByIdBranchToSlowCase = 16;
    372         static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
    373         static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
    374         static const int patchOffsetGetByIdPutResult = 36;
    375 #if ENABLE(OPCODE_SAMPLING)
    376         #error "OPCODE_SAMPLING is not yet supported"
    377 #else
    378         static const int patchOffsetGetByIdSlowCaseCall = 32;
    379 #endif
    380         static const int patchOffsetOpCallCompareToJump = 12;
    381 
    382         static const int patchOffsetMethodCheckProtoObj = 12;
    383         static const int patchOffsetMethodCheckProtoStruct = 20;
    384         static const int patchOffsetMethodCheckPutFunction = 32;
    385 
    386         // sequenceOpCall
    387         static const int sequenceOpCallInstructionSpace = 12;
    388         static const int sequenceOpCallConstantSpace = 2;
    389         // sequenceMethodCheck
    390         static const int sequenceMethodCheckInstructionSpace = 40;
    391         static const int sequenceMethodCheckConstantSpace = 6;
    392         // sequenceGetByIdHotPath
    393         static const int sequenceGetByIdHotPathInstructionSpace = 36;
    394         static const int sequenceGetByIdHotPathConstantSpace = 4;
    395         // sequenceGetByIdSlowCase
    396         static const int sequenceGetByIdSlowCaseInstructionSpace = 56;
    397         static const int sequenceGetByIdSlowCaseConstantSpace = 2;
    398         // sequencePutById
    399         static const int sequencePutByIdInstructionSpace = 36;
    400         static const int sequencePutByIdConstantSpace = 4;
    401 #elif CPU(ARM_THUMB2)
    402         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    403         static const int patchOffsetPutByIdStructure = 10;
    404         static const int patchOffsetPutByIdPropertyMapOffset1 = 36;
    405         static const int patchOffsetPutByIdPropertyMapOffset2 = 48;
    406         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    407         static const int patchOffsetGetByIdStructure = 10;
    408         static const int patchOffsetGetByIdBranchToSlowCase = 26;
    409         static const int patchOffsetGetByIdPropertyMapOffset1 = 36;
    410         static const int patchOffsetGetByIdPropertyMapOffset2 = 48;
    411         static const int patchOffsetGetByIdPutResult = 52;
    412 #if ENABLE(OPCODE_SAMPLING)
    413         #error "OPCODE_SAMPLING is not yet supported"
    414 #else
    415         static const int patchOffsetGetByIdSlowCaseCall = 30;
    416 #endif
    417         static const int patchOffsetOpCallCompareToJump = 16;
    418 
    419         static const int patchOffsetMethodCheckProtoObj = 24;
    420         static const int patchOffsetMethodCheckProtoStruct = 34;
    421         static const int patchOffsetMethodCheckPutFunction = 58;
    422 
    423         // sequenceOpCall
    424         static const int sequenceOpCallInstructionSpace = 12;
    425         static const int sequenceOpCallConstantSpace = 2;
    426         // sequenceMethodCheck
    427         static const int sequenceMethodCheckInstructionSpace = 40;
    428         static const int sequenceMethodCheckConstantSpace = 6;
    429         // sequenceGetByIdHotPath
    430         static const int sequenceGetByIdHotPathInstructionSpace = 36;
    431         static const int sequenceGetByIdHotPathConstantSpace = 4;
    432         // sequenceGetByIdSlowCase
    433         static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
    434         static const int sequenceGetByIdSlowCaseConstantSpace = 2;
    435         // sequencePutById
    436         static const int sequencePutByIdInstructionSpace = 36;
    437         static const int sequencePutByIdConstantSpace = 4;
    438 #elif CPU(MIPS)
    439 #if WTF_MIPS_ISA(1)
    440         static const int patchOffsetPutByIdStructure = 16;
    441         static const int patchOffsetPutByIdPropertyMapOffset1 = 56;
    442         static const int patchOffsetPutByIdPropertyMapOffset2 = 72;
    443         static const int patchOffsetGetByIdStructure = 16;
    444         static const int patchOffsetGetByIdBranchToSlowCase = 48;
    445         static const int patchOffsetGetByIdPropertyMapOffset1 = 56;
    446         static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
    447         static const int patchOffsetGetByIdPutResult = 96;
    448 #if ENABLE(OPCODE_SAMPLING)
    449         #error "OPCODE_SAMPLING is not yet supported"
    450 #else
    451         static const int patchOffsetGetByIdSlowCaseCall = 44;
    452 #endif
    453         static const int patchOffsetOpCallCompareToJump = 32;
    454         static const int patchOffsetMethodCheckProtoObj = 32;
    455         static const int patchOffsetMethodCheckProtoStruct = 56;
    456         static const int patchOffsetMethodCheckPutFunction = 88;
    457 #else // WTF_MIPS_ISA(1)
    458         static const int patchOffsetPutByIdStructure = 12;
    459         static const int patchOffsetPutByIdPropertyMapOffset1 = 48;
    460         static const int patchOffsetPutByIdPropertyMapOffset2 = 64;
    461         static const int patchOffsetGetByIdStructure = 12;
    462         static const int patchOffsetGetByIdBranchToSlowCase = 44;
    463         static const int patchOffsetGetByIdPropertyMapOffset1 = 48;
    464         static const int patchOffsetGetByIdPropertyMapOffset2 = 64;
    465         static const int patchOffsetGetByIdPutResult = 80;
    466 #if ENABLE(OPCODE_SAMPLING)
    467         #error "OPCODE_SAMPLING is not yet supported"
    468 #else
    469         static const int patchOffsetGetByIdSlowCaseCall = 44;
    470 #endif
    471         static const int patchOffsetOpCallCompareToJump = 32;
    472         static const int patchOffsetMethodCheckProtoObj = 32;
    473         static const int patchOffsetMethodCheckProtoStruct = 52;
    474         static const int patchOffsetMethodCheckPutFunction = 84;
    475 #endif
    476 #elif CPU(SH4)
    477        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    478         static const int patchOffsetGetByIdStructure = 6;
    479         static const int patchOffsetPutByIdPropertyMapOffset = 24;
    480         static const int patchOffsetPutByIdStructure = 6;
    481         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    482         static const int patchOffsetGetByIdBranchToSlowCase = 10;
    483         static const int patchOffsetGetByIdPropertyMapOffset = 24;
    484         static const int patchOffsetGetByIdPutResult = 32;
    485 
    486         // sequenceOpCall
    487         static const int sequenceOpCallInstructionSpace = 12;
    488         static const int sequenceOpCallConstantSpace = 2;
    489         // sequenceMethodCheck
    490         static const int sequenceMethodCheckInstructionSpace = 40;
    491         static const int sequenceMethodCheckConstantSpace = 6;
    492         // sequenceGetByIdHotPath
    493         static const int sequenceGetByIdHotPathInstructionSpace = 36;
    494         static const int sequenceGetByIdHotPathConstantSpace = 5;
    495         // sequenceGetByIdSlowCase
    496         static const int sequenceGetByIdSlowCaseInstructionSpace = 26;
    497         static const int sequenceGetByIdSlowCaseConstantSpace = 2;
    498         // sequencePutById
    499         static const int sequencePutByIdInstructionSpace = 36;
    500         static const int sequencePutByIdConstantSpace = 5;
    501 
    502         static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
    503         static const int patchOffsetGetByIdPropertyMapOffset2 = 26;
    504 
    505         static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
    506         static const int patchOffsetPutByIdPropertyMapOffset2 = 26;
    507 
    508 #if ENABLE(OPCODE_SAMPLING)
    509         static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
    510 #else
    511         static const int patchOffsetGetByIdSlowCaseCall = 22;
    512 #endif
    513         static const int patchOffsetOpCallCompareToJump = 4;
    514 
    515         static const int patchOffsetMethodCheckProtoObj = 12;
    516         static const int patchOffsetMethodCheckProtoStruct = 20;
    517         static const int patchOffsetMethodCheckPutFunction = 32;
    518 #else
    519 #error "JSVALUE32_64 not supported on this platform."
    520 #endif
    521 
    522 #else // USE(JSVALUE32_64)
    523         void emitGetVirtualRegister(int src, RegisterID dst);
    524         void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
    525         void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0);
    526 
    527         int32_t getConstantOperandImmediateInt(unsigned src);
    528 
    529         void killLastResultRegister();
    530 
    531         Jump emitJumpIfJSCell(RegisterID);
    532         Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
    533         void emitJumpSlowCaseIfJSCell(RegisterID);
    534         Jump emitJumpIfNotJSCell(RegisterID);
    535         void emitJumpSlowCaseIfNotJSCell(RegisterID);
    536         void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
    537 #if USE(JSVALUE32_64)
    538         JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
    539         {
    540             return emitJumpIfImmediateInteger(reg);
    541         }
    542 
    543         JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg)
    544         {
    545             return emitJumpIfNotImmediateInteger(reg);
    546         }
    547 #endif
    548         JIT::Jump emitJumpIfImmediateInteger(RegisterID);
    549         JIT::Jump emitJumpIfNotImmediateInteger(RegisterID);
    550         JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
    551         void emitJumpSlowCaseIfNotImmediateInteger(RegisterID);
    552         void emitJumpSlowCaseIfNotImmediateNumber(RegisterID);
    553         void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
    554 
    555 #if USE(JSVALUE32_64)
    556         void emitFastArithDeTagImmediate(RegisterID);
    557         Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
    558 #endif
    559         void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
    560         void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
    561 
    562         void emitTagAsBoolImmediate(RegisterID reg);
    563         void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
    564 #if USE(JSVALUE64)
    565         void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase);
    566 #else
    567         void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes);
    568 #endif
    569 
    570 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
    571         void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex);
    572         void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
    573 #endif
    574         void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset);
    575         void compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset);
    576         void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch);
    577         void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset);
    578 
    579 #if CPU(X86_64)
    580         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    581         static const int patchOffsetPutByIdStructure = 10;
    582         static const int patchOffsetPutByIdPropertyMapOffset = 31;
    583         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    584         static const int patchOffsetGetByIdStructure = 10;
    585         static const int patchOffsetGetByIdBranchToSlowCase = 20;
    586         static const int patchOffsetGetByIdPropertyMapOffset = 31;
    587         static const int patchOffsetGetByIdPutResult = 31;
    588 #if ENABLE(OPCODE_SAMPLING)
    589         static const int patchOffsetGetByIdSlowCaseCall = 64;
    590 #else
    591         static const int patchOffsetGetByIdSlowCaseCall = 41;
    592 #endif
    593         static const int patchOffsetOpCallCompareToJump = 9;
    594 
    595         static const int patchOffsetMethodCheckProtoObj = 20;
    596         static const int patchOffsetMethodCheckProtoStruct = 30;
    597         static const int patchOffsetMethodCheckPutFunction = 50;
    598 #elif CPU(X86)
    599         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    600         static const int patchOffsetPutByIdStructure = 7;
    601         static const int patchOffsetPutByIdPropertyMapOffset = 22;
    602         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    603         static const int patchOffsetGetByIdStructure = 7;
    604         static const int patchOffsetGetByIdBranchToSlowCase = 13;
    605         static const int patchOffsetGetByIdPropertyMapOffset = 22;
    606         static const int patchOffsetGetByIdPutResult = 22;
    607 #if ENABLE(OPCODE_SAMPLING)
    608         static const int patchOffsetGetByIdSlowCaseCall = 33;
    609 #else
    610         static const int patchOffsetGetByIdSlowCaseCall = 23;
    611 #endif
    612         static const int patchOffsetOpCallCompareToJump = 6;
    613 
    614         static const int patchOffsetMethodCheckProtoObj = 11;
    615         static const int patchOffsetMethodCheckProtoStruct = 18;
    616         static const int patchOffsetMethodCheckPutFunction = 29;
    617 #elif CPU(ARM_THUMB2)
    618         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    619         static const int patchOffsetPutByIdStructure = 10;
    620         static const int patchOffsetPutByIdPropertyMapOffset = 46;
    621         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    622         static const int patchOffsetGetByIdStructure = 10;
    623         static const int patchOffsetGetByIdBranchToSlowCase = 26;
    624         static const int patchOffsetGetByIdPropertyMapOffset = 46;
    625         static const int patchOffsetGetByIdPutResult = 50;
    626 #if ENABLE(OPCODE_SAMPLING)
    627         static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
    628 #else
    629         static const int patchOffsetGetByIdSlowCaseCall = 28;
    630 #endif
    631         static const int patchOffsetOpCallCompareToJump = 16;
    632 
    633         static const int patchOffsetMethodCheckProtoObj = 24;
    634         static const int patchOffsetMethodCheckProtoStruct = 34;
    635         static const int patchOffsetMethodCheckPutFunction = 58;
    636 #elif CPU(ARM_TRADITIONAL)
    637         // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    638         static const int patchOffsetPutByIdStructure = 4;
    639         static const int patchOffsetPutByIdPropertyMapOffset = 20;
    640         // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    641         static const int patchOffsetGetByIdStructure = 4;
    642         static const int patchOffsetGetByIdBranchToSlowCase = 16;
    643         static const int patchOffsetGetByIdPropertyMapOffset = 20;
    644         static const int patchOffsetGetByIdPutResult = 28;
    645 #if ENABLE(OPCODE_SAMPLING)
    646         #error "OPCODE_SAMPLING is not yet supported"
    647 #else
    648         static const int patchOffsetGetByIdSlowCaseCall = 28;
    649 #endif
    650         static const int patchOffsetOpCallCompareToJump = 12;
    651 
    652         static const int patchOffsetMethodCheckProtoObj = 12;
    653         static const int patchOffsetMethodCheckProtoStruct = 20;
    654         static const int patchOffsetMethodCheckPutFunction = 32;
    655 
    656         // sequenceOpCall
    657         static const int sequenceOpCallInstructionSpace = 12;
    658         static const int sequenceOpCallConstantSpace = 2;
    659         // sequenceMethodCheck
    660         static const int sequenceMethodCheckInstructionSpace = 40;
    661         static const int sequenceMethodCheckConstantSpace = 6;
    662         // sequenceGetByIdHotPath
    663         static const int sequenceGetByIdHotPathInstructionSpace = 28;
    664         static const int sequenceGetByIdHotPathConstantSpace = 3;
    665         // sequenceGetByIdSlowCase
    666         static const int sequenceGetByIdSlowCaseInstructionSpace = 32;
    667         static const int sequenceGetByIdSlowCaseConstantSpace = 2;
    668         // sequencePutById
    669         static const int sequencePutByIdInstructionSpace = 28;
    670         static const int sequencePutByIdConstantSpace = 3;
    671 #elif CPU(MIPS)
    672 #if WTF_MIPS_ISA(1)
    673         static const int patchOffsetPutByIdStructure = 16;
    674         static const int patchOffsetPutByIdPropertyMapOffset = 68;
    675         static const int patchOffsetGetByIdStructure = 16;
    676         static const int patchOffsetGetByIdBranchToSlowCase = 48;
    677         static const int patchOffsetGetByIdPropertyMapOffset = 68;
    678         static const int patchOffsetGetByIdPutResult = 88;
    679 #if ENABLE(OPCODE_SAMPLING)
    680         #error "OPCODE_SAMPLING is not yet supported"
    681 #else
    682         static const int patchOffsetGetByIdSlowCaseCall = 40;
    683 #endif
    684         static const int patchOffsetOpCallCompareToJump = 32;
    685         static const int patchOffsetMethodCheckProtoObj = 32;
    686         static const int patchOffsetMethodCheckProtoStruct = 56;
    687         static const int patchOffsetMethodCheckPutFunction = 88;
    688 #else // WTF_MIPS_ISA(1)
    689         static const int patchOffsetPutByIdStructure = 12;
    690         static const int patchOffsetPutByIdPropertyMapOffset = 60;
    691         static const int patchOffsetGetByIdStructure = 12;
    692         static const int patchOffsetGetByIdBranchToSlowCase = 44;
    693         static const int patchOffsetGetByIdPropertyMapOffset = 60;
    694         static const int patchOffsetGetByIdPutResult = 76;
    695 #if ENABLE(OPCODE_SAMPLING)
    696         #error "OPCODE_SAMPLING is not yet supported"
    697 #else
    698         static const int patchOffsetGetByIdSlowCaseCall = 40;
    699 #endif
    700         static const int patchOffsetOpCallCompareToJump = 32;
    701         static const int patchOffsetMethodCheckProtoObj = 32;
    702         static const int patchOffsetMethodCheckProtoStruct = 52;
    703         static const int patchOffsetMethodCheckPutFunction = 84;
    704 #endif
    705 #endif
    706 #endif // USE(JSVALUE32_64)
    707 
    708 #if (defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL)
    709 #define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false)
    710 #define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace, dst); } while (false)
    711 #define END_UNINTERRUPTED_SEQUENCE(name) END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, 0)
    712 
    713         void beginUninterruptedSequence(int, int);
    714         void endUninterruptedSequence(int, int, int);
    715 
    716 #else
    717 #define BEGIN_UNINTERRUPTED_SEQUENCE(name)  do { beginUninterruptedSequence(); } while (false)
    718 #define END_UNINTERRUPTED_SEQUENCE(name)  do { endUninterruptedSequence(); } while (false)
    719 #define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(); } while (false)
    720 #endif
    721 
    722         void emit_op_add(Instruction*);
    723         void emit_op_bitand(Instruction*);
    724         void emit_op_bitnot(Instruction*);
    725         void emit_op_bitor(Instruction*);
    726         void emit_op_bitxor(Instruction*);
    727         void emit_op_call(Instruction*);
    728         void emit_op_call_eval(Instruction*);
    729         void emit_op_call_varargs(Instruction*);
    730         void emit_op_call_put_result(Instruction*);
    731         void emit_op_catch(Instruction*);
    732         void emit_op_construct(Instruction*);
    733         void emit_op_get_callee(Instruction*);
    734         void emit_op_create_this(Instruction*);
    735         void emit_op_convert_this(Instruction*);
    736         void emit_op_convert_this_strict(Instruction*);
    737         void emit_op_create_arguments(Instruction*);
    738         void emit_op_debug(Instruction*);
    739         void emit_op_del_by_id(Instruction*);
    740         void emit_op_div(Instruction*);
    741         void emit_op_end(Instruction*);
    742         void emit_op_enter(Instruction*);
    743         void emit_op_create_activation(Instruction*);
    744         void emit_op_eq(Instruction*);
    745         void emit_op_eq_null(Instruction*);
    746         void emit_op_get_by_id(Instruction*);
    747         void emit_op_get_arguments_length(Instruction*);
    748         void emit_op_get_by_val(Instruction*);
    749         void emit_op_get_argument_by_val(Instruction*);
    750         void emit_op_get_by_pname(Instruction*);
    751         void emit_op_get_global_var(Instruction*);
    752         void emit_op_get_scoped_var(Instruction*);
    753         void emit_op_init_lazy_reg(Instruction*);
    754         void emit_op_check_has_instance(Instruction*);
    755         void emit_op_instanceof(Instruction*);
    756         void emit_op_jeq_null(Instruction*);
    757         void emit_op_jfalse(Instruction*);
    758         void emit_op_jmp(Instruction*);
    759         void emit_op_jmp_scopes(Instruction*);
    760         void emit_op_jneq_null(Instruction*);
    761         void emit_op_jneq_ptr(Instruction*);
    762         void emit_op_jnless(Instruction*);
    763         void emit_op_jless(Instruction*);
    764         void emit_op_jlesseq(Instruction*, bool invert = false);
    765         void emit_op_jnlesseq(Instruction*);
    766         void emit_op_jsr(Instruction*);
    767         void emit_op_jtrue(Instruction*);
    768         void emit_op_load_varargs(Instruction*);
    769         void emit_op_loop(Instruction*);
    770         void emit_op_loop_if_less(Instruction*);
    771         void emit_op_loop_if_lesseq(Instruction*);
    772         void emit_op_loop_if_true(Instruction*);
    773         void emit_op_loop_if_false(Instruction*);
    774         void emit_op_lshift(Instruction*);
    775         void emit_op_method_check(Instruction*);
    776         void emit_op_mod(Instruction*);
    777         void emit_op_mov(Instruction*);
    778         void emit_op_mul(Instruction*);
    779         void emit_op_negate(Instruction*);
    780         void emit_op_neq(Instruction*);
    781         void emit_op_neq_null(Instruction*);
    782         void emit_op_new_array(Instruction*);
    783         void emit_op_new_func(Instruction*);
    784         void emit_op_new_func_exp(Instruction*);
    785         void emit_op_new_object(Instruction*);
    786         void emit_op_new_regexp(Instruction*);
    787         void emit_op_get_pnames(Instruction*);
    788         void emit_op_next_pname(Instruction*);
    789         void emit_op_not(Instruction*);
    790         void emit_op_nstricteq(Instruction*);
    791         void emit_op_pop_scope(Instruction*);
    792         void emit_op_post_dec(Instruction*);
    793         void emit_op_post_inc(Instruction*);
    794         void emit_op_pre_dec(Instruction*);
    795         void emit_op_pre_inc(Instruction*);
    796         void emit_op_profile_did_call(Instruction*);
    797         void emit_op_profile_will_call(Instruction*);
    798         void emit_op_push_new_scope(Instruction*);
    799         void emit_op_push_scope(Instruction*);
    800         void emit_op_put_by_id(Instruction*);
    801         void emit_op_put_by_index(Instruction*);
    802         void emit_op_put_by_val(Instruction*);
    803         void emit_op_put_getter(Instruction*);
    804         void emit_op_put_global_var(Instruction*);
    805         void emit_op_put_scoped_var(Instruction*);
    806         void emit_op_put_setter(Instruction*);
    807         void emit_op_resolve(Instruction*);
    808         void emit_op_resolve_base(Instruction*);
    809         void emit_op_ensure_property_exists(Instruction*);
    810         void emit_op_resolve_global(Instruction*, bool dynamic = false);
    811         void emit_op_resolve_global_dynamic(Instruction*);
    812         void emit_op_resolve_skip(Instruction*);
    813         void emit_op_resolve_with_base(Instruction*);
    814         void emit_op_ret(Instruction*);
    815         void emit_op_ret_object_or_this(Instruction*);
    816         void emit_op_rshift(Instruction*);
    817         void emit_op_sret(Instruction*);
    818         void emit_op_strcat(Instruction*);
    819         void emit_op_stricteq(Instruction*);
    820         void emit_op_sub(Instruction*);
    821         void emit_op_switch_char(Instruction*);
    822         void emit_op_switch_imm(Instruction*);
    823         void emit_op_switch_string(Instruction*);
    824         void emit_op_tear_off_activation(Instruction*);
    825         void emit_op_tear_off_arguments(Instruction*);
    826         void emit_op_throw(Instruction*);
    827         void emit_op_throw_reference_error(Instruction*);
    828         void emit_op_to_jsnumber(Instruction*);
    829         void emit_op_to_primitive(Instruction*);
    830         void emit_op_unexpected_load(Instruction*);
    831         void emit_op_urshift(Instruction*);
    832 #if ENABLE(JIT_USE_SOFT_MODULO)
    833         void softModulo();
    834 #endif
    835 
    836         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
    837         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
    838         void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&);
    839         void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&);
    840         void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&);
    841         void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&);
    842         void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&);
    843         void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
    844         void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
    845         void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
    846         void emitSlow_op_convert_this_strict(Instruction*, Vector<SlowCaseEntry>::iterator&);
    847         void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
    848         void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    849         void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
    850         void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&);
    851         void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
    852         void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
    853         void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
    854         void emitSlow_op_check_has_instance(Instruction*, Vector<SlowCaseEntry>::iterator&);
    855         void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
    856         void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
    857         void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
    858         void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
    859         void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false);
    860         void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    861         void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
    862         void emitSlow_op_load_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
    863         void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
    864         void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    865         void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
    866         void emitSlow_op_loop_if_false(Instruction*, Vector<SlowCaseEntry>::iterator&);
    867         void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
    868         void emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
    869         void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&);
    870         void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
    871         void emitSlow_op_negate(Instruction*, Vector<SlowCaseEntry>::iterator&);
    872         void emitSlow_op_neq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    873         void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&);
    874         void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    875         void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
    876         void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
    877         void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
    878         void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
    879         void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
    880         void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
    881         void emitSlow_op_resolve_global(Instruction*, Vector<SlowCaseEntry>::iterator&);
    882         void emitSlow_op_resolve_global_dynamic(Instruction*, Vector<SlowCaseEntry>::iterator&);
    883         void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
    884         void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    885         void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
    886         void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
    887         void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
    888         void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
    889 
    890 
    891         void emitRightShift(Instruction*, bool isUnsigned);
    892         void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned);
    893 
    894         /* This function is deprecated. */
    895         void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst);
    896 
    897         void emitInitRegister(unsigned dst);
    898 
    899         void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
    900         void emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
    901         void emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
    902         void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
    903         void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
    904         void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
    905 
    906         JSValue getConstantOperand(unsigned src);
    907         bool isOperandConstantImmediateInt(unsigned src);
    908         bool isOperandConstantImmediateChar(unsigned src);
    909 
    910         Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
    911         {
    912             return iter++->from;
    913         }
    914         void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter)
    915         {
    916             iter->from.link(this);
    917             ++iter;
    918         }
    919         void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg);
    920 
    921         Jump checkStructure(RegisterID reg, Structure* structure);
    922 
    923         void restoreArgumentReference();
    924         void restoreArgumentReferenceForTrampoline();
    925 
    926         Call emitNakedCall(CodePtr function = CodePtr());
    927 
    928         void preserveReturnAddressAfterCall(RegisterID);
    929         void restoreReturnAddressBeforeReturn(RegisterID);
    930         void restoreReturnAddressBeforeReturn(Address);
    931 
    932         // Loads the character value of a single character string into dst.
    933         void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures);
    934 
    935         void emitTimeoutCheck();
    936 #ifndef NDEBUG
    937         void printBytecodeOperandTypes(unsigned src1, unsigned src2);
    938 #endif
    939 
    940 #if ENABLE(SAMPLING_FLAGS)
    941         void setSamplingFlag(int32_t);
    942         void clearSamplingFlag(int32_t);
    943 #endif
    944 
    945 #if ENABLE(SAMPLING_COUNTERS)
    946         void emitCount(AbstractSamplingCounter&, uint32_t = 1);
    947 #endif
    948 
    949 #if ENABLE(OPCODE_SAMPLING)
    950         void sampleInstruction(Instruction*, bool = false);
    951 #endif
    952 
    953 #if ENABLE(CODEBLOCK_SAMPLING)
    954         void sampleCodeBlock(CodeBlock*);
    955 #else
    956         void sampleCodeBlock(CodeBlock*) {}
    957 #endif
    958 
    959         Interpreter* m_interpreter;
    960         JSGlobalData* m_globalData;
    961         CodeBlock* m_codeBlock;
    962 
    963         Vector<CallRecord> m_calls;
    964         Vector<Label> m_labels;
    965         Vector<PropertyStubCompilationInfo> m_propertyAccessCompilationInfo;
    966         Vector<StructureStubCompilationInfo> m_callStructureStubCompilationInfo;
    967         Vector<MethodCallCompilationInfo> m_methodCallCompilationInfo;
    968         Vector<JumpTable> m_jmpTable;
    969 
    970         unsigned m_bytecodeOffset;
    971         Vector<JSRInfo> m_jsrSites;
    972         Vector<SlowCaseEntry> m_slowCases;
    973         Vector<SwitchRecord> m_switches;
    974 
    975         unsigned m_propertyAccessInstructionIndex;
    976         unsigned m_globalResolveInfoIndex;
    977         unsigned m_callLinkInfoIndex;
    978 
    979 #if USE(JSVALUE32_64)
    980         unsigned m_jumpTargetIndex;
    981         unsigned m_mappedBytecodeOffset;
    982         unsigned m_mappedVirtualRegisterIndex;
    983         RegisterID m_mappedTag;
    984         RegisterID m_mappedPayload;
    985 #else
    986         int m_lastResultBytecodeRegister;
    987         unsigned m_jumpTargetsPosition;
    988 #endif
    989 
    990 #ifndef NDEBUG
    991 #if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
    992         Label m_uninterruptedInstructionSequenceBegin;
    993         int m_uninterruptedConstantSequenceBegin;
    994 #endif
    995 #endif
    996         void* m_linkerOffset;
    997         static CodePtr stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool);
    998     } JIT_CLASS_ALIGNMENT;
    999 
   1000     inline void JIT::emit_op_loop(Instruction* currentInstruction)
   1001     {
   1002         emitTimeoutCheck();
   1003         emit_op_jmp(currentInstruction);
   1004     }
   1005 
   1006     inline void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
   1007     {
   1008         emitTimeoutCheck();
   1009         emit_op_jtrue(currentInstruction);
   1010     }
   1011 
   1012     inline void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
   1013     {
   1014         emitSlow_op_jtrue(currentInstruction, iter);
   1015     }
   1016 
   1017     inline void JIT::emit_op_loop_if_false(Instruction* currentInstruction)
   1018     {
   1019         emitTimeoutCheck();
   1020         emit_op_jfalse(currentInstruction);
   1021     }
   1022 
   1023     inline void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
   1024     {
   1025         emitSlow_op_jfalse(currentInstruction, iter);
   1026     }
   1027 
   1028     inline void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
   1029     {
   1030         emitTimeoutCheck();
   1031         emit_op_jless(currentInstruction);
   1032     }
   1033 
   1034     inline void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
   1035     {
   1036         emitSlow_op_jless(currentInstruction, iter);
   1037     }
   1038 
   1039 } // namespace JSC
   1040 
   1041 #endif // ENABLE(JIT)
   1042 
   1043 #endif // JIT_h
   1044