Mercurial > hg > graal-jvmci-8
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; |