Fri, 30 Nov 2012 11:44:05 -0800
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
Reviewed-by: twisti, kvn
Contributed-by: Bharadwaj Yadavalli <bharadwaj.yadavalli@oracle.com>
1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Tue Nov 27 17:41:38 2012 -0800 1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Nov 30 11:44:05 2012 -0800 1.3 @@ -1154,7 +1154,7 @@ 1.4 assert(entry != NULL, "call most probably wrong"); 1.5 InstructionMark im(this); 1.6 emit_byte(0xE8); 1.7 - intptr_t disp = entry - (_code_pos + sizeof(int32_t)); 1.8 + intptr_t disp = entry - (pc() + sizeof(int32_t)); 1.9 assert(is_simm32(disp), "must be 32bit offset (call2)"); 1.10 // Technically, should use call32_operand, but this format is 1.11 // implied by the fact that we're emitting a call instruction. 1.12 @@ -1417,7 +1417,7 @@ 1.13 1.14 const int short_size = 2; 1.15 const int long_size = 6; 1.16 - intptr_t offs = (intptr_t)dst - (intptr_t)_code_pos; 1.17 + intptr_t offs = (intptr_t)dst - (intptr_t)pc(); 1.18 if (maybe_short && is8bit(offs - short_size)) { 1.19 // 0111 tttn #8-bit disp 1.20 emit_byte(0x70 | cc); 1.21 @@ -1447,14 +1447,14 @@ 1.22 const int short_size = 2; 1.23 address entry = target(L); 1.24 #ifdef ASSERT 1.25 - intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); 1.26 + intptr_t dist = (intptr_t)entry - ((intptr_t)pc() + short_size); 1.27 intptr_t delta = short_branch_delta(); 1.28 if (delta != 0) { 1.29 dist += (dist < 0 ? (-delta) :delta); 1.30 } 1.31 assert(is8bit(dist), "Dispacement too large for a short jmp"); 1.32 #endif 1.33 - intptr_t offs = (intptr_t)entry - (intptr_t)_code_pos; 1.34 + intptr_t offs = (intptr_t)entry - (intptr_t)pc(); 1.35 // 0111 tttn #8-bit disp 1.36 emit_byte(0x70 | cc); 1.37 emit_byte((offs - short_size) & 0xFF); 1.38 @@ -1480,7 +1480,7 @@ 1.39 InstructionMark im(this); 1.40 const int short_size = 2; 1.41 const int long_size = 5; 1.42 - intptr_t offs = entry - _code_pos; 1.43 + intptr_t offs = entry - pc(); 1.44 if (maybe_short && is8bit(offs - short_size)) { 1.45 emit_byte(0xEB); 1.46 emit_byte((offs - short_size) & 0xFF); 1.47 @@ -1510,7 +1510,7 @@ 1.48 InstructionMark im(this); 1.49 emit_byte(0xE9); 1.50 assert(dest != NULL, "must have a target"); 1.51 - intptr_t disp = dest - (_code_pos + sizeof(int32_t)); 1.52 + intptr_t disp = dest - (pc() + sizeof(int32_t)); 1.53 assert(is_simm32(disp), "must be 32bit offset (jmp)"); 1.54 emit_data(disp, rspec.reloc(), call32_operand); 1.55 } 1.56 @@ -1521,14 +1521,14 @@ 1.57 address entry = target(L); 1.58 assert(entry != NULL, "jmp most probably wrong"); 1.59 #ifdef ASSERT 1.60 - intptr_t dist = (intptr_t)entry - ((intptr_t)_code_pos + short_size); 1.61 + intptr_t dist = (intptr_t)entry - ((intptr_t)pc() + short_size); 1.62 intptr_t delta = short_branch_delta(); 1.63 if (delta != 0) { 1.64 dist += (dist < 0 ? (-delta) :delta); 1.65 } 1.66 assert(is8bit(dist), "Dispacement too large for a short jmp"); 1.67 #endif 1.68 - intptr_t offs = entry - _code_pos; 1.69 + intptr_t offs = entry - pc(); 1.70 emit_byte(0xEB); 1.71 emit_byte((offs - short_size) & 0xFF); 1.72 } else { 1.73 @@ -4361,7 +4361,7 @@ 1.74 disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int)); 1.75 if (!is_simm32(disp)) return false; 1.76 1.77 - disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int)); 1.78 + disp = (int64_t)adr._target - ((int64_t)pc() + sizeof(int)); 1.79 1.80 // Because rip relative is a disp + address_of_next_instruction and we 1.81 // don't know the value of address_of_next_instruction we apply a fudge factor 1.82 @@ -4392,7 +4392,7 @@ 1.83 relocInfo::relocType rtype, 1.84 int format) { 1.85 if (rtype == relocInfo::none) { 1.86 - emit_long64(data); 1.87 + emit_int64(data); 1.88 } else { 1.89 emit_data64(data, Relocation::spec_simple(rtype), format); 1.90 } 1.91 @@ -4410,7 +4410,7 @@ 1.92 #ifdef ASSERT 1.93 check_relocation(rspec, format); 1.94 #endif 1.95 - emit_long64(data); 1.96 + emit_int64(data); 1.97 } 1.98 1.99 int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { 1.100 @@ -4943,7 +4943,7 @@ 1.101 InstructionMark im(this); 1.102 int encode = prefixq_and_encode(dst->encoding()); 1.103 emit_byte(0xB8 | encode); 1.104 - emit_long64(imm64); 1.105 + emit_int64(imm64); 1.106 } 1.107 1.108 void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) { 1.109 @@ -7891,7 +7891,7 @@ 1.110 relocate(dst.reloc()); 1.111 const int short_size = 2; 1.112 const int long_size = 6; 1.113 - int offs = (intptr_t)dst.target() - ((intptr_t)_code_pos); 1.114 + int offs = (intptr_t)dst.target() - ((intptr_t)pc()); 1.115 if (dst.reloc() == relocInfo::none && is8bit(offs - short_size)) { 1.116 // 0111 tttn #8-bit disp 1.117 emit_byte(0x70 | cc);
2.1 --- a/src/cpu/x86/vm/assembler_x86.hpp Tue Nov 27 17:41:38 2012 -0800 2.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Nov 30 11:44:05 2012 -0800 2.3 @@ -706,8 +706,6 @@ 2.4 void check_relocation(RelocationHolder const& rspec, int format); 2.5 #endif 2.6 2.7 - inline void emit_long64(jlong x); 2.8 - 2.9 void emit_data(jint data, relocInfo::relocType rtype, int format); 2.10 void emit_data(jint data, RelocationHolder const& rspec, int format); 2.11 void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
3.1 --- a/src/cpu/x86/vm/assembler_x86.inline.hpp Tue Nov 27 17:41:38 2012 -0800 3.2 +++ b/src/cpu/x86/vm/assembler_x86.inline.hpp Fri Nov 30 11:44:05 2012 -0800 3.3 @@ -87,12 +87,6 @@ 3.4 3.5 inline void Assembler::prefix(Address adr, XMMRegister reg) {} 3.6 inline void Assembler::prefixq(Address adr, XMMRegister reg) {} 3.7 -#else 3.8 -inline void Assembler::emit_long64(jlong x) { 3.9 - *(jlong*) _code_pos = x; 3.10 - _code_pos += sizeof(jlong); 3.11 - code_section()->set_end(_code_pos); 3.12 -} 3.13 #endif // _LP64 3.14 3.15 #endif // CPU_X86_VM_ASSEMBLER_X86_INLINE_HPP
4.1 --- a/src/share/vm/asm/assembler.cpp Tue Nov 27 17:41:38 2012 -0800 4.2 +++ b/src/share/vm/asm/assembler.cpp Fri Nov 30 11:44:05 2012 -0800 4.3 @@ -56,16 +56,13 @@ 4.4 if (code == NULL) return; 4.5 CodeSection* cs = code->insts(); 4.6 cs->clear_mark(); // new assembler kills old mark 4.7 - _code_section = cs; 4.8 - _code_begin = cs->start(); 4.9 - _code_limit = cs->limit(); 4.10 - _code_pos = cs->end(); 4.11 - _oop_recorder= code->oop_recorder(); 4.12 - DEBUG_ONLY( _short_branch_delta = 0; ) 4.13 - if (_code_begin == NULL) { 4.14 + if (cs->start() == NULL) { 4.15 vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s", 4.16 code->name())); 4.17 } 4.18 + _code_section = cs; 4.19 + _oop_recorder= code->oop_recorder(); 4.20 + DEBUG_ONLY( _short_branch_delta = 0; ) 4.21 } 4.22 4.23 void AbstractAssembler::set_code_section(CodeSection* cs) { 4.24 @@ -73,9 +70,6 @@ 4.25 assert(cs->is_allocated(), "need to pre-allocate this section"); 4.26 cs->clear_mark(); // new assembly into this section kills old mark 4.27 _code_section = cs; 4.28 - _code_begin = cs->start(); 4.29 - _code_limit = cs->limit(); 4.30 - _code_pos = cs->end(); 4.31 } 4.32 4.33 // Inform CodeBuffer that incoming code and relocation will be for stubs 4.34 @@ -83,7 +77,6 @@ 4.35 CodeBuffer* cb = code(); 4.36 CodeSection* cs = cb->stubs(); 4.37 assert(_code_section == cb->insts(), "not in insts?"); 4.38 - sync(); 4.39 if (cs->maybe_expand_to_ensure_remaining(required_space) 4.40 && cb->blob() == NULL) { 4.41 return NULL; 4.42 @@ -96,7 +89,6 @@ 4.43 // Should not be called if start_a_stub() returned NULL 4.44 void AbstractAssembler::end_a_stub() { 4.45 assert(_code_section == code()->stubs(), "not in stubs?"); 4.46 - sync(); 4.47 set_code_section(code()->insts()); 4.48 } 4.49 4.50 @@ -105,7 +97,6 @@ 4.51 CodeBuffer* cb = code(); 4.52 CodeSection* cs = cb->consts(); 4.53 assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?"); 4.54 - sync(); 4.55 address end = cs->end(); 4.56 int pad = -(intptr_t)end & (required_align-1); 4.57 if (cs->maybe_expand_to_ensure_remaining(pad + required_space)) { 4.58 @@ -124,12 +115,10 @@ 4.59 // in section cs (insts or stubs). 4.60 void AbstractAssembler::end_a_const(CodeSection* cs) { 4.61 assert(_code_section == code()->consts(), "not in consts?"); 4.62 - sync(); 4.63 set_code_section(cs); 4.64 } 4.65 4.66 void AbstractAssembler::flush() { 4.67 - sync(); 4.68 ICache::invalidate_range(addr_at(0), offset()); 4.69 } 4.70
5.1 --- a/src/share/vm/asm/assembler.hpp Tue Nov 27 17:41:38 2012 -0800 5.2 +++ b/src/share/vm/asm/assembler.hpp Fri Nov 30 11:44:05 2012 -0800 5.3 @@ -201,13 +201,10 @@ 5.4 5.5 protected: 5.6 CodeSection* _code_section; // section within the code buffer 5.7 - address _code_begin; // first byte of code buffer 5.8 - address _code_limit; // first byte after code buffer 5.9 - address _code_pos; // current code generation position 5.10 OopRecorder* _oop_recorder; // support for relocInfo::oop_type 5.11 5.12 // Code emission & accessing 5.13 - address addr_at(int pos) const { return _code_begin + pos; } 5.14 + inline address addr_at(int pos) const; 5.15 5.16 // This routine is called with a label is used for an address. 5.17 // Labels and displacements truck in offsets, but target must return a PC. 5.18 @@ -217,10 +214,18 @@ 5.19 bool isByte(int x) const { return 0 <= x && x < 0x100; } 5.20 bool isShiftCount(int x) const { return 0 <= x && x < 32; } 5.21 5.22 - void emit_byte(int x); // emit a single byte 5.23 - void emit_word(int x); // emit a 16-bit word (not a wordSize word!) 5.24 - void emit_long(jint x); // emit a 32-bit word (not a longSize word!) 5.25 - void emit_address(address x); // emit an address (not a longSize word!) 5.26 + void emit_byte(int x) { emit_int8 (x); } // deprecated 5.27 + void emit_word(int x) { emit_int16(x); } // deprecated 5.28 + void emit_long(jint x) { emit_int32(x); } // deprecated 5.29 + 5.30 + inline void emit_int8( int8_t x); 5.31 + inline void emit_int16( int16_t x); 5.32 + inline void emit_int32( int32_t x); 5.33 + inline void emit_int64( int64_t x); 5.34 + 5.35 + inline void emit_float( jfloat x); 5.36 + inline void emit_double(jdouble x); 5.37 + inline void emit_address(address x); 5.38 5.39 // Instruction boundaries (required when emitting relocatable values). 5.40 class InstructionMark: public StackObj { 5.41 @@ -278,9 +283,6 @@ 5.42 // Creation 5.43 AbstractAssembler(CodeBuffer* code); 5.44 5.45 - // save end pointer back to code buf. 5.46 - void sync(); 5.47 - 5.48 // ensure buf contains all code (call this before using/copying the code) 5.49 void flush(); 5.50 5.51 @@ -308,12 +310,13 @@ 5.52 static bool is_simm32(intptr_t x) { return is_simm(x, 32); } 5.53 5.54 // Accessors 5.55 - CodeBuffer* code() const; // _code_section->outer() 5.56 CodeSection* code_section() const { return _code_section; } 5.57 - int sect() const; // return _code_section->index() 5.58 - address pc() const { return _code_pos; } 5.59 - int offset() const { return _code_pos - _code_begin; } 5.60 - int locator() const; // CodeBuffer::locator(offset(), sect()) 5.61 + inline CodeBuffer* code() const; 5.62 + inline int sect() const; 5.63 + inline address pc() const; 5.64 + inline int offset() const; 5.65 + inline int locator() const; // CodeBuffer::locator(offset(), sect()) 5.66 + 5.67 OopRecorder* oop_recorder() const { return _oop_recorder; } 5.68 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } 5.69 5.70 @@ -358,8 +361,7 @@ 5.71 CodeSection* c1 = _code_section; 5.72 address ptr = start_a_const(sizeof(c), sizeof(c)); 5.73 if (ptr != NULL) { 5.74 - *(jlong*)ptr = c; 5.75 - _code_pos = ptr + sizeof(c); 5.76 + emit_int64(c); 5.77 end_a_const(c1); 5.78 } 5.79 return ptr; 5.80 @@ -368,8 +370,7 @@ 5.81 CodeSection* c1 = _code_section; 5.82 address ptr = start_a_const(sizeof(c), sizeof(c)); 5.83 if (ptr != NULL) { 5.84 - *(jdouble*)ptr = c; 5.85 - _code_pos = ptr + sizeof(c); 5.86 + emit_double(c); 5.87 end_a_const(c1); 5.88 } 5.89 return ptr; 5.90 @@ -378,8 +379,7 @@ 5.91 CodeSection* c1 = _code_section; 5.92 address ptr = start_a_const(sizeof(c), sizeof(c)); 5.93 if (ptr != NULL) { 5.94 - *(jfloat*)ptr = c; 5.95 - _code_pos = ptr + sizeof(c); 5.96 + emit_float(c); 5.97 end_a_const(c1); 5.98 } 5.99 return ptr; 5.100 @@ -388,8 +388,7 @@ 5.101 CodeSection* c1 = _code_section; 5.102 address ptr = start_a_const(sizeof(c), sizeof(c)); 5.103 if (ptr != NULL) { 5.104 - *(address*)ptr = c; 5.105 - _code_pos = ptr + sizeof(c); 5.106 + emit_address(c); 5.107 end_a_const(c1); 5.108 } 5.109 return ptr; 5.110 @@ -399,8 +398,7 @@ 5.111 address ptr = start_a_const(sizeof(c), sizeof(c)); 5.112 if (ptr != NULL) { 5.113 relocate(rspec); 5.114 - *(address*)ptr = c; 5.115 - _code_pos = ptr + sizeof(c); 5.116 + emit_address(c); 5.117 end_a_const(c1); 5.118 } 5.119 return ptr;
6.1 --- a/src/share/vm/asm/assembler.inline.hpp Tue Nov 27 17:41:38 2012 -0800 6.2 +++ b/src/share/vm/asm/assembler.inline.hpp Fri Nov 30 11:44:05 2012 -0800 6.3 @@ -30,49 +30,27 @@ 6.4 #include "compiler/disassembler.hpp" 6.5 #include "runtime/threadLocalStorage.hpp" 6.6 6.7 -inline void AbstractAssembler::sync() { 6.8 - CodeSection* cs = code_section(); 6.9 - guarantee(cs->start() == _code_begin, "must not shift code buffer"); 6.10 - cs->set_end(_code_pos); 6.11 +inline address AbstractAssembler::addr_at(int pos) const { 6.12 + return code_section()->start() + pos; 6.13 } 6.14 6.15 -inline void AbstractAssembler::emit_byte(int x) { 6.16 - assert(isByte(x), "not a byte"); 6.17 - *(unsigned char*)_code_pos = (unsigned char)x; 6.18 - _code_pos += sizeof(unsigned char); 6.19 - sync(); 6.20 -} 6.21 +void AbstractAssembler::emit_int8(int8_t x) { code_section()->emit_int8 (x); } 6.22 +void AbstractAssembler::emit_int16(int16_t x) { code_section()->emit_int16(x); } 6.23 +void AbstractAssembler::emit_int32(int32_t x) { code_section()->emit_int32(x); } 6.24 +void AbstractAssembler::emit_int64(int64_t x) { code_section()->emit_int64(x); } 6.25 6.26 - 6.27 -inline void AbstractAssembler::emit_word(int x) { 6.28 - *(short*)_code_pos = (short)x; 6.29 - _code_pos += sizeof(short); 6.30 - sync(); 6.31 -} 6.32 - 6.33 - 6.34 -inline void AbstractAssembler::emit_long(jint x) { 6.35 - *(jint*)_code_pos = x; 6.36 - _code_pos += sizeof(jint); 6.37 - sync(); 6.38 -} 6.39 - 6.40 -inline void AbstractAssembler::emit_address(address x) { 6.41 - *(address*)_code_pos = x; 6.42 - _code_pos += sizeof(address); 6.43 - sync(); 6.44 -} 6.45 +void AbstractAssembler::emit_float(jfloat x) { code_section()->emit_float(x); } 6.46 +void AbstractAssembler::emit_double(jdouble x) { code_section()->emit_double(x); } 6.47 +void AbstractAssembler::emit_address(address x) { code_section()->emit_address(x); } 6.48 6.49 inline address AbstractAssembler::inst_mark() const { 6.50 return code_section()->mark(); 6.51 } 6.52 6.53 - 6.54 inline void AbstractAssembler::set_inst_mark() { 6.55 code_section()->set_mark(); 6.56 } 6.57 6.58 - 6.59 inline void AbstractAssembler::clear_inst_mark() { 6.60 code_section()->clear_mark(); 6.61 } 6.62 @@ -80,9 +58,9 @@ 6.63 6.64 inline void AbstractAssembler::relocate(RelocationHolder const& rspec, int format) { 6.65 assert(!pd_check_instruction_mark() 6.66 - || inst_mark() == NULL || inst_mark() == _code_pos, 6.67 + || inst_mark() == NULL || inst_mark() == code_section()->end(), 6.68 "call relocate() between instructions"); 6.69 - code_section()->relocate(_code_pos, rspec, format); 6.70 + code_section()->relocate(code_section()->end(), rspec, format); 6.71 } 6.72 6.73 6.74 @@ -94,6 +72,14 @@ 6.75 return code_section()->index(); 6.76 } 6.77 6.78 +inline address AbstractAssembler::pc() const { 6.79 + return code_section()->end(); 6.80 +} 6.81 + 6.82 +inline int AbstractAssembler::offset() const { 6.83 + return code_section()->size(); 6.84 +} 6.85 + 6.86 inline int AbstractAssembler::locator() const { 6.87 return CodeBuffer::locator(offset(), sect()); 6.88 }
7.1 --- a/src/share/vm/asm/codeBuffer.hpp Tue Nov 27 17:41:38 2012 -0800 7.2 +++ b/src/share/vm/asm/codeBuffer.hpp Fri Nov 30 11:44:05 2012 -0800 7.3 @@ -30,8 +30,6 @@ 7.4 #include "code/relocInfo.hpp" 7.5 7.6 class CodeComments; 7.7 -class AbstractAssembler; 7.8 -class MacroAssembler; 7.9 class PhaseCFG; 7.10 class Compile; 7.11 class BufferBlob; 7.12 @@ -194,10 +192,14 @@ 7.13 } 7.14 7.15 // Code emission 7.16 - void emit_int8 (int8_t x) { *((int8_t*) end()) = x; set_end(end() + 1); } 7.17 - void emit_int16(int16_t x) { *((int16_t*) end()) = x; set_end(end() + 2); } 7.18 - void emit_int32(int32_t x) { *((int32_t*) end()) = x; set_end(end() + 4); } 7.19 - void emit_int64(int64_t x) { *((int64_t*) end()) = x; set_end(end() + 8); } 7.20 + void emit_int8 ( int8_t x) { *((int8_t*) end()) = x; set_end(end() + sizeof(int8_t)); } 7.21 + void emit_int16( int16_t x) { *((int16_t*) end()) = x; set_end(end() + sizeof(int16_t)); } 7.22 + void emit_int32( int32_t x) { *((int32_t*) end()) = x; set_end(end() + sizeof(int32_t)); } 7.23 + void emit_int64( int64_t x) { *((int64_t*) end()) = x; set_end(end() + sizeof(int64_t)); } 7.24 + 7.25 + void emit_float( jfloat x) { *((jfloat*) end()) = x; set_end(end() + sizeof(jfloat)); } 7.26 + void emit_double(jdouble x) { *((jdouble*) end()) = x; set_end(end() + sizeof(jdouble)); } 7.27 + void emit_address(address x) { *((address*) end()) = x; set_end(end() + sizeof(address)); } 7.28 7.29 // Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.) 7.30 void initialize_shared_locs(relocInfo* buf, int length);