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
|