< prev index next >

src/hotspot/share/asm/assembler.hpp

Print this page




  54  * the instruction are immediately filled in based on the Label's code
  55  * offset.  If an instruction references an unbound label, that
  56  * instruction is put on a list of instructions that must be patched
  57  * (i.e., 'resolved') when the Label is bound.
  58  *
  59  * 'bind' will call the platform-specific 'patch_instruction' method to
  60  * fill in the offset field(s) for each unresolved instruction (if there
  61  * are any).  'patch_instruction' lives in one of the
  62  * cpu/<arch>/vm/assembler_<arch>* files.
  63  *
  64  * Instead of using a linked list of unresolved instructions, a Label has
  65  * an array of unresolved instruction code offsets.  _patch_index
  66  * contains the total number of forward references.  If the Label's array
  67  * overflows (i.e., _patch_index grows larger than the array size), a
  68  * GrowableArray is allocated to hold the remaining offsets.  (The cache
  69  * size is 4 for now, which handles over 99.5% of the cases)
  70  *
  71  * Labels may only be used within a single CodeSection.  If you need
  72  * to create references between code sections, use explicit relocations.
  73  */
  74 class Label VALUE_OBJ_CLASS_SPEC {
  75  private:
  76   enum { PatchCacheSize = 4 };
  77 
  78   // _loc encodes both the binding state (via its sign)
  79   // and the binding locator (via its value) of a label.
  80   //
  81   // _loc >= 0   bound label, loc() encodes the target (jump) position
  82   // _loc == -1  unbound label
  83   int _loc;
  84 
  85   // References to instructions that jump to this unresolved label.
  86   // These instructions need to be patched when the label is bound
  87   // using the platform-specific patchInstruction() method.
  88   //
  89   // To avoid having to allocate from the C-heap each time, we provide
  90   // a local cache and use the overflow only if we exceed the local cache
  91   int _patches[PatchCacheSize];
  92   int _patch_index;
  93   GrowableArray<int>* _patch_overflow;
  94 


 154     _patch_index = 0;
 155     _patch_overflow = NULL;
 156     _is_near = false;
 157   }
 158 
 159   Label() {
 160     init();
 161   }
 162 };
 163 
 164 // A NearLabel must be bound to a location near its users. Users can
 165 // optimize on this information, e.g. generate short branches.
 166 class NearLabel : public Label {
 167  public:
 168   NearLabel() : Label() { _is_near = true; }
 169 };
 170 
 171 // A union type for code which has to assemble both constant and
 172 // non-constant operands, when the distinction cannot be made
 173 // statically.
 174 class RegisterOrConstant VALUE_OBJ_CLASS_SPEC {
 175  private:
 176   Register _r;
 177   intptr_t _c;
 178 
 179  public:
 180   RegisterOrConstant(): _r(noreg), _c(0) {}
 181   RegisterOrConstant(Register r): _r(r), _c(0) {}
 182   RegisterOrConstant(intptr_t c): _r(noreg), _c(c) {}
 183 
 184   Register as_register() const { assert(is_register(),""); return _r; }
 185   intptr_t as_constant() const { assert(is_constant(),""); return _c; }
 186 
 187   Register register_or_noreg() const { return _r; }
 188   intptr_t constant_or_zero() const  { return _c; }
 189 
 190   bool is_register() const { return _r != noreg; }
 191   bool is_constant() const { return _r == noreg; }
 192 };
 193 
 194 // The Abstract Assembler: Pure assembler doing NO optimizations on the




  54  * the instruction are immediately filled in based on the Label's code
  55  * offset.  If an instruction references an unbound label, that
  56  * instruction is put on a list of instructions that must be patched
  57  * (i.e., 'resolved') when the Label is bound.
  58  *
  59  * 'bind' will call the platform-specific 'patch_instruction' method to
  60  * fill in the offset field(s) for each unresolved instruction (if there
  61  * are any).  'patch_instruction' lives in one of the
  62  * cpu/<arch>/vm/assembler_<arch>* files.
  63  *
  64  * Instead of using a linked list of unresolved instructions, a Label has
  65  * an array of unresolved instruction code offsets.  _patch_index
  66  * contains the total number of forward references.  If the Label's array
  67  * overflows (i.e., _patch_index grows larger than the array size), a
  68  * GrowableArray is allocated to hold the remaining offsets.  (The cache
  69  * size is 4 for now, which handles over 99.5% of the cases)
  70  *
  71  * Labels may only be used within a single CodeSection.  If you need
  72  * to create references between code sections, use explicit relocations.
  73  */
  74 class Label {
  75  private:
  76   enum { PatchCacheSize = 4 };
  77 
  78   // _loc encodes both the binding state (via its sign)
  79   // and the binding locator (via its value) of a label.
  80   //
  81   // _loc >= 0   bound label, loc() encodes the target (jump) position
  82   // _loc == -1  unbound label
  83   int _loc;
  84 
  85   // References to instructions that jump to this unresolved label.
  86   // These instructions need to be patched when the label is bound
  87   // using the platform-specific patchInstruction() method.
  88   //
  89   // To avoid having to allocate from the C-heap each time, we provide
  90   // a local cache and use the overflow only if we exceed the local cache
  91   int _patches[PatchCacheSize];
  92   int _patch_index;
  93   GrowableArray<int>* _patch_overflow;
  94 


 154     _patch_index = 0;
 155     _patch_overflow = NULL;
 156     _is_near = false;
 157   }
 158 
 159   Label() {
 160     init();
 161   }
 162 };
 163 
 164 // A NearLabel must be bound to a location near its users. Users can
 165 // optimize on this information, e.g. generate short branches.
 166 class NearLabel : public Label {
 167  public:
 168   NearLabel() : Label() { _is_near = true; }
 169 };
 170 
 171 // A union type for code which has to assemble both constant and
 172 // non-constant operands, when the distinction cannot be made
 173 // statically.
 174 class RegisterOrConstant {
 175  private:
 176   Register _r;
 177   intptr_t _c;
 178 
 179  public:
 180   RegisterOrConstant(): _r(noreg), _c(0) {}
 181   RegisterOrConstant(Register r): _r(r), _c(0) {}
 182   RegisterOrConstant(intptr_t c): _r(noreg), _c(c) {}
 183 
 184   Register as_register() const { assert(is_register(),""); return _r; }
 185   intptr_t as_constant() const { assert(is_constant(),""); return _c; }
 186 
 187   Register register_or_noreg() const { return _r; }
 188   intptr_t constant_or_zero() const  { return _c; }
 189 
 190   bool is_register() const { return _r != noreg; }
 191   bool is_constant() const { return _r == noreg; }
 192 };
 193 
 194 // The Abstract Assembler: Pure assembler doing NO optimizations on the


< prev index next >