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

ggaren@apple.com's avatar
ggaren@apple.com committed
26 27
#ifndef JIT_h
#define JIT_h
28

29
#if ENABLE(JIT)
30

31 32
// Verbose logging of code generation
#define ENABLE_JIT_VERBOSE 0
33 34 35
// Verbose logging for OSR-related code.
#define ENABLE_JIT_VERBOSE_OSR 0

36 37 38 39 40 41 42 43
// We've run into some problems where changing the size of the class JIT leads to
// performance fluctuations.  Try forcing alignment in an attempt to stabalize this.
#if COMPILER(GCC)
#define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32)))
#else
#define JIT_CLASS_ALIGNMENT
#endif

44
#define ASSERT_JIT_OFFSET_UNUSED(variable, actual, expected) ASSERT_WITH_MESSAGE_UNUSED(variable, actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(expected), static_cast<int>(actual));
45
#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));
46

47
#include "CodeBlock.h"
48
#include "CompactJITCodeMap.h"
ggaren@apple.com's avatar
ggaren@apple.com committed
49
#include "Interpreter.h"
50
#include "JSInterfaceJIT.h"
51
#include "Opcode.h"
52
#include "Profiler.h"
53
#include <bytecode/SamplingTool.h>
54

55
namespace JSC {
56 57

    class CodeBlock;
58
    class FunctionExecutable;
59
    class JIT;
60
    class JSPropertyNameIterator;
61
    class Interpreter;
62 63 64
    class Register;
    class RegisterFile;
    class ScopeChainNode;
darin@apple.com's avatar
darin@apple.com committed
65
    class StructureChain;
darin@apple.com's avatar
darin@apple.com committed
66

67
    struct CallLinkInfo;
68
    struct Instruction;
69
    struct OperandTypes;
70
    struct PolymorphicAccessStructureList;
71 72
    struct SimpleJumpTable;
    struct StringJumpTable;
73
    struct StructureStubInfo;
74 75

    struct CallRecord {
76
        MacroAssembler::Call from;
77
        unsigned bytecodeOffset;
78
        void* to;
79 80 81 82 83

        CallRecord()
        {
        }

84
        CallRecord(MacroAssembler::Call from, unsigned bytecodeOffset, void* to = 0)
85
            : from(from)
86
            , bytecodeOffset(bytecodeOffset)
87
            , to(to)
88 89
        {
        }
90 91
    };

92 93
    struct JumpTable {
        MacroAssembler::Jump from;
94
        unsigned toBytecodeOffset;
95 96

        JumpTable(MacroAssembler::Jump f, unsigned t)
97
            : from(f)
98
            , toBytecodeOffset(t)
99 100 101 102 103
        {
        }
    };

    struct SlowCaseEntry {
104
        MacroAssembler::Jump from;
105 106 107
        unsigned to;
        unsigned hint;
        
108
        SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0)
109 110 111 112 113 114 115 116 117 118 119 120 121 122
            : from(f)
            , to(t)
            , hint(h)
        {
        }
    };

    struct SwitchRecord {
        enum Type {
            Immediate,
            Character,
            String
        };

123
        Type type;
124 125

        union {
126 127 128
            SimpleJumpTable* simpleJumpTable;
            StringJumpTable* stringJumpTable;
        } jumpTable;
129

130
        unsigned bytecodeOffset;
131
        unsigned defaultOffset;
132

133
        SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset, Type type)
134
            : type(type)
135
            , bytecodeOffset(bytecodeOffset)
136
            , defaultOffset(defaultOffset)
137
        {
138
            this->jumpTable.simpleJumpTable = jumpTable;
139 140
        }

141
        SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeOffset, unsigned defaultOffset)
142
            : type(String)
143
            , bytecodeOffset(bytecodeOffset)
144
            , defaultOffset(defaultOffset)
145
        {
146
            this->jumpTable.stringJumpTable = jumpTable;
147 148 149
        }
    };

150
    struct PropertyStubCompilationInfo {
151
        unsigned bytecodeIndex;
152
        MacroAssembler::Call callReturnLocation;
153
        MacroAssembler::Label hotPathBegin;
154 155 156 157 158 159 160
        
#if !ASSERT_DISABLED
        PropertyStubCompilationInfo()
            : bytecodeIndex(std::numeric_limits<unsigned>::max())
        {
        }
#endif
161 162
    };

163
    struct StructureStubCompilationInfo {
164
        MacroAssembler::DataLabelPtr hotPathBegin;
165 166
        MacroAssembler::Call hotPathOther;
        MacroAssembler::Call callReturnLocation;
167
        bool isCall;
168 169
    };

170
    struct MethodCallCompilationInfo {
171 172 173
        MethodCallCompilationInfo(unsigned bytecodeIndex, unsigned propertyAccessIndex)
            : bytecodeIndex(bytecodeIndex)
            , propertyAccessIndex(propertyAccessIndex)
174 175 176
        {
        }

177
        unsigned bytecodeIndex;
178 179 180 181
        MacroAssembler::DataLabelPtr structureToCompare;
        unsigned propertyAccessIndex;
    };

182
    // Near calls can only be patched to other JIT code, regular calls can be patched to JIT code or relinked to stub functions.
183 184 185
    void ctiPatchNearCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
    void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
    void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction);
186

187
    class JIT : private JSInterfaceJIT {
188 189
        friend class JITStubCall;

190 191 192 193
        using MacroAssembler::Jump;
        using MacroAssembler::JumpList;
        using MacroAssembler::Label;

194
        static const int patchGetByIdDefaultStructure = -1;
195
        static const int patchGetByIdDefaultOffset = 0;
196
        // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
197
        // will compress the displacement, and we may not be able to fit a patched offset.
198
        static const int patchPutByIdDefaultOffset = 256;
199

200
    public:
201
        static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0)
202
        {
203
            return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck);
204 205
        }

206
        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)
207
        {
208
            JIT jit(globalData, codeBlock);
209
            jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame);
210 211
        }

212
        static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
213 214
        {
            JIT jit(globalData, codeBlock);
215
            jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset);
216
        }
217
        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)
218 219
        {
            JIT jit(globalData, codeBlock);
220
            jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame);
221
        }
222
        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)
223 224
        {
            JIT jit(globalData, codeBlock);
225
            jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame);
226
        }
227

228
        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)
229
        {
230
            JIT jit(globalData, codeBlock);
231
            jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame);
232
        }
233
        
234
        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
235
        {
236
            JIT jit(globalData, codeBlock);
237
            jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct);
238
        }
239

240
        static PassRefPtr<ExecutableMemoryHandle> compileCTIMachineTrampolines(JSGlobalData* globalData, TrampolineStructure *trampolines)
241
        {
242
            if (!globalData->canUseJIT())
243
                return 0;
244
            JIT jit(globalData, 0);
245
            return jit.privateCompileCTIMachineTrampolines(globalData, trampolines);
246 247
        }

248
        static CodeRef compileCTINativeCall(JSGlobalData* globalData, NativeFunction func)
249
        {
250
            if (!globalData->canUseJIT())
251
                return CodeRef();
252
            JIT jit(globalData, 0);
253
            return jit.privateCompileCTINativeCall(globalData, func);
254 255
        }

256
        static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
257
        static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
258
        static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, JSObject*, Structure*, JSObject*, ReturnAddressPtr);
259

260
        static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
261
        {
262
            JIT jit(globalData, codeBlock);
263
            return jit.privateCompilePatchGetArrayLength(returnAddress);
264 265
        }

266
        static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*, CodeSpecializationKind);
267

268
    private:
269 270 271 272 273 274 275 276 277 278 279
        struct JSRInfo {
            DataLabelPtr storeLocation;
            Label target;

            JSRInfo(DataLabelPtr storeLocation, Label targetLocation)
                : storeLocation(storeLocation)
                , target(targetLocation)
            {
            }
        };

280
        JIT(JSGlobalData*, CodeBlock* = 0);
darin@apple.com's avatar
darin@apple.com committed
281

282 283 284
        void privateCompileMainPass();
        void privateCompileLinkPass();
        void privateCompileSlowCases();
285
        JITCode privateCompile(CodePtr* functionEntryArityCheck);
286 287 288 289 290 291
        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
        void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset);
        void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
        void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct);
292

293
        PassRefPtr<ExecutableMemoryHandle> privateCompileCTIMachineTrampolines(JSGlobalData*, TrampolineStructure*);
barraclough@apple.com's avatar
barraclough@apple.com committed
294
        Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false);
295
        CodeRef privateCompileCTINativeCall(JSGlobalData*, NativeFunction);
296
        void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
297

298
        void addSlowCase(Jump);
299
        void addSlowCase(JumpList);
300
        void addSlowCase();
301 302
        void addJump(Jump, int);
        void emitJumpSlowToHot(Jump, int);
303 304

        void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex);
305
        void compileOpCallVarargs(Instruction* instruction);
306
        void compileOpCallInitializeCallFrame();
307
        void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID);
308
        void compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter);
309

310
        enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
311
        void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
312 313 314 315
        bool isOperandConstantImmediateDouble(unsigned src);
        
        void emitLoadDouble(unsigned index, FPRegisterID value);
        void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
316
        Jump emitJumpIfNotObject(RegisterID structureReg);
317
        Jump emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType);
318

319
        void testPrototype(JSValue, JumpList& failureCases);
320

321 322 323 324 325
        enum WriteBarrierMode { UnconditionalWriteBarrier, ShouldFilterImmediates };
        // value register in write barrier is used before any scratch registers
        // so may safely be the same as either of the scratch registers.
        void emitWriteBarrier(RegisterID owner, RegisterID valueTag, RegisterID scratch, RegisterID scratch2, WriteBarrierMode, WriteBarrierUseKind);
        void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
326 327 328 329

        template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, void* vtable, RegisterID result, RegisterID storagePtr);
        template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
        void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr);
330 331 332 333 334 335 336 337 338
        
        enum ValueProfilingSiteKind { FirstProfilingSite, SubsequentProfilingSite };
#if ENABLE(VALUE_PROFILER)
        // This assumes that the value to profile is in regT0 and that regT3 is available for
        // scratch.
        void emitValueProfilingSite(ValueProfilingSiteKind);
#else
        void emitValueProfilingSite(ValueProfilingSiteKind) { }
#endif
339

340 341 342 343 344 345 346 347 348 349 350 351 352
#if USE(JSVALUE32_64)
        bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);

        void emitLoadTag(unsigned index, RegisterID tag);
        void emitLoadPayload(unsigned index, RegisterID payload);

        void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload);
        void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
        void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2);

        void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
        void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister);
        void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false);
353
        void emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32 = false);
354
        void emitStoreAndMapInt32(unsigned index, RegisterID tag, RegisterID payload, bool indexIsInt32, size_t opcodeLength);
355
        void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
356
        void emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool = false);
357 358
        void emitStoreDouble(unsigned index, FPRegisterID value);

359 360
        bool isLabeled(unsigned bytecodeOffset);
        void map(unsigned bytecodeOffset, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload);
361 362 363 364 365 366 367 368 369 370 371 372
        void unmap(RegisterID);
        void unmap();
        bool isMapped(unsigned virtualRegisterIndex);
        bool getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload);
        bool getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag);

        void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex);
        void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag);
        void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, unsigned virtualRegisterIndex);

        void compileGetByIdHotPath();
        void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
373
        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
374 375
        void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset);
376
        void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, size_t cachedOffset);
377 378 379 380 381 382

        // Arithmetic opcode helpers
        void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
        void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
        void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);

383
#if CPU(X86)
384 385 386 387 388 389 390
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 7;
        static const int patchOffsetPutByIdPropertyMapOffset1 = 22;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 7;
        static const int patchOffsetGetByIdBranchToSlowCase = 13;
391 392 393
        static const int patchOffsetGetByIdPropertyMapOffset1 = 19;
        static const int patchOffsetGetByIdPropertyMapOffset2 = 22;
        static const int patchOffsetGetByIdPutResult = 22;
394
#if ENABLE(OPCODE_SAMPLING)
395 396
        static const int patchOffsetGetByIdSlowCaseCall = 37;
#else
397
        static const int patchOffsetGetByIdSlowCaseCall = 33;
398 399 400 401 402 403
#endif
        static const int patchOffsetOpCallCompareToJump = 6;

        static const int patchOffsetMethodCheckProtoObj = 11;
        static const int patchOffsetMethodCheckProtoStruct = 18;
        static const int patchOffsetMethodCheckPutFunction = 29;
404
#elif CPU(ARM_TRADITIONAL)
405 406 407 408 409 410 411 412 413 414 415 416 417
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 4;
        static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 4;
        static const int patchOffsetGetByIdBranchToSlowCase = 16;
        static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
        static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
        static const int patchOffsetGetByIdPutResult = 36;
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
418
        static const int patchOffsetGetByIdSlowCaseCall = 40;
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
#endif
        static const int patchOffsetOpCallCompareToJump = 12;

        static const int patchOffsetMethodCheckProtoObj = 12;
        static const int patchOffsetMethodCheckProtoStruct = 20;
        static const int patchOffsetMethodCheckPutFunction = 32;

        // sequenceOpCall
        static const int sequenceOpCallInstructionSpace = 12;
        static const int sequenceOpCallConstantSpace = 2;
        // sequenceMethodCheck
        static const int sequenceMethodCheckInstructionSpace = 40;
        static const int sequenceMethodCheckConstantSpace = 6;
        // sequenceGetByIdHotPath
        static const int sequenceGetByIdHotPathInstructionSpace = 36;
434 435
        static const int sequenceGetByIdHotPathConstantSpace = 4;
        // sequenceGetByIdSlowCase
436
        static const int sequenceGetByIdSlowCaseInstructionSpace = 56;
437
        static const int sequenceGetByIdSlowCaseConstantSpace = 3;
438 439 440 441 442 443
        // sequencePutById
        static const int sequencePutByIdInstructionSpace = 36;
        static const int sequencePutByIdConstantSpace = 4;
#elif CPU(ARM_THUMB2)
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 10;
444 445
        static const int patchOffsetPutByIdPropertyMapOffset1 = 36;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 48;
446 447 448
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 10;
        static const int patchOffsetGetByIdBranchToSlowCase = 26;
449 450 451
        static const int patchOffsetGetByIdPropertyMapOffset1 = 28;
        static const int patchOffsetGetByIdPropertyMapOffset2 = 30;
        static const int patchOffsetGetByIdPutResult = 32;
452 453 454
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
455
        static const int patchOffsetGetByIdSlowCaseCall = 40;
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
#endif
        static const int patchOffsetOpCallCompareToJump = 16;

        static const int patchOffsetMethodCheckProtoObj = 24;
        static const int patchOffsetMethodCheckProtoStruct = 34;
        static const int patchOffsetMethodCheckPutFunction = 58;

        // sequenceOpCall
        static const int sequenceOpCallInstructionSpace = 12;
        static const int sequenceOpCallConstantSpace = 2;
        // sequenceMethodCheck
        static const int sequenceMethodCheckInstructionSpace = 40;
        static const int sequenceMethodCheckConstantSpace = 6;
        // sequenceGetByIdHotPath
        static const int sequenceGetByIdHotPathInstructionSpace = 36;
471 472 473 474 475 476 477
        static const int sequenceGetByIdHotPathConstantSpace = 4;
        // sequenceGetByIdSlowCase
        static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
        static const int sequenceGetByIdSlowCaseConstantSpace = 2;
        // sequencePutById
        static const int sequencePutByIdInstructionSpace = 36;
        static const int sequencePutByIdConstantSpace = 4;
478 479 480
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
        static const int patchOffsetPutByIdStructure = 16;
481 482
        static const int patchOffsetPutByIdPropertyMapOffset1 = 56;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 72;
483 484
        static const int patchOffsetGetByIdStructure = 16;
        static const int patchOffsetGetByIdBranchToSlowCase = 48;
485 486 487
        static const int patchOffsetGetByIdPropertyMapOffset1 = 56;
        static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
        static const int patchOffsetGetByIdPutResult = 96;
488 489 490
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
491
        static const int patchOffsetGetByIdSlowCaseCall = 56;
492 493 494 495 496 497 498
#endif
        static const int patchOffsetOpCallCompareToJump = 32;
        static const int patchOffsetMethodCheckProtoObj = 32;
        static const int patchOffsetMethodCheckProtoStruct = 56;
        static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
        static const int patchOffsetPutByIdStructure = 12;
499 500
        static const int patchOffsetPutByIdPropertyMapOffset1 = 48;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 64;
501 502
        static const int patchOffsetGetByIdStructure = 12;
        static const int patchOffsetGetByIdBranchToSlowCase = 44;
503 504 505
        static const int patchOffsetGetByIdPropertyMapOffset1 = 48;
        static const int patchOffsetGetByIdPropertyMapOffset2 = 64;
        static const int patchOffsetGetByIdPutResult = 80;
506 507 508
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
509
        static const int patchOffsetGetByIdSlowCaseCall = 56;
510 511 512 513 514 515
#endif
        static const int patchOffsetOpCallCompareToJump = 32;
        static const int patchOffsetMethodCheckProtoObj = 32;
        static const int patchOffsetMethodCheckProtoStruct = 52;
        static const int patchOffsetMethodCheckPutFunction = 84;
#endif
516 517 518 519 520 521 522 523
#elif CPU(SH4)
       // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetGetByIdStructure = 6;
        static const int patchOffsetPutByIdPropertyMapOffset = 24;
        static const int patchOffsetPutByIdStructure = 6;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdBranchToSlowCase = 10;
        static const int patchOffsetGetByIdPropertyMapOffset = 24;
524
        static const int patchOffsetGetByIdPutResult = 24;
525 526 527 528 529 530 531 532 533 534 535

        // sequenceOpCall
        static const int sequenceOpCallInstructionSpace = 12;
        static const int sequenceOpCallConstantSpace = 2;
        // sequenceMethodCheck
        static const int sequenceMethodCheckInstructionSpace = 40;
        static const int sequenceMethodCheckConstantSpace = 6;
        // sequenceGetByIdHotPath
        static const int sequenceGetByIdHotPathInstructionSpace = 36;
        static const int sequenceGetByIdHotPathConstantSpace = 5;
        // sequenceGetByIdSlowCase
536 537
        static const int sequenceGetByIdSlowCaseInstructionSpace = 30;
        static const int sequenceGetByIdSlowCaseConstantSpace = 3;
538 539 540 541 542
        // sequencePutById
        static const int sequencePutByIdInstructionSpace = 36;
        static const int sequencePutByIdConstantSpace = 5;

        static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
543
        static const int patchOffsetGetByIdPropertyMapOffset2 = 22;
544 545 546 547 548 549 550

        static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
        static const int patchOffsetPutByIdPropertyMapOffset2 = 26;

#if ENABLE(OPCODE_SAMPLING)
        static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
#else
551
        static const int patchOffsetGetByIdSlowCaseCall = 26;
552 553 554 555 556 557
#endif
        static const int patchOffsetOpCallCompareToJump = 4;

        static const int patchOffsetMethodCheckProtoObj = 12;
        static const int patchOffsetMethodCheckProtoStruct = 20;
        static const int patchOffsetMethodCheckPutFunction = 32;
558 559 560 561 562 563 564 565
#else
#error "JSVALUE32_64 not supported on this platform."
#endif

#else // USE(JSVALUE32_64)
        void emitGetVirtualRegister(int src, RegisterID dst);
        void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
        void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0);
566 567 568 569
        void emitStoreCell(unsigned dst, RegisterID payload, bool /* only used in JSValue32_64 */ = false)
        {
            emitPutVirtualRegister(dst, payload);
        }
570 571 572 573 574 575 576 577 578 579 580

        int32_t getConstantOperandImmediateInt(unsigned src);

        void killLastResultRegister();

        Jump emitJumpIfJSCell(RegisterID);
        Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
        void emitJumpSlowCaseIfJSCell(RegisterID);
        Jump emitJumpIfNotJSCell(RegisterID);
        void emitJumpSlowCaseIfNotJSCell(RegisterID);
        void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
581
#if USE(JSVALUE32_64)
582 583 584 585 586 587 588 589 590 591
        JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
        {
            return emitJumpIfImmediateInteger(reg);
        }
        
        JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg)
        {
            return emitJumpIfNotImmediateInteger(reg);
        }
#endif
592 593 594
        Jump emitJumpIfImmediateInteger(RegisterID);
        Jump emitJumpIfNotImmediateInteger(RegisterID);
        Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
595
        void emitJumpSlowCaseIfNotImmediateInteger(RegisterID);
596
        void emitJumpSlowCaseIfNotImmediateNumber(RegisterID);
597 598
        void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);

599
#if USE(JSVALUE32_64)
600 601 602 603 604 605 606 607
        void emitFastArithDeTagImmediate(RegisterID);
        Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
#endif
        void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
        void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);

        void emitTagAsBoolImmediate(RegisterID reg);
        void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
608 609 610 611 612
#if USE(JSVALUE64)
        void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase);
#else
        void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes);
#endif
613

614
        void compileGetByIdHotPath(int baseVReg, Identifier*);
615
        void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
616
        void compileGetDirectOffset(RegisterID base, RegisterID result, size_t cachedOffset);
617 618
        void compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset);
        void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch);
619
        void compilePutDirectOffset(RegisterID base, RegisterID value, size_t cachedOffset);
620

621
#if CPU(X86_64)
622 623 624 625 626 627
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 10;
        static const int patchOffsetPutByIdPropertyMapOffset = 31;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 10;
        static const int patchOffsetGetByIdBranchToSlowCase = 20;
628 629
        static const int patchOffsetGetByIdPropertyMapOffset = 28;
        static const int patchOffsetGetByIdPutResult = 28;
630
#if ENABLE(OPCODE_SAMPLING)
oliver@apple.com's avatar
oliver@apple.com committed
631
        static const int patchOffsetGetByIdSlowCaseCall = 64;
632
#else
633
        static const int patchOffsetGetByIdSlowCaseCall = 54;
634 635
#endif
        static const int patchOffsetOpCallCompareToJump = 9;
636

637 638 639
        static const int patchOffsetMethodCheckProtoObj = 20;
        static const int patchOffsetMethodCheckProtoStruct = 30;
        static const int patchOffsetMethodCheckPutFunction = 50;
640
#elif CPU(X86)
641 642 643 644 645 646 647 648
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 7;
        static const int patchOffsetPutByIdPropertyMapOffset = 22;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 7;
        static const int patchOffsetGetByIdBranchToSlowCase = 13;
        static const int patchOffsetGetByIdPropertyMapOffset = 22;
        static const int patchOffsetGetByIdPutResult = 22;
649
#if ENABLE(OPCODE_SAMPLING)
650 651 652 653 654
        static const int patchOffsetGetByIdSlowCaseCall = 33;
#else
        static const int patchOffsetGetByIdSlowCaseCall = 23;
#endif
        static const int patchOffsetOpCallCompareToJump = 6;
655

656 657 658
        static const int patchOffsetMethodCheckProtoObj = 11;
        static const int patchOffsetMethodCheckProtoStruct = 18;
        static const int patchOffsetMethodCheckPutFunction = 29;
659
#elif CPU(ARM_THUMB2)
660 661
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 10;
662
        static const int patchOffsetPutByIdPropertyMapOffset = 46;
663 664
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 10;
665 666 667
        static const int patchOffsetGetByIdBranchToSlowCase = 26;
        static const int patchOffsetGetByIdPropertyMapOffset = 46;
        static const int patchOffsetGetByIdPutResult = 50;
668 669 670 671 672
#if ENABLE(OPCODE_SAMPLING)
        static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
#else
        static const int patchOffsetGetByIdSlowCaseCall = 28;
#endif
673
        static const int patchOffsetOpCallCompareToJump = 16;
674

675 676 677
        static const int patchOffsetMethodCheckProtoObj = 24;
        static const int patchOffsetMethodCheckProtoStruct = 34;
        static const int patchOffsetMethodCheckPutFunction = 58;
678
#elif CPU(ARM_TRADITIONAL)
679 680 681 682 683 684 685 686 687 688 689
        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
        static const int patchOffsetPutByIdStructure = 4;
        static const int patchOffsetPutByIdPropertyMapOffset = 20;
        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
        static const int patchOffsetGetByIdStructure = 4;
        static const int patchOffsetGetByIdBranchToSlowCase = 16;
        static const int patchOffsetGetByIdPropertyMapOffset = 20;
        static const int patchOffsetGetByIdPutResult = 28;
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
690
        static const int patchOffsetGetByIdSlowCaseCall = 28;
691 692 693 694 695 696
#endif
        static const int patchOffsetOpCallCompareToJump = 12;

        static const int patchOffsetMethodCheckProtoObj = 12;
        static const int patchOffsetMethodCheckProtoStruct = 20;
        static const int patchOffsetMethodCheckPutFunction = 32;
697

698 699 700 701 702 703 704 705 706 707
        // sequenceOpCall
        static const int sequenceOpCallInstructionSpace = 12;
        static const int sequenceOpCallConstantSpace = 2;
        // sequenceMethodCheck
        static const int sequenceMethodCheckInstructionSpace = 40;
        static const int sequenceMethodCheckConstantSpace = 6;
        // sequenceGetByIdHotPath
        static const int sequenceGetByIdHotPathInstructionSpace = 28;
        static const int sequenceGetByIdHotPathConstantSpace = 3;
        // sequenceGetByIdSlowCase
708
        static const int sequenceGetByIdSlowCaseInstructionSpace = 32;
709 710 711 712
        static const int sequenceGetByIdSlowCaseConstantSpace = 2;
        // sequencePutById
        static const int sequencePutByIdInstructionSpace = 28;
        static const int sequencePutByIdConstantSpace = 3;
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
        static const int patchOffsetPutByIdStructure = 16;
        static const int patchOffsetPutByIdPropertyMapOffset = 68;
        static const int patchOffsetGetByIdStructure = 16;
        static const int patchOffsetGetByIdBranchToSlowCase = 48;
        static const int patchOffsetGetByIdPropertyMapOffset = 68;
        static const int patchOffsetGetByIdPutResult = 88;
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
        static const int patchOffsetGetByIdSlowCaseCall = 40;
#endif
        static const int patchOffsetOpCallCompareToJump = 32;
        static const int patchOffsetMethodCheckProtoObj = 32;
        static const int patchOffsetMethodCheckProtoStruct = 56;
        static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
        static const int patchOffsetPutByIdStructure = 12;
        static const int patchOffsetPutByIdPropertyMapOffset = 60;
        static const int patchOffsetGetByIdStructure = 12;
        static const int patchOffsetGetByIdBranchToSlowCase = 44;
        static const int patchOffsetGetByIdPropertyMapOffset = 60;
        static const int patchOffsetGetByIdPutResult = 76;
#if ENABLE(OPCODE_SAMPLING)
        #error "OPCODE_SAMPLING is not yet supported"
#else
        static const int patchOffsetGetByIdSlowCaseCall = 40;
#endif
        static const int patchOffsetOpCallCompareToJump = 32;
        static const int patchOffsetMethodCheckProtoObj = 32;
        static const int patchOffsetMethodCheckProtoStruct = 52;
        static const int patchOffsetMethodCheckPutFunction = 84;
#endif
747
#endif
748
#endif // USE(JSVALUE32_64)
749

750
#if (defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL)
751
#define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false)
752 753
#define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace, dst); } while (false)
#define END_UNINTERRUPTED_SEQUENCE(name) END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, 0)
754 755

        void beginUninterruptedSequence(int, int);
756
        void endUninterruptedSequence(int, int, int);
757 758

#else
759 760
#define BEGIN_UNINTERRUPTED_SEQUENCE(name)  do { beginUninterruptedSequence(); } while (false)
#define END_UNINTERRUPTED_SEQUENCE(name)  do { endUninterruptedSequence(); } while (false)
761
#define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(); } while (false)
762 763
#endif

764 765 766
        void emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition);
        void emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator&);

767 768 769 770 771
        void emit_op_add(Instruction*);
        void emit_op_bitand(Instruction*);
        void emit_op_bitnot(Instruction*);
        void emit_op_bitor(Instruction*);
        void emit_op_bitxor(Instruction*);
772 773 774
        void emit_op_call(Instruction*);
        void emit_op_call_eval(Instruction*);
        void emit_op_call_varargs(Instruction*);
775
        void emit_op_call_put_result(Instruction*);
776
        void emit_op_catch(Instruction*);
777
        void emit_op_construct(Instruction*);
barraclough@apple.com's avatar
barraclough@apple.com committed
778 779
        void emit_op_get_callee(Instruction*);
        void emit_op_create_this(Instruction*);
780 781 782 783 784 785 786
        void emit_op_convert_this(Instruction*);
        void emit_op_create_arguments(Instruction*);
        void emit_op_debug(Instruction*);
        void emit_op_del_by_id(Instruction*);
        void emit_op_div(Instruction*);
        void emit_op_end(Instruction*);
        void emit_op_enter(Instruction*);
787
        void emit_op_create_activation(Instruction*);
788 789 790
        void emit_op_eq(Instruction*);
        void emit_op_eq_null(Instruction*);
        void emit_op_get_by_id(Instruction*);
791
        void emit_op_get_arguments_length(Instruction*);
792
        void emit_op_get_by_val(Instruction*);
793
        void emit_op_get_argument_by_val(Instruction*);
794
        void emit_op_get_by_pname(Instruction*);
795 796
        void emit_op_get_global_var(Instruction*);
        void emit_op_get_scoped_var(Instruction*);
797
        void emit_op_init_lazy_reg(Instruction*);
798
        void emit_op_check_has_instance(Instruction*);
799
        void emit_op_instanceof(Instruction*);
800
        void emit_op_jeq_null(Instruction*);
801 802 803
        void emit_op_jfalse(Instruction*);
        void emit_op_jmp(Instruction*);
        void emit_op_jmp_scopes(Instruction*);
804 805
        void emit_op_jneq_null(Instruction*);
        void emit_op_jneq_ptr(Instruction*);
806
        void emit_op_jless(Instruction*);
807
        void emit_op_jlesseq(Instruction*);
808 809 810
        void emit_op_jgreater(Instruction*);
        void emit_op_jgreatereq(Instruction*);
        void emit_op_jnless(Instruction*);
811
        void emit_op_jnlesseq(Instruction*);
812 813
        void emit_op_jngreater(Instruction*);
        void emit_op_jngreatereq(Instruction*);
814 815
        void emit_op_jsr(Instruction*);
        void emit_op_jtrue(Instruction*);
816 817
        void emit_op_load_varargs(Instruction*);
        void emit_op_loop(Instruction*);
818
        void emit_op_loop_hint(Instruction*);
819 820
        void emit_op_loop_if_less(Instruction*);
        void emit_op_loop_if_lesseq(Instruction*);
821 822
        void emit_op_loop_if_greater(Instruction*);
        void emit_op_loop_if_greatereq(Instruction*);
823
        void emit_op_loop_if_true(Instruction*);
824
        void emit_op_loop_if_false(Instruction*);
825 826 827 828 829 830
        void emit_op_lshift(Instruction*);
        void emit_op_method_check(Instruction*);
        void emit_op_mod(Instruction*);
        void emit_op_mov(Instruction*);
        void emit_op_mul(Instruction*);
        void emit_op_negate(Instruction*);
831
        void emit_op_neq(Instruction*);
832 833
        void emit_op_neq_null(Instruction*);
        void emit_op_new_array(Instruction*);
834
        void emit_op_new_array_buffer(Instruction*);
835 836 837
        void emit_op_new_func(Instruction*);
        void emit_op_new_func_exp(Instruction*);
        void emit_op_new_object(Instruction*);
838
        void emit_op_new_regexp(Instruction*);
839
        void emit_op_get_pnames(Instruction*);
840
        void emit_op_next_pname(Instruction*);
841
        void emit_op_not(Instruction*);
842
        void emit_op_nstricteq(Instruction*);
843 844 845 846 847
        void emit_op_pop_scope(Instruction*);
        void emit_op_post_dec(Instruction*);
        void emit_op_post_inc(Instruction*);
        void emit_op_pre_dec(Instruction*);
        void emit_op_pre_inc(Instruction*);
848 849
        void emit_op_profile_did_call(Instruction*);
        void emit_op_profile_will_call(Instruction*);
850
        void emit_op_push_new_scope(Instruction*);
851 852 853 854 855 856 857 858 859 860
        void emit_op_push_scope(Instruction*);
        void emit_op_put_by_id(Instruction*);
        void emit_op_put_by_index(Instruction*);
        void emit_op_put_by_val(Instruction*);
        void emit_op_put_getter(Instruction*);
        void emit_op_put_global_var(Instruction*);
        void emit_op_put_scoped_var(Instruction*);
        void emit_op_put_setter(Instruction*);
        void emit_op_resolve(Instruction*);
        void emit_op_resolve_base(Instruction*);
861
        void emit_op_ensure_property_exists(Instruction*);
862 863
        void emit_op_resolve_global(Instruction*, bool dynamic = false);
        void emit_op_resolve_global_dynamic(Instruction*);
864 865
        void emit_op_resolve_skip(Instruction*);
        void emit_op_resolve_with_base(Instruction*);
866
        void emit_op_resolve_with_this(Instruction*);
867
        void emit_op_ret(Instruction*);
868
        void emit_op_ret_object_or_this(Instruction*);
869 870