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; }
|