• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2009 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #ifndef DALVIK_VM_COMPILER_H_
18  #define DALVIK_VM_COMPILER_H_
19  
20  #include <setjmp.h>
21  #include "Thread.h"
22  
23  /*
24   * Uncomment the following to enable JIT signature breakpoint
25   * #define SIGNATURE_BREAKPOINT
26   */
27  
28  #define COMPILER_WORK_QUEUE_SIZE        100
29  #define COMPILER_IC_PATCH_QUEUE_SIZE    64
30  #define COMPILER_PC_OFFSET_SIZE         100
31  
32  /* Architectural-independent parameters for predicted chains */
33  #define PREDICTED_CHAIN_CLAZZ_INIT       0
34  #define PREDICTED_CHAIN_METHOD_INIT      0
35  #define PREDICTED_CHAIN_COUNTER_INIT     0
36  /* A fake value which will avoid initialization and won't match any class */
37  #define PREDICTED_CHAIN_FAKE_CLAZZ       0xdeadc001
38  /* Has to be positive */
39  #define PREDICTED_CHAIN_COUNTER_AVOID    0x7fffffff
40  /* Rechain after this many misses - shared globally and has to be positive */
41  #define PREDICTED_CHAIN_COUNTER_RECHAIN  8192
42  
43  #define COMPILER_TRACED(X)
44  #define COMPILER_TRACEE(X)
45  #define COMPILER_TRACE_CHAINING(X)
46  
47  /* Macro to change the permissions applied to a chunk of the code cache */
48  #define PROTECT_CODE_CACHE_ATTRS       (PROT_READ | PROT_EXEC)
49  #define UNPROTECT_CODE_CACHE_ATTRS     (PROT_READ | PROT_EXEC | PROT_WRITE)
50  
51  /* Acquire the lock before removing PROT_WRITE from the specified mem region */
52  #define UNPROTECT_CODE_CACHE(addr, size)                                       \
53      {                                                                          \
54          dvmLockMutex(&gDvmJit.codeCacheProtectionLock);                        \
55          mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask),       \
56                   (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask),        \
57                   (UNPROTECT_CODE_CACHE_ATTRS));                                \
58      }
59  
60  /* Add the PROT_WRITE to the specified memory region then release the lock */
61  #define PROTECT_CODE_CACHE(addr, size)                                         \
62      {                                                                          \
63          mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask),       \
64                   (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask),        \
65                   (PROTECT_CODE_CACHE_ATTRS));                                  \
66          dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock);                      \
67      }
68  
69  #define SINGLE_STEP_OP(opcode)                                                 \
70      (gDvmJit.includeSelectedOp !=                                              \
71       ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
72  
73  typedef enum JitInstructionSetType {
74      DALVIK_JIT_NONE = 0,
75      DALVIK_JIT_ARM,
76      DALVIK_JIT_THUMB,
77      DALVIK_JIT_THUMB2,
78      DALVIK_JIT_IA32,
79      DALVIK_JIT_MIPS
80  } JitInstructionSetType;
81  
82  /* Description of a compiled trace. */
83  typedef struct JitTranslationInfo {
84      void *codeAddress;
85      JitInstructionSetType instructionSet;
86      int profileCodeSize;
87      bool discardResult;         // Used for debugging divergence and IC patching
88      bool methodCompilationAborted;  // Cannot compile the whole method
89      Thread *requestingThread;   // For debugging purpose
90      int cacheVersion;           // Used to identify stale trace requests
91  } JitTranslationInfo;
92  
93  typedef enum WorkOrderKind {
94      kWorkOrderInvalid = 0,      // Should never see by the backend
95      kWorkOrderMethod = 1,       // Work is to compile a whole method
96      kWorkOrderTrace = 2,        // Work is to compile code fragment(s)
97      kWorkOrderTraceDebug = 3,   // Work is to compile/debug code fragment(s)
98      kWorkOrderProfileMode = 4,  // Change profiling mode
99  } WorkOrderKind;
100  
101  typedef struct CompilerWorkOrder {
102      const u2* pc;
103      WorkOrderKind kind;
104      void* info;
105      JitTranslationInfo result;
106      jmp_buf *bailPtr;
107  } CompilerWorkOrder;
108  
109  /* Chain cell for predicted method invocation */
110  typedef struct PredictedChainingCell {
111      u4 branch;                  /* Branch to chained destination */
112  #ifdef __mips__
113      u4 delay_slot;              /* nop goes here */
114  #elif defined(ARCH_IA32)
115      u4 branch2;                 /* IA32 branch instr may be > 32 bits */
116  #endif
117      const ClassObject *clazz;   /* key for prediction */
118      const Method *method;       /* to lookup native PC from dalvik PC */
119      const ClassObject *stagedClazz;   /* possible next key for prediction */
120  } PredictedChainingCell;
121  
122  /* Work order for inline cache patching */
123  typedef struct ICPatchWorkOrder {
124      PredictedChainingCell *cellAddr;    /* Address to be patched */
125      PredictedChainingCell cellContent;  /* content of the new cell */
126      const char *classDescriptor;        /* Descriptor of the class object */
127      Object *classLoader;                /* Class loader */
128      u4 serialNumber;                    /* Serial # (for verification only) */
129  } ICPatchWorkOrder;
130  
131  /*
132   * Trace description as will appear in the translation cache.  Note
133   * flexible array at end, as these will be of variable size.  To
134   * conserve space in the translation cache, total length of JitTraceRun
135   * array must be recomputed via seqential scan if needed.
136   */
137  typedef struct {
138      const Method* method;
139      JitTraceRun trace[0];       // Variable-length trace descriptors
140  } JitTraceDescription;
141  
142  typedef enum JitMethodAttributes {
143      kIsCallee = 0,      /* Code is part of a callee (invoked by a hot trace) */
144      kIsHot,             /* Code is part of a hot trace */
145      kIsLeaf,            /* Method is leaf */
146      kIsEmpty,           /* Method is empty */
147      kIsThrowFree,       /* Method doesn't throw */
148      kIsGetter,          /* Method fits the getter pattern */
149      kIsSetter,          /* Method fits the setter pattern */
150      kCannotCompile,     /* Method cannot be compiled */
151  } JitMethodAttributes;
152  
153  #define METHOD_IS_CALLEE        (1 << kIsCallee)
154  #define METHOD_IS_HOT           (1 << kIsHot)
155  #define METHOD_IS_LEAF          (1 << kIsLeaf)
156  #define METHOD_IS_EMPTY         (1 << kIsEmpty)
157  #define METHOD_IS_THROW_FREE    (1 << kIsThrowFree)
158  #define METHOD_IS_GETTER        (1 << kIsGetter)
159  #define METHOD_IS_SETTER        (1 << kIsSetter)
160  #define METHOD_CANNOT_COMPILE   (1 << kCannotCompile)
161  
162  /* Vectors to provide optimization hints */
163  typedef enum JitOptimizationHints {
164      kJitOptNoLoop = 0,          // Disable loop formation/optimization
165  } JitOptimizationHints;
166  
167  #define JIT_OPT_NO_LOOP         (1 << kJitOptNoLoop)
168  
169  /* Customized node traversal orders for different needs */
170  typedef enum DataFlowAnalysisMode {
171      kAllNodes = 0,              // All nodes
172      kReachableNodes,            // All reachable nodes
173      kPreOrderDFSTraversal,      // Depth-First-Search / Pre-Order
174      kPostOrderDFSTraversal,     // Depth-First-Search / Post-Order
175      kPostOrderDOMTraversal,     // Dominator tree / Post-Order
176  } DataFlowAnalysisMode;
177  
178  typedef struct CompilerMethodStats {
179      const Method *method;       // Used as hash entry signature
180      int dalvikSize;             // # of bytes for dalvik bytecodes
181      int compiledDalvikSize;     // # of compiled dalvik bytecodes
182      int nativeSize;             // # of bytes for produced native code
183      int attributes;             // attribute vector
184  } CompilerMethodStats;
185  
186  struct CompilationUnit;
187  struct BasicBlock;
188  struct SSARepresentation;
189  struct GrowableList;
190  struct JitEntry;
191  struct MIR;
192  
193  bool dvmCompilerSetupCodeCache(void);
194  bool dvmCompilerArchInit(void);
195  void dvmCompilerArchDump(void);
196  bool dvmCompilerStartup(void);
197  void dvmCompilerShutdown(void);
198  void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
199  bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
200  void *dvmCheckCodeCache(void *method);
201  CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
202                                                    bool isCallee);
203  bool dvmCompilerCanIncludeThisInstruction(const Method *method,
204                                            const DecodedInstruction *insn);
205  bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
206  bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
207                       JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
208  void dvmCompilerDumpStats(void);
209  void dvmCompilerDrainQueue(void);
210  void dvmJitUnchainAll(void);
211  void dvmJitScanAllClassPointers(void (*callback)(void *ptr));
212  void dvmCompilerSortAndPrintTraceProfiles(void);
213  void dvmCompilerPerformSafePointChecks(void);
214  void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
215                            JitTranslationInfo *info);
216  void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
217  int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
218  bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
219  void dvmCompilerInsertBackwardChaining(struct CompilationUnit *cUnit);
220  void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
221  bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
222                                  struct BasicBlock *bb);
223  bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
224                                  struct BasicBlock *bb);
225  bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
226                                        struct BasicBlock *bb);
227  bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
228                                         struct BasicBlock *bb);
229  /* Clear the visited flag for each BB */
230  bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
231                                   struct BasicBlock *bb);
232  char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
233                                        const char *note);
234  char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
235                                    const struct MIR *mir);
236  char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
237                                struct SSARepresentation *ssaRep);
238  void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
239                  bool (*func)(struct CompilationUnit *, struct BasicBlock *),
240                  DataFlowAnalysisMode dfaMode,
241                  bool isIterative);
242  void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
243  bool dvmCompilerBuildLoop(struct CompilationUnit *cUnit);
244  void dvmCompilerUpdateGlobalState(void);
245  JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
246                                              const struct JitEntry *desc);
247  extern "C" void *dvmCompilerGetInterpretTemplate();
248  JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
249  u8 dvmGetRegResourceMask(int reg);
250  void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix);
251  bool dvmIsOpcodeSupportedByJit(Opcode opcode);
252  
253  #endif  // DALVIK_VM_COMPILER_H_
254