comparison src/cpu/x86/vm/assembler_x86.cpp @ 2100:b1a2afa37ec4

7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis Summary: Track allocated bytes in Thread's, update on TLAB retirement and direct allocation in Eden and tenured, add JNI methods for ThreadMXBean. Reviewed-by: coleenp, kvn, dholmes, ysr
author phh
date Fri, 07 Jan 2011 10:42:32 -0500
parents 4de5f4101cfd
children 91fe28b03d6a 28bf941f445e
comparison
equal deleted inserted replaced
2097:039eb4201e06 2100:b1a2afa37ec4
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
818 emit_byte(b1); 818 emit_byte(b1);
819 emit_byte(b2 + i); 819 emit_byte(b2 + i);
820 } 820 }
821 821
822 822
823 // Now the Assembler instruction (identical for 32/64 bits) 823 // Now the Assembler instructions (identical for 32/64 bits)
824
825 void Assembler::adcl(Address dst, int32_t imm32) {
826 InstructionMark im(this);
827 prefix(dst);
828 emit_arith_operand(0x81, rdx, dst, imm32);
829 }
830
831 void Assembler::adcl(Address dst, Register src) {
832 InstructionMark im(this);
833 prefix(dst, src);
834 emit_byte(0x11);
835 emit_operand(src, dst);
836 }
824 837
825 void Assembler::adcl(Register dst, int32_t imm32) { 838 void Assembler::adcl(Register dst, int32_t imm32) {
826 prefix(dst); 839 prefix(dst);
827 emit_arith(0x81, 0xD0, dst, imm32); 840 emit_arith(0x81, 0xD0, dst, imm32);
828 } 841 }
2193 } 2206 }
2194 2207
2195 void Assembler::orl(Address dst, int32_t imm32) { 2208 void Assembler::orl(Address dst, int32_t imm32) {
2196 InstructionMark im(this); 2209 InstructionMark im(this);
2197 prefix(dst); 2210 prefix(dst);
2198 emit_byte(0x81); 2211 emit_arith_operand(0x81, rcx, dst, imm32);
2199 emit_operand(rcx, dst, 4);
2200 emit_long(imm32);
2201 } 2212 }
2202 2213
2203 void Assembler::orl(Register dst, int32_t imm32) { 2214 void Assembler::orl(Register dst, int32_t imm32) {
2204 prefix(dst); 2215 prefix(dst);
2205 emit_arith(0x81, 0xC8, dst, imm32); 2216 emit_arith(0x81, 0xC8, dst, imm32);
2206 } 2217 }
2207 2218
2208
2209 void Assembler::orl(Register dst, Address src) { 2219 void Assembler::orl(Register dst, Address src) {
2210 InstructionMark im(this); 2220 InstructionMark im(this);
2211 prefix(src, dst); 2221 prefix(src, dst);
2212 emit_byte(0x0B); 2222 emit_byte(0x0B);
2213 emit_operand(dst, src); 2223 emit_operand(dst, src);
2214 } 2224 }
2215
2216 2225
2217 void Assembler::orl(Register dst, Register src) { 2226 void Assembler::orl(Register dst, Register src) {
2218 (void) prefix_and_encode(dst->encoding(), src->encoding()); 2227 (void) prefix_and_encode(dst->encoding(), src->encoding());
2219 emit_arith(0x0B, 0xC0, dst, src); 2228 emit_arith(0x0B, 0xC0, dst, src);
2220 } 2229 }
2690 } 2699 }
2691 2700
2692 void Assembler::subl(Address dst, int32_t imm32) { 2701 void Assembler::subl(Address dst, int32_t imm32) {
2693 InstructionMark im(this); 2702 InstructionMark im(this);
2694 prefix(dst); 2703 prefix(dst);
2695 if (is8bit(imm32)) { 2704 emit_arith_operand(0x81, rbp, dst, imm32);
2696 emit_byte(0x83); 2705 }
2697 emit_operand(rbp, dst, 1); 2706
2698 emit_byte(imm32 & 0xFF); 2707 void Assembler::subl(Address dst, Register src) {
2699 } else { 2708 InstructionMark im(this);
2700 emit_byte(0x81); 2709 prefix(dst, src);
2701 emit_operand(rbp, dst, 4); 2710 emit_byte(0x29);
2702 emit_long(imm32); 2711 emit_operand(src, dst);
2703 }
2704 } 2712 }
2705 2713
2706 void Assembler::subl(Register dst, int32_t imm32) { 2714 void Assembler::subl(Register dst, int32_t imm32) {
2707 prefix(dst); 2715 prefix(dst);
2708 emit_arith(0x81, 0xE8, dst, imm32); 2716 emit_arith(0x81, 0xE8, dst, imm32);
2709 }
2710
2711 void Assembler::subl(Address dst, Register src) {
2712 InstructionMark im(this);
2713 prefix(dst, src);
2714 emit_byte(0x29);
2715 emit_operand(src, dst);
2716 } 2717 }
2717 2718
2718 void Assembler::subl(Register dst, Address src) { 2719 void Assembler::subl(Register dst, Address src) {
2719 InstructionMark im(this); 2720 InstructionMark im(this);
2720 prefix(src, dst); 2721 prefix(src, dst);
4331 void Assembler::sarq(Register dst) { 4332 void Assembler::sarq(Register dst) {
4332 int encode = prefixq_and_encode(dst->encoding()); 4333 int encode = prefixq_and_encode(dst->encoding());
4333 emit_byte(0xD3); 4334 emit_byte(0xD3);
4334 emit_byte(0xF8 | encode); 4335 emit_byte(0xF8 | encode);
4335 } 4336 }
4337
4336 void Assembler::sbbq(Address dst, int32_t imm32) { 4338 void Assembler::sbbq(Address dst, int32_t imm32) {
4337 InstructionMark im(this); 4339 InstructionMark im(this);
4338 prefixq(dst); 4340 prefixq(dst);
4339 emit_arith_operand(0x81, rbx, dst, imm32); 4341 emit_arith_operand(0x81, rbx, dst, imm32);
4340 } 4342 }
4390 } 4392 }
4391 4393
4392 void Assembler::subq(Address dst, int32_t imm32) { 4394 void Assembler::subq(Address dst, int32_t imm32) {
4393 InstructionMark im(this); 4395 InstructionMark im(this);
4394 prefixq(dst); 4396 prefixq(dst);
4395 if (is8bit(imm32)) { 4397 emit_arith_operand(0x81, rbp, dst, imm32);
4396 emit_byte(0x83); 4398 }
4397 emit_operand(rbp, dst, 1); 4399
4398 emit_byte(imm32 & 0xFF); 4400 void Assembler::subq(Address dst, Register src) {
4399 } else { 4401 InstructionMark im(this);
4400 emit_byte(0x81); 4402 prefixq(dst, src);
4401 emit_operand(rbp, dst, 4); 4403 emit_byte(0x29);
4402 emit_long(imm32); 4404 emit_operand(src, dst);
4403 }
4404 } 4405 }
4405 4406
4406 void Assembler::subq(Register dst, int32_t imm32) { 4407 void Assembler::subq(Register dst, int32_t imm32) {
4407 (void) prefixq_and_encode(dst->encoding()); 4408 (void) prefixq_and_encode(dst->encoding());
4408 emit_arith(0x81, 0xE8, dst, imm32); 4409 emit_arith(0x81, 0xE8, dst, imm32);
4409 }
4410
4411 void Assembler::subq(Address dst, Register src) {
4412 InstructionMark im(this);
4413 prefixq(dst, src);
4414 emit_byte(0x29);
4415 emit_operand(src, dst);
4416 } 4410 }
4417 4411
4418 void Assembler::subq(Register dst, Address src) { 4412 void Assembler::subq(Register dst, Address src) {
4419 InstructionMark im(this); 4413 InstructionMark im(this);
4420 prefixq(src, dst); 4414 prefixq(src, dst);
7134 } 7128 }
7135 verify_tlab(); 7129 verify_tlab();
7136 } 7130 }
7137 7131
7138 // Preserves rbx, and rdx. 7132 // Preserves rbx, and rdx.
7139 void MacroAssembler::tlab_refill(Label& retry, 7133 Register MacroAssembler::tlab_refill(Label& retry,
7140 Label& try_eden, 7134 Label& try_eden,
7141 Label& slow_case) { 7135 Label& slow_case) {
7142 Register top = rax; 7136 Register top = rax;
7143 Register t1 = rcx; 7137 Register t1 = rcx;
7144 Register t2 = rsi; 7138 Register t2 = rsi;
7145 Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread); 7139 Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread);
7146 assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); 7140 assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx);
7183 addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); 7177 addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1);
7184 } 7178 }
7185 7179
7186 // if tlab is currently allocated (top or end != null) then 7180 // if tlab is currently allocated (top or end != null) then
7187 // fill [top, end + alignment_reserve) with array object 7181 // fill [top, end + alignment_reserve) with array object
7188 testptr (top, top); 7182 testptr(top, top);
7189 jcc(Assembler::zero, do_refill); 7183 jcc(Assembler::zero, do_refill);
7190 7184
7191 // set up the mark word 7185 // set up the mark word
7192 movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); 7186 movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
7193 // set the length to the remaining space 7187 // set the length to the remaining space
7195 addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); 7189 addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
7196 shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); 7190 shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint)));
7197 movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); 7191 movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
7198 // set klass to intArrayKlass 7192 // set klass to intArrayKlass
7199 // dubious reloc why not an oop reloc? 7193 // dubious reloc why not an oop reloc?
7200 movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); 7194 movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
7201 // store klass last. concurrent gcs assumes klass length is valid if 7195 // store klass last. concurrent gcs assumes klass length is valid if
7202 // klass field is not null. 7196 // klass field is not null.
7203 store_klass(top, t1); 7197 store_klass(top, t1);
7198
7199 movptr(t1, top);
7200 subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
7201 incr_allocated_bytes(thread_reg, t1, 0);
7204 7202
7205 // refill the tlab with an eden allocation 7203 // refill the tlab with an eden allocation
7206 bind(do_refill); 7204 bind(do_refill);
7207 movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); 7205 movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
7208 shlptr(t1, LogHeapWordSize); 7206 shlptr(t1, LogHeapWordSize);
7209 // add object_size ?? 7207 // allocate new tlab, address returned in top
7210 eden_allocate(top, t1, 0, t2, slow_case); 7208 eden_allocate(top, t1, 0, t2, slow_case);
7211 7209
7212 // Check that t1 was preserved in eden_allocate. 7210 // Check that t1 was preserved in eden_allocate.
7213 #ifdef ASSERT 7211 #ifdef ASSERT
7214 if (UseTLAB) { 7212 if (UseTLAB) {
7232 addptr(top, t1); 7230 addptr(top, t1);
7233 subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); 7231 subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
7234 movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); 7232 movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
7235 verify_tlab(); 7233 verify_tlab();
7236 jmp(retry); 7234 jmp(retry);
7235
7236 return thread_reg; // for use by caller
7237 }
7238
7239 void MacroAssembler::incr_allocated_bytes(Register thread,
7240 Register var_size_in_bytes,
7241 int con_size_in_bytes,
7242 Register t1) {
7243 #ifdef _LP64
7244 if (var_size_in_bytes->is_valid()) {
7245 addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
7246 } else {
7247 addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
7248 }
7249 #else
7250 if (!thread->is_valid()) {
7251 assert(t1->is_valid(), "need temp reg");
7252 thread = t1;
7253 get_thread(thread);
7254 }
7255
7256 if (var_size_in_bytes->is_valid()) {
7257 addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
7258 } else {
7259 addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
7260 }
7261 adcl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())+4), 0);
7262 #endif
7237 } 7263 }
7238 7264
7239 static const double pi_4 = 0.7853981633974483; 7265 static const double pi_4 = 0.7853981633974483;
7240 7266
7241 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { 7267 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) {