comparison src/cpu/x86/vm/assembler_x86_64.cpp @ 164:c436414a719e

6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions Summary: Add LoadNKlass and CMoveN nodes, use CmpN and ConN nodes to generate narrow oops compare instructions. Reviewed-by: never, rasbold
author kvn
date Wed, 21 May 2008 13:46:23 -0700
parents b130b98db9cf
children feeb96a45707
comparison
equal deleted inserted replaced
163:885ed790ecf0 164:c436414a719e
681 } 681 }
682 break; 682 break;
683 683
684 case REP8(0xB8): // movl/q r, #32/#64(oop?) 684 case REP8(0xB8): // movl/q r, #32/#64(oop?)
685 if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); 685 if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4);
686 assert((which == call32_operand || which == imm64_operand) && is_64bit, ""); 686 assert((which == call32_operand || which == imm64_operand) && is_64bit ||
687 which == narrow_oop_operand && !is_64bit, "");
687 return ip; 688 return ip;
688 689
689 case 0x69: // imul r, a, #32 690 case 0x69: // imul r, a, #32
690 case 0xC7: // movl a, #32(oop?) 691 case 0xC7: // movl a, #32(oop?)
691 tail_size = 4; 692 tail_size = 4;
907 if (r->type() == relocInfo::none) { 908 if (r->type() == relocInfo::none) {
908 return; 909 return;
909 } else if (r->is_call() || format == call32_operand) { 910 } else if (r->is_call() || format == call32_operand) {
910 opnd = locate_operand(inst, call32_operand); 911 opnd = locate_operand(inst, call32_operand);
911 } else if (r->is_data()) { 912 } else if (r->is_data()) {
912 assert(format == imm64_operand || format == disp32_operand, "format ok"); 913 assert(format == imm64_operand || format == disp32_operand ||
914 format == narrow_oop_operand, "format ok");
913 opnd = locate_operand(inst, (WhichOperand) format); 915 opnd = locate_operand(inst, (WhichOperand) format);
914 } else { 916 } else {
915 assert(format == 0, "cannot specify a format"); 917 assert(format == 0, "cannot specify a format");
916 return; 918 return;
917 } 919 }
5155 } 5157 }
5156 5158
5157 void MacroAssembler::store_klass(Register dst, Register src) { 5159 void MacroAssembler::store_klass(Register dst, Register src) {
5158 if (UseCompressedOops) { 5160 if (UseCompressedOops) {
5159 encode_heap_oop_not_null(src); 5161 encode_heap_oop_not_null(src);
5160 // zero the entire klass field first as the gap needs to be zeroed too. 5162 // Store to the wide klass field to zero the gap.
5161 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD); 5163 }
5162 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); 5164 movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
5163 } else {
5164 movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
5165 }
5166 } 5165 }
5167 5166
5168 void MacroAssembler::load_heap_oop(Register dst, Address src) { 5167 void MacroAssembler::load_heap_oop(Register dst, Address src) {
5169 if (UseCompressedOops) { 5168 if (UseCompressedOops) {
5170 movl(dst, src); 5169 movl(dst, src);
5186 5185
5187 // Algorithm must match oop.inline.hpp encode_heap_oop. 5186 // Algorithm must match oop.inline.hpp encode_heap_oop.
5188 void MacroAssembler::encode_heap_oop(Register r) { 5187 void MacroAssembler::encode_heap_oop(Register r) {
5189 assert (UseCompressedOops, "should be compressed"); 5188 assert (UseCompressedOops, "should be compressed");
5190 #ifdef ASSERT 5189 #ifdef ASSERT
5191 Label ok; 5190 if (CheckCompressedOops) {
5192 pushq(rscratch1); // cmpptr trashes rscratch1 5191 Label ok;
5193 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); 5192 pushq(rscratch1); // cmpptr trashes rscratch1
5194 jcc(Assembler::equal, ok); 5193 cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
5195 stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); 5194 jcc(Assembler::equal, ok);
5196 bind(ok); 5195 stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
5197 popq(rscratch1); 5196 bind(ok);
5197 popq(rscratch1);
5198 }
5198 #endif 5199 #endif
5199 verify_oop(r, "broken oop in encode_heap_oop"); 5200 verify_oop(r, "broken oop in encode_heap_oop");
5200 testq(r, r); 5201 testq(r, r);
5201 cmovq(Assembler::equal, r, r12_heapbase); 5202 cmovq(Assembler::equal, r, r12_heapbase);
5202 subq(r, r12_heapbase); 5203 subq(r, r12_heapbase);
5204 } 5205 }
5205 5206
5206 void MacroAssembler::encode_heap_oop_not_null(Register r) { 5207 void MacroAssembler::encode_heap_oop_not_null(Register r) {
5207 assert (UseCompressedOops, "should be compressed"); 5208 assert (UseCompressedOops, "should be compressed");
5208 #ifdef ASSERT 5209 #ifdef ASSERT
5209 Label ok; 5210 if (CheckCompressedOops) {
5210 testq(r, r); 5211 Label ok;
5211 jcc(Assembler::notEqual, ok); 5212 testq(r, r);
5212 stop("null oop passed to encode_heap_oop_not_null"); 5213 jcc(Assembler::notEqual, ok);
5213 bind(ok); 5214 stop("null oop passed to encode_heap_oop_not_null");
5215 bind(ok);
5216 }
5214 #endif 5217 #endif
5215 verify_oop(r, "broken oop in encode_heap_oop_not_null"); 5218 verify_oop(r, "broken oop in encode_heap_oop_not_null");
5216 subq(r, r12_heapbase); 5219 subq(r, r12_heapbase);
5217 shrq(r, LogMinObjAlignmentInBytes); 5220 shrq(r, LogMinObjAlignmentInBytes);
5218 } 5221 }
5219 5222
5220 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { 5223 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
5221 assert (UseCompressedOops, "should be compressed"); 5224 assert (UseCompressedOops, "should be compressed");
5222 #ifdef ASSERT 5225 #ifdef ASSERT
5223 Label ok; 5226 if (CheckCompressedOops) {
5224 testq(src, src); 5227 Label ok;
5225 jcc(Assembler::notEqual, ok); 5228 testq(src, src);
5226 stop("null oop passed to encode_heap_oop_not_null2"); 5229 jcc(Assembler::notEqual, ok);
5227 bind(ok); 5230 stop("null oop passed to encode_heap_oop_not_null2");
5231 bind(ok);
5232 }
5228 #endif 5233 #endif
5229 verify_oop(src, "broken oop in encode_heap_oop_not_null2"); 5234 verify_oop(src, "broken oop in encode_heap_oop_not_null2");
5230 if (dst != src) { 5235 if (dst != src) {
5231 movq(dst, src); 5236 movq(dst, src);
5232 } 5237 }
5235 } 5240 }
5236 5241
5237 void MacroAssembler::decode_heap_oop(Register r) { 5242 void MacroAssembler::decode_heap_oop(Register r) {
5238 assert (UseCompressedOops, "should be compressed"); 5243 assert (UseCompressedOops, "should be compressed");
5239 #ifdef ASSERT 5244 #ifdef ASSERT
5240 Label ok; 5245 if (CheckCompressedOops) {
5241 pushq(rscratch1); 5246 Label ok;
5242 cmpptr(r12_heapbase, 5247 pushq(rscratch1);
5243 ExternalAddress((address)Universe::heap_base_addr())); 5248 cmpptr(r12_heapbase,
5244 jcc(Assembler::equal, ok); 5249 ExternalAddress((address)Universe::heap_base_addr()));
5245 stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); 5250 jcc(Assembler::equal, ok);
5246 bind(ok); 5251 stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
5247 popq(rscratch1); 5252 bind(ok);
5253 popq(rscratch1);
5254 }
5248 #endif 5255 #endif
5249 5256
5250 Label done; 5257 Label done;
5251 shlq(r, LogMinObjAlignmentInBytes); 5258 shlq(r, LogMinObjAlignmentInBytes);
5252 jccb(Assembler::equal, done); 5259 jccb(Assembler::equal, done);
5274 // Cannot assert, unverified entry point counts instructions (see .ad file) 5281 // Cannot assert, unverified entry point counts instructions (see .ad file)
5275 // vtableStubs also counts instructions in pd_code_size_limit. 5282 // vtableStubs also counts instructions in pd_code_size_limit.
5276 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); 5283 assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
5277 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); 5284 leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
5278 } 5285 }
5286
5287 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
5288 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
5289 int oop_index = oop_recorder()->find_index(obj);
5290 RelocationHolder rspec = oop_Relocation::spec(oop_index);
5291
5292 // movl dst,obj
5293 InstructionMark im(this);
5294 int encode = prefix_and_encode(dst->encoding());
5295 emit_byte(0xB8 | encode);
5296 emit_data(oop_index, rspec, narrow_oop_operand);
5297 }
5298
5279 5299
5280 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { 5300 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
5281 switch (cond) { 5301 switch (cond) {
5282 // Note some conditions are synonyms for others 5302 // Note some conditions are synonyms for others
5283 case Assembler::zero: return Assembler::notZero; 5303 case Assembler::zero: return Assembler::notZero;