< prev index next >

src/share/vm/asm/assembler.hpp

Print this page
rev 12485 : 8173465: Introduce NearLabel for branches known to be short.


  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 
  95   Label(const Label&) { ShouldNotReachHere(); }




  96 
  97  public:
  98 
  99   /**
 100    * After binding, be sure 'patch_instructions' is called later to link
 101    */
 102   void bind_loc(int loc) {
 103     assert(loc >= 0, "illegal locator");
 104     assert(_loc == -1, "already bound");
 105     _loc = loc;
 106   }
 107   void bind_loc(int pos, int sect) { bind_loc(CodeBuffer::locator(pos, sect)); }
 108 
 109 #ifndef PRODUCT
 110   // Iterates over all unresolved instructions for printing
 111   void print_instructions(MacroAssembler* masm) const;
 112 #endif // PRODUCT
 113 
 114   /**
 115    * Returns the position of the the Label in the code buffer
 116    * The position is a 'locator', which encodes both offset and section.
 117    */
 118   int loc() const {
 119     assert(_loc >= 0, "unbound label");
 120     return _loc;
 121   }
 122   int loc_pos()  const { return CodeBuffer::locator_pos(loc()); }
 123   int loc_sect() const { return CodeBuffer::locator_sect(loc()); }
 124 
 125   bool is_bound() const    { return _loc >=  0; }
 126   bool is_unbound() const  { return _loc == -1 && _patch_index > 0; }
 127   bool is_unused() const   { return _loc == -1 && _patch_index == 0; }
 128 




 129   /**
 130    * Adds a reference to an unresolved displacement instruction to
 131    * this unbound label
 132    *
 133    * @param cb         the code buffer being patched
 134    * @param branch_loc the locator of the branch instruction in the code buffer
 135    */
 136   void add_patch_at(CodeBuffer* cb, int branch_loc);
 137 
 138   /**
 139    * Iterate over the list of patches, resolving the instructions
 140    * Call patch_instruction on each 'branch_loc' value
 141    */
 142   void patch_instructions(MacroAssembler* masm);
 143 
 144   void init() {
 145     _loc = -1;
 146     _patch_index = 0;
 147     _patch_overflow = NULL;

 148   }
 149 
 150   Label() {
 151     init();
 152   }







 153 };
 154 
 155 // A union type for code which has to assemble both constant and
 156 // non-constant operands, when the distinction cannot be made
 157 // statically.
 158 class RegisterOrConstant VALUE_OBJ_CLASS_SPEC {
 159  private:
 160   Register _r;
 161   intptr_t _c;
 162 
 163  public:
 164   RegisterOrConstant(): _r(noreg), _c(0) {}
 165   RegisterOrConstant(Register r): _r(r), _c(0) {}
 166   RegisterOrConstant(intptr_t c): _r(noreg), _c(c) {}
 167 
 168   Register as_register() const { assert(is_register(),""); return _r; }
 169   intptr_t as_constant() const { assert(is_constant(),""); return _c; }
 170 
 171   Register register_or_noreg() const { return _r; }
 172   intptr_t constant_or_zero() const  { return _c; }




  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 
  95   Label(const Label&) { ShouldNotReachHere(); }
  96  protected:
  97 
  98   // The label will be bound to a location near its users.
  99   unsigned int _is_near:1;
 100 
 101  public:
 102 
 103   /**
 104    * After binding, be sure 'patch_instructions' is called later to link
 105    */
 106   void bind_loc(int loc) {
 107     assert(loc >= 0, "illegal locator");
 108     assert(_loc == -1, "already bound");
 109     _loc = loc;
 110   }
 111   void bind_loc(int pos, int sect) { bind_loc(CodeBuffer::locator(pos, sect)); }
 112 
 113 #ifndef PRODUCT
 114   // Iterates over all unresolved instructions for printing
 115   void print_instructions(MacroAssembler* masm) const;
 116 #endif // PRODUCT
 117 
 118   /**
 119    * Returns the position of the the Label in the code buffer
 120    * The position is a 'locator', which encodes both offset and section.
 121    */
 122   int loc() const {
 123     assert(_loc >= 0, "unbound label");
 124     return _loc;
 125   }
 126   int loc_pos()  const { return CodeBuffer::locator_pos(loc()); }
 127   int loc_sect() const { return CodeBuffer::locator_sect(loc()); }
 128 
 129   bool is_bound() const    { return _loc >=  0; }
 130   bool is_unbound() const  { return _loc == -1 && _patch_index > 0; }
 131   bool is_unused() const   { return _loc == -1 && _patch_index == 0; }
 132 
 133   // The label will be bound to a location near its users. Users can
 134   // optimize on this information, e.g. generate short branches.
 135   bool is_near()           { return _is_near; }
 136 
 137   /**
 138    * Adds a reference to an unresolved displacement instruction to
 139    * this unbound label
 140    *
 141    * @param cb         the code buffer being patched
 142    * @param branch_loc the locator of the branch instruction in the code buffer
 143    */
 144   void add_patch_at(CodeBuffer* cb, int branch_loc);
 145 
 146   /**
 147    * Iterate over the list of patches, resolving the instructions
 148    * Call patch_instruction on each 'branch_loc' value
 149    */
 150   void patch_instructions(MacroAssembler* masm);
 151 
 152   void init() {
 153     _loc = -1;
 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; }


< prev index next >