comparison src/share/vm/asm/assembler.hpp @ 7206:d2f8c38e543d

Merge
author roland
date Fri, 07 Dec 2012 01:09:03 -0800
parents f0c2369fda5a
children 18d56ca3e901
comparison
equal deleted inserted replaced
7191:816b7e5bf2ed 7206:d2f8c38e543d
23 */ 23 */
24 24
25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP 25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP
26 #define SHARE_VM_ASM_ASSEMBLER_HPP 26 #define SHARE_VM_ASM_ASSEMBLER_HPP
27 27
28 #include "asm/codeBuffer.hpp"
28 #include "code/oopRecorder.hpp" 29 #include "code/oopRecorder.hpp"
29 #include "code/relocInfo.hpp" 30 #include "code/relocInfo.hpp"
30 #include "memory/allocation.hpp" 31 #include "memory/allocation.hpp"
31 #include "utilities/debug.hpp" 32 #include "utilities/debug.hpp"
32 #include "utilities/growableArray.hpp" 33 #include "utilities/growableArray.hpp"
33 #include "utilities/top.hpp" 34 #include "utilities/top.hpp"
35
34 #ifdef TARGET_ARCH_x86 36 #ifdef TARGET_ARCH_x86
35 # include "register_x86.hpp" 37 # include "register_x86.hpp"
36 # include "vm_version_x86.hpp" 38 # include "vm_version_x86.hpp"
37 #endif 39 #endif
38 #ifdef TARGET_ARCH_sparc 40 #ifdef TARGET_ARCH_sparc
52 # include "vm_version_ppc.hpp" 54 # include "vm_version_ppc.hpp"
53 #endif 55 #endif
54 56
55 // This file contains platform-independent assembler declarations. 57 // This file contains platform-independent assembler declarations.
56 58
57 class CodeBuffer;
58 class MacroAssembler; 59 class MacroAssembler;
59 class AbstractAssembler; 60 class AbstractAssembler;
60 class Label; 61 class Label;
61 62
62 /** 63 /**
120 void bind_loc(int loc) { 121 void bind_loc(int loc) {
121 assert(loc >= 0, "illegal locator"); 122 assert(loc >= 0, "illegal locator");
122 assert(_loc == -1, "already bound"); 123 assert(_loc == -1, "already bound");
123 _loc = loc; 124 _loc = loc;
124 } 125 }
125 void bind_loc(int pos, int sect); // = bind_loc(locator(pos, sect)) 126 void bind_loc(int pos, int sect) { bind_loc(CodeBuffer::locator(pos, sect)); }
126 127
127 #ifndef PRODUCT 128 #ifndef PRODUCT
128 // Iterates over all unresolved instructions for printing 129 // Iterates over all unresolved instructions for printing
129 void print_instructions(MacroAssembler* masm) const; 130 void print_instructions(MacroAssembler* masm) const;
130 #endif // PRODUCT 131 #endif // PRODUCT
135 */ 136 */
136 int loc() const { 137 int loc() const {
137 assert(_loc >= 0, "unbound label"); 138 assert(_loc >= 0, "unbound label");
138 return _loc; 139 return _loc;
139 } 140 }
140 int loc_pos() const; // == locator_pos(loc()) 141 int loc_pos() const { return CodeBuffer::locator_pos(loc()); }
141 int loc_sect() const; // == locator_sect(loc()) 142 int loc_sect() const { return CodeBuffer::locator_sect(loc()); }
142 143
143 bool is_bound() const { return _loc >= 0; } 144 bool is_bound() const { return _loc >= 0; }
144 bool is_unbound() const { return _loc == -1 && _patch_index > 0; } 145 bool is_unbound() const { return _loc == -1 && _patch_index > 0; }
145 bool is_unused() const { return _loc == -1 && _patch_index == 0; } 146 bool is_unused() const { return _loc == -1 && _patch_index == 0; }
146 147
199 class AbstractAssembler : public ResourceObj { 200 class AbstractAssembler : public ResourceObj {
200 friend class Label; 201 friend class Label;
201 202
202 protected: 203 protected:
203 CodeSection* _code_section; // section within the code buffer 204 CodeSection* _code_section; // section within the code buffer
204 address _code_begin; // first byte of code buffer
205 address _code_limit; // first byte after code buffer
206 address _code_pos; // current code generation position
207 OopRecorder* _oop_recorder; // support for relocInfo::oop_type 205 OopRecorder* _oop_recorder; // support for relocInfo::oop_type
208 206
209 // Code emission & accessing 207 // Code emission & accessing
210 address addr_at(int pos) const { return _code_begin + pos; } 208 address addr_at(int pos) const { return code_section()->start() + pos; }
209
211 210
212 // This routine is called with a label is used for an address. 211 // This routine is called with a label is used for an address.
213 // Labels and displacements truck in offsets, but target must return a PC. 212 // Labels and displacements truck in offsets, but target must return a PC.
214 address target(Label& L); // return _code_section->target(L) 213 address target(Label& L) { return code_section()->target(L, pc()); }
215 214
216 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } 215 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; }
217 bool isByte(int x) const { return 0 <= x && x < 0x100; } 216 bool isByte(int x) const { return 0 <= x && x < 0x100; }
218 bool isShiftCount(int x) const { return 0 <= x && x < 32; } 217 bool isShiftCount(int x) const { return 0 <= x && x < 32; }
219 218
220 void emit_byte(int x); // emit a single byte 219 void emit_int8( int8_t x) { code_section()->emit_int8( x); }
221 void emit_word(int x); // emit a 16-bit word (not a wordSize word!) 220 void emit_int16( int16_t x) { code_section()->emit_int16( x); }
222 void emit_long(jint x); // emit a 32-bit word (not a longSize word!) 221 void emit_int32( int32_t x) { code_section()->emit_int32( x); }
223 void emit_address(address x); // emit an address (not a longSize word!) 222 void emit_int64( int64_t x) { code_section()->emit_int64( x); }
223
224 void emit_float( jfloat x) { code_section()->emit_float( x); }
225 void emit_double( jdouble x) { code_section()->emit_double( x); }
226 void emit_address(address x) { code_section()->emit_address(x); }
227
228 void emit_byte(int x) { emit_int8 (x); } // deprecated
229 void emit_word(int x) { emit_int16(x); } // deprecated
230 void emit_long(jint x) { emit_int32(x); } // deprecated
224 231
225 // Instruction boundaries (required when emitting relocatable values). 232 // Instruction boundaries (required when emitting relocatable values).
226 class InstructionMark: public StackObj { 233 class InstructionMark: public StackObj {
227 private: 234 private:
228 AbstractAssembler* _assm; 235 AbstractAssembler* _assm;
235 ~InstructionMark() { 242 ~InstructionMark() {
236 _assm->clear_inst_mark(); 243 _assm->clear_inst_mark();
237 } 244 }
238 }; 245 };
239 friend class InstructionMark; 246 friend class InstructionMark;
240 #ifdef ASSERT 247 #ifdef ASSERT
241 // Make it return true on platforms which need to verify 248 // Make it return true on platforms which need to verify
242 // instruction boundaries for some operations. 249 // instruction boundaries for some operations.
243 inline static bool pd_check_instruction_mark(); 250 static bool pd_check_instruction_mark();
244 251
245 // Add delta to short branch distance to verify that it still fit into imm8. 252 // Add delta to short branch distance to verify that it still fit into imm8.
246 int _short_branch_delta; 253 int _short_branch_delta;
247 254
248 int short_branch_delta() const { return _short_branch_delta; } 255 int short_branch_delta() const { return _short_branch_delta; }
260 } 267 }
261 ~ShortBranchVerifier() { 268 ~ShortBranchVerifier() {
262 _assm->clear_short_branch_delta(); 269 _assm->clear_short_branch_delta();
263 } 270 }
264 }; 271 };
265 #else 272 #else
266 // Dummy in product. 273 // Dummy in product.
267 class ShortBranchVerifier: public StackObj { 274 class ShortBranchVerifier: public StackObj {
268 public: 275 public:
269 ShortBranchVerifier(AbstractAssembler* assm) {} 276 ShortBranchVerifier(AbstractAssembler* assm) {}
270 }; 277 };
271 #endif 278 #endif
272 279
273 // Label functions 280 // Label functions
274 void print(Label& L); 281 void print(Label& L);
275 282
276 public: 283 public:
277 284
278 // Creation 285 // Creation
279 AbstractAssembler(CodeBuffer* code); 286 AbstractAssembler(CodeBuffer* code);
280
281 // save end pointer back to code buf.
282 void sync();
283 287
284 // ensure buf contains all code (call this before using/copying the code) 288 // ensure buf contains all code (call this before using/copying the code)
285 void flush(); 289 void flush();
286 290
287 // min and max values for signed immediate ranges 291 // min and max values for signed immediate ranges
306 static bool is_simm16(intptr_t x) { return is_simm(x, 16); } 310 static bool is_simm16(intptr_t x) { return is_simm(x, 16); }
307 static bool is_simm26(intptr_t x) { return is_simm(x, 26); } 311 static bool is_simm26(intptr_t x) { return is_simm(x, 26); }
308 static bool is_simm32(intptr_t x) { return is_simm(x, 32); } 312 static bool is_simm32(intptr_t x) { return is_simm(x, 32); }
309 313
310 // Accessors 314 // Accessors
311 CodeBuffer* code() const; // _code_section->outer()
312 CodeSection* code_section() const { return _code_section; } 315 CodeSection* code_section() const { return _code_section; }
313 int sect() const; // return _code_section->index() 316 CodeBuffer* code() const { return code_section()->outer(); }
314 address pc() const { return _code_pos; } 317 int sect() const { return code_section()->index(); }
315 int offset() const { return _code_pos - _code_begin; } 318 address pc() const { return code_section()->end(); }
316 int locator() const; // CodeBuffer::locator(offset(), sect()) 319 int offset() const { return code_section()->size(); }
320 int locator() const { return CodeBuffer::locator(offset(), sect()); }
321
317 OopRecorder* oop_recorder() const { return _oop_recorder; } 322 OopRecorder* oop_recorder() const { return _oop_recorder; }
318 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } 323 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; }
319 324
320 address inst_mark() const; 325 address inst_mark() const { return code_section()->mark(); }
321 void set_inst_mark(); 326 void set_inst_mark() { code_section()->set_mark(); }
322 void clear_inst_mark(); 327 void clear_inst_mark() { code_section()->clear_mark(); }
323 328
324 // Constants in code 329 // Constants in code
325 void a_byte(int x); 330 void a_byte(int x);
326 void a_long(jint x); 331 void a_long(jint x);
327 void relocate(RelocationHolder const& rspec, int format = 0); 332 void relocate(RelocationHolder const& rspec, int format = 0) {
333 assert(!pd_check_instruction_mark()
334 || inst_mark() == NULL || inst_mark() == code_section()->end(),
335 "call relocate() between instructions");
336 code_section()->relocate(code_section()->end(), rspec, format);
337 }
328 void relocate( relocInfo::relocType rtype, int format = 0) { 338 void relocate( relocInfo::relocType rtype, int format = 0) {
329 if (rtype != relocInfo::none) 339 code_section()->relocate(code_section()->end(), rtype, format);
330 relocate(Relocation::spec_simple(rtype), format);
331 } 340 }
332 341
333 static int code_fill_byte(); // used to pad out odd-sized code buffers 342 static int code_fill_byte(); // used to pad out odd-sized code buffers
334 343
335 // Associate a comment with the current offset. It will be printed 344 // Associate a comment with the current offset. It will be printed
346 // Inform assembler when generating stub code and relocation info 355 // Inform assembler when generating stub code and relocation info
347 address start_a_stub(int required_space); 356 address start_a_stub(int required_space);
348 void end_a_stub(); 357 void end_a_stub();
349 // Ditto for constants. 358 // Ditto for constants.
350 address start_a_const(int required_space, int required_align = sizeof(double)); 359 address start_a_const(int required_space, int required_align = sizeof(double));
351 void end_a_const(); 360 void end_a_const(CodeSection* cs); // Pass the codesection to continue in (insts or stubs?).
352 361
353 // constants support 362 // constants support
363 //
364 // We must remember the code section (insts or stubs) in c1
365 // so we can reset to the proper section in end_a_const().
354 address long_constant(jlong c) { 366 address long_constant(jlong c) {
367 CodeSection* c1 = _code_section;
355 address ptr = start_a_const(sizeof(c), sizeof(c)); 368 address ptr = start_a_const(sizeof(c), sizeof(c));
356 if (ptr != NULL) { 369 if (ptr != NULL) {
357 *(jlong*)ptr = c; 370 emit_int64(c);
358 _code_pos = ptr + sizeof(c); 371 end_a_const(c1);
359 end_a_const();
360 } 372 }
361 return ptr; 373 return ptr;
362 } 374 }
363 address double_constant(jdouble c) { 375 address double_constant(jdouble c) {
376 CodeSection* c1 = _code_section;
364 address ptr = start_a_const(sizeof(c), sizeof(c)); 377 address ptr = start_a_const(sizeof(c), sizeof(c));
365 if (ptr != NULL) { 378 if (ptr != NULL) {
366 *(jdouble*)ptr = c; 379 emit_double(c);
367 _code_pos = ptr + sizeof(c); 380 end_a_const(c1);
368 end_a_const();
369 } 381 }
370 return ptr; 382 return ptr;
371 } 383 }
372 address float_constant(jfloat c) { 384 address float_constant(jfloat c) {
385 CodeSection* c1 = _code_section;
373 address ptr = start_a_const(sizeof(c), sizeof(c)); 386 address ptr = start_a_const(sizeof(c), sizeof(c));
374 if (ptr != NULL) { 387 if (ptr != NULL) {
375 *(jfloat*)ptr = c; 388 emit_float(c);
376 _code_pos = ptr + sizeof(c); 389 end_a_const(c1);
377 end_a_const();
378 } 390 }
379 return ptr; 391 return ptr;
380 } 392 }
381 address address_constant(address c) { 393 address address_constant(address c) {
394 CodeSection* c1 = _code_section;
382 address ptr = start_a_const(sizeof(c), sizeof(c)); 395 address ptr = start_a_const(sizeof(c), sizeof(c));
383 if (ptr != NULL) { 396 if (ptr != NULL) {
384 *(address*)ptr = c; 397 emit_address(c);
385 _code_pos = ptr + sizeof(c); 398 end_a_const(c1);
386 end_a_const();
387 } 399 }
388 return ptr; 400 return ptr;
389 } 401 }
390 address address_constant(address c, RelocationHolder const& rspec) { 402 address address_constant(address c, RelocationHolder const& rspec) {
403 CodeSection* c1 = _code_section;
391 address ptr = start_a_const(sizeof(c), sizeof(c)); 404 address ptr = start_a_const(sizeof(c), sizeof(c));
392 if (ptr != NULL) { 405 if (ptr != NULL) {
393 relocate(rspec); 406 relocate(rspec);
394 *(address*)ptr = c; 407 emit_address(c);
395 _code_pos = ptr + sizeof(c); 408 end_a_const(c1);
396 end_a_const();
397 } 409 }
398 return ptr; 410 return ptr;
399 } 411 }
400 412
401 // Bootstrapping aid to cope with delayed determination of constants. 413 // Bootstrapping aid to cope with delayed determination of constants.