Mercurial > hg > truffle
comparison src/cpu/sparc/vm/assembler_sparc.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | 2cb2f30450c7 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, 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. |
50 #define STOP(error) block_comment(error); stop(error) | 50 #define STOP(error) block_comment(error); stop(error) |
51 #endif | 51 #endif |
52 | 52 |
53 // Convert the raw encoding form into the form expected by the | 53 // Convert the raw encoding form into the form expected by the |
54 // constructor for Address. | 54 // constructor for Address. |
55 Address Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) { | 55 Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) { |
56 assert(scale == 0, "not supported"); | 56 assert(scale == 0, "not supported"); |
57 RelocationHolder rspec; | 57 RelocationHolder rspec; |
58 if (disp_is_oop) { | 58 if (disp_reloc != relocInfo::none) { |
59 rspec = Relocation::spec_simple(relocInfo::oop_type); | 59 rspec = Relocation::spec_simple(disp_reloc); |
60 } | 60 } |
61 | 61 |
62 Register rindex = as_Register(index); | 62 Register rindex = as_Register(index); |
63 if (rindex != G0) { | 63 if (rindex != G0) { |
64 Address madr(as_Register(base), rindex); | 64 Address madr(as_Register(base), rindex); |
1248 st_ptr(G0, vm_result_addr); | 1248 st_ptr(G0, vm_result_addr); |
1249 verify_oop(oop_result); | 1249 verify_oop(oop_result); |
1250 } | 1250 } |
1251 | 1251 |
1252 | 1252 |
1253 void MacroAssembler::get_vm_result_2(Register oop_result) { | 1253 void MacroAssembler::get_vm_result_2(Register metadata_result) { |
1254 verify_thread(); | 1254 verify_thread(); |
1255 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); | 1255 Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset()); |
1256 ld_ptr(vm_result_addr_2, oop_result); | 1256 ld_ptr(vm_result_addr_2, metadata_result); |
1257 st_ptr(G0, vm_result_addr_2); | 1257 st_ptr(G0, vm_result_addr_2); |
1258 verify_oop(oop_result); | |
1259 } | 1258 } |
1260 | 1259 |
1261 | 1260 |
1262 // We require that C code which does not return a value in vm_result will | 1261 // We require that C code which does not return a value in vm_result will |
1263 // leave it undisturbed. | 1262 // leave it undisturbed. |
1279 breakpoint_trap(notZero, Assembler::ptr_cc); | 1278 breakpoint_trap(notZero, Assembler::ptr_cc); |
1280 // } | 1279 // } |
1281 # endif | 1280 # endif |
1282 | 1281 |
1283 st_ptr(oop_result, vm_result_addr); | 1282 st_ptr(oop_result, vm_result_addr); |
1283 } | |
1284 | |
1285 | |
1286 void MacroAssembler::ic_call(address entry, bool emit_delay) { | |
1287 RelocationHolder rspec = virtual_call_Relocation::spec(pc()); | |
1288 patchable_set((intptr_t)Universe::non_oop_word(), G5_inline_cache_reg); | |
1289 relocate(rspec); | |
1290 call(entry, relocInfo::none); | |
1291 if (emit_delay) { | |
1292 delayed()->nop(); | |
1293 } | |
1284 } | 1294 } |
1285 | 1295 |
1286 | 1296 |
1287 void MacroAssembler::card_table_write(jbyte* byte_map_base, | 1297 void MacroAssembler::card_table_write(jbyte* byte_map_base, |
1288 Register tmp, Register obj) { | 1298 Register tmp, Register obj) { |
1610 mov(s2->after_save(), d2); | 1620 mov(s2->after_save(), d2); |
1611 } | 1621 } |
1612 } | 1622 } |
1613 | 1623 |
1614 | 1624 |
1615 AddressLiteral MacroAssembler::allocate_oop_address(jobject obj) { | 1625 AddressLiteral MacroAssembler::allocate_metadata_address(Metadata* obj) { |
1616 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 1626 assert(oop_recorder() != NULL, "this assembler needs a Recorder"); |
1617 int oop_index = oop_recorder()->allocate_index(obj); | 1627 int index = oop_recorder()->allocate_metadata_index(obj); |
1618 return AddressLiteral(obj, oop_Relocation::spec(oop_index)); | 1628 RelocationHolder rspec = metadata_Relocation::spec(index); |
1629 return AddressLiteral((address)obj, rspec); | |
1630 } | |
1631 | |
1632 AddressLiteral MacroAssembler::constant_metadata_address(Metadata* obj) { | |
1633 assert(oop_recorder() != NULL, "this assembler needs a Recorder"); | |
1634 int index = oop_recorder()->find_index(obj); | |
1635 RelocationHolder rspec = metadata_Relocation::spec(index); | |
1636 return AddressLiteral((address)obj, rspec); | |
1619 } | 1637 } |
1620 | 1638 |
1621 | 1639 |
1622 AddressLiteral MacroAssembler::constant_oop_address(jobject obj) { | 1640 AddressLiteral MacroAssembler::constant_oop_address(jobject obj) { |
1623 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 1641 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
1642 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "not an oop"); | |
1624 int oop_index = oop_recorder()->find_index(obj); | 1643 int oop_index = oop_recorder()->find_index(obj); |
1625 return AddressLiteral(obj, oop_Relocation::spec(oop_index)); | 1644 return AddressLiteral(obj, oop_Relocation::spec(oop_index)); |
1626 } | 1645 } |
1627 | 1646 |
1628 void MacroAssembler::set_narrow_oop(jobject obj, Register d) { | 1647 void MacroAssembler::set_narrow_oop(jobject obj, Register d) { |
1904 if ((NULL_WORD & Universe::verify_oop_mask()) == Universe::verify_oop_bits()) { | 1923 if ((NULL_WORD & Universe::verify_oop_mask()) == Universe::verify_oop_bits()) { |
1905 // the null_or_fail case is useless; must test for null separately | 1924 // the null_or_fail case is useless; must test for null separately |
1906 br_null_short(O0_obj, pn, succeed); | 1925 br_null_short(O0_obj, pn, succeed); |
1907 } | 1926 } |
1908 | 1927 |
1909 // Check the klassOop of this object for being in the right area of memory. | 1928 // Check the Klass* of this object for being in the right area of memory. |
1910 // Cannot do the load in the delay above slot in case O0 is null | 1929 // Cannot do the load in the delay above slot in case O0 is null |
1911 load_klass(O0_obj, O0_obj); | 1930 load_klass(O0_obj, O0_obj); |
1912 // assert((klass & klass_mask) == klass_bits); | 1931 // assert((klass != NULL) |
1913 if( Universe::verify_klass_mask() != Universe::verify_oop_mask() ) | 1932 br_null_short(O0_obj, pn, fail); |
1914 set(Universe::verify_klass_mask(), O2_mask); | 1933 // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers |
1915 if( Universe::verify_klass_bits() != Universe::verify_oop_bits() ) | 1934 |
1916 set(Universe::verify_klass_bits(), O3_bits); | 1935 wrccr( O5_save_flags ); // Restore CCR's |
1917 and3(O0_obj, O2_mask, O4_temp); | |
1918 cmp_and_brx_short(O4_temp, O3_bits, notEqual, pn, fail); | |
1919 // Check the klass's klass | |
1920 load_klass(O0_obj, O0_obj); | |
1921 and3(O0_obj, O2_mask, O4_temp); | |
1922 cmp(O4_temp, O3_bits); | |
1923 brx(notEqual, false, pn, fail); | |
1924 delayed()->wrccr( O5_save_flags ); // Restore CCR's | |
1925 | 1936 |
1926 // mark upper end of faulting range | 1937 // mark upper end of faulting range |
1927 _verify_oop_implicit_branch[1] = pc(); | 1938 _verify_oop_implicit_branch[1] = pc(); |
1928 | 1939 |
1929 //----------------------- | 1940 //----------------------- |
2063 } | 2074 } |
2064 | 2075 |
2065 | 2076 |
2066 void MacroAssembler::debug(char* msg, RegistersForDebugging* regs) { | 2077 void MacroAssembler::debug(char* msg, RegistersForDebugging* regs) { |
2067 if ( ShowMessageBoxOnError ) { | 2078 if ( ShowMessageBoxOnError ) { |
2068 JavaThreadState saved_state = JavaThread::current()->thread_state(); | 2079 JavaThread* thread = JavaThread::current(); |
2069 JavaThread::current()->set_thread_state(_thread_in_vm); | 2080 JavaThreadState saved_state = thread->thread_state(); |
2081 thread->set_thread_state(_thread_in_vm); | |
2070 { | 2082 { |
2071 // In order to get locks work, we need to fake a in_VM state | 2083 // In order to get locks work, we need to fake a in_VM state |
2072 ttyLocker ttyl; | 2084 ttyLocker ttyl; |
2073 ::tty->print_cr("EXECUTION STOPPED: %s\n", msg); | 2085 ::tty->print_cr("EXECUTION STOPPED: %s\n", msg); |
2074 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { | 2086 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { |
2075 ::tty->print_cr("Interpreter::bytecode_counter = %d", BytecodeCounter::counter_value()); | 2087 BytecodeCounter::print(); |
2076 } | 2088 } |
2077 if (os::message_box(msg, "Execution stopped, print registers?")) | 2089 if (os::message_box(msg, "Execution stopped, print registers?")) |
2078 regs->print(::tty); | 2090 regs->print(::tty); |
2079 } | 2091 } |
2092 BREAKPOINT; | |
2080 ThreadStateTransition::transition(JavaThread::current(), _thread_in_vm, saved_state); | 2093 ThreadStateTransition::transition(JavaThread::current(), _thread_in_vm, saved_state); |
2081 } | 2094 } |
2082 else | 2095 else { |
2083 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); | 2096 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg); |
2097 } | |
2084 assert(false, err_msg("DEBUG MESSAGE: %s", msg)); | 2098 assert(false, err_msg("DEBUG MESSAGE: %s", msg)); |
2085 } | 2099 } |
2086 | |
2087 | 2100 |
2088 #ifndef PRODUCT | 2101 #ifndef PRODUCT |
2089 void MacroAssembler::test() { | 2102 void MacroAssembler::test() { |
2090 ResourceMark rm; | 2103 ResourceMark rm; |
2091 | 2104 |
2929 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); | 2942 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
2930 assert(itable_index.is_constant() || itable_index.as_register() == method_result, | 2943 assert(itable_index.is_constant() || itable_index.as_register() == method_result, |
2931 "caller must use same register for non-constant itable index as for method"); | 2944 "caller must use same register for non-constant itable index as for method"); |
2932 | 2945 |
2933 // Compute start of first itableOffsetEntry (which is at the end of the vtable) | 2946 // Compute start of first itableOffsetEntry (which is at the end of the vtable) |
2934 int vtable_base = instanceKlass::vtable_start_offset() * wordSize; | 2947 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; |
2935 int scan_step = itableOffsetEntry::size() * wordSize; | 2948 int scan_step = itableOffsetEntry::size() * wordSize; |
2936 int vte_size = vtableEntry::size() * wordSize; | 2949 int vte_size = vtableEntry::size() * wordSize; |
2937 | 2950 |
2938 lduw(recv_klass, instanceKlass::vtable_length_offset() * wordSize, scan_temp); | 2951 lduw(recv_klass, InstanceKlass::vtable_length_offset() * wordSize, scan_temp); |
2939 // %%% We should store the aligned, prescaled offset in the klassoop. | 2952 // %%% We should store the aligned, prescaled offset in the klassoop. |
2940 // Then the next several instructions would fold away. | 2953 // Then the next several instructions would fold away. |
2941 | 2954 |
2942 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0); | 2955 int round_to_unit = ((HeapWordsPerLong > 1) ? BytesPerLong : 0); |
2943 int itb_offset = vtable_base; | 2956 int itb_offset = vtable_base; |
2948 int itb_scale = exact_log2(vtableEntry::size() * wordSize); | 2961 int itb_scale = exact_log2(vtableEntry::size() * wordSize); |
2949 sll(scan_temp, itb_scale, scan_temp); | 2962 sll(scan_temp, itb_scale, scan_temp); |
2950 add(scan_temp, itb_offset, scan_temp); | 2963 add(scan_temp, itb_offset, scan_temp); |
2951 if (round_to_unit != 0) { | 2964 if (round_to_unit != 0) { |
2952 // Round up to align_object_offset boundary | 2965 // Round up to align_object_offset boundary |
2953 // see code for instanceKlass::start_of_itable! | 2966 // see code for InstanceKlass::start_of_itable! |
2954 // Was: round_to(scan_temp, BytesPerLong); | 2967 // Was: round_to(scan_temp, BytesPerLong); |
2955 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); | 2968 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); |
2956 and3(scan_temp, -round_to_unit, scan_temp); | 2969 and3(scan_temp, -round_to_unit, scan_temp); |
2957 } | 2970 } |
2958 add(recv_klass, scan_temp, scan_temp); | 2971 add(recv_klass, scan_temp, scan_temp); |
3009 void MacroAssembler::lookup_virtual_method(Register recv_klass, | 3022 void MacroAssembler::lookup_virtual_method(Register recv_klass, |
3010 RegisterOrConstant vtable_index, | 3023 RegisterOrConstant vtable_index, |
3011 Register method_result) { | 3024 Register method_result) { |
3012 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg()); | 3025 assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg()); |
3013 Register sethi_temp = method_result; | 3026 Register sethi_temp = method_result; |
3014 const int base = (instanceKlass::vtable_start_offset() * wordSize + | 3027 const int base = (InstanceKlass::vtable_start_offset() * wordSize + |
3015 // method pointer offset within the vtable entry: | 3028 // method pointer offset within the vtable entry: |
3016 vtableEntry::method_offset_in_bytes()); | 3029 vtableEntry::method_offset_in_bytes()); |
3017 RegisterOrConstant vtable_offset = vtable_index; | 3030 RegisterOrConstant vtable_offset = vtable_index; |
3018 // Each of the following three lines potentially generates an instruction. | 3031 // Each of the following three lines potentially generates an instruction. |
3019 // But the total number of address formation instructions will always be | 3032 // But the total number of address formation instructions will always be |
3210 #endif | 3223 #endif |
3211 | 3224 |
3212 // We will consult the secondary-super array. | 3225 // We will consult the secondary-super array. |
3213 ld_ptr(sub_klass, ss_offset, scan_temp); | 3226 ld_ptr(sub_klass, ss_offset, scan_temp); |
3214 | 3227 |
3215 // Compress superclass if necessary. | |
3216 Register search_key = super_klass; | 3228 Register search_key = super_klass; |
3217 bool decode_super_klass = false; | |
3218 if (UseCompressedOops) { | |
3219 if (coop_reg != noreg) { | |
3220 encode_heap_oop_not_null(super_klass, coop_reg); | |
3221 search_key = coop_reg; | |
3222 } else { | |
3223 encode_heap_oop_not_null(super_klass); | |
3224 decode_super_klass = true; // scarce temps! | |
3225 } | |
3226 // The superclass is never null; it would be a basic system error if a null | |
3227 // pointer were to sneak in here. Note that we have already loaded the | |
3228 // Klass::super_check_offset from the super_klass in the fast path, | |
3229 // so if there is a null in that register, we are already in the afterlife. | |
3230 } | |
3231 | 3229 |
3232 // Load the array length. (Positive movl does right thing on LP64.) | 3230 // Load the array length. (Positive movl does right thing on LP64.) |
3233 lduw(scan_temp, arrayOopDesc::length_offset_in_bytes(), count_temp); | 3231 lduw(scan_temp, Array<Klass*>::length_offset_in_bytes(), count_temp); |
3234 | 3232 |
3235 // Check for empty secondary super list | 3233 // Check for empty secondary super list |
3236 tst(count_temp); | 3234 tst(count_temp); |
3235 | |
3236 // In the array of super classes elements are pointer sized. | |
3237 int element_size = wordSize; | |
3237 | 3238 |
3238 // Top of search loop | 3239 // Top of search loop |
3239 bind(L_loop); | 3240 bind(L_loop); |
3240 br(Assembler::equal, false, Assembler::pn, *L_failure); | 3241 br(Assembler::equal, false, Assembler::pn, *L_failure); |
3241 delayed()->add(scan_temp, heapOopSize, scan_temp); | 3242 delayed()->add(scan_temp, element_size, scan_temp); |
3242 assert(heapOopSize != 0, "heapOopSize should be initialized"); | |
3243 | 3243 |
3244 // Skip the array header in all array accesses. | 3244 // Skip the array header in all array accesses. |
3245 int elem_offset = arrayOopDesc::base_offset_in_bytes(T_OBJECT); | 3245 int elem_offset = Array<Klass*>::base_offset_in_bytes(); |
3246 elem_offset -= heapOopSize; // the scan pointer was pre-incremented also | 3246 elem_offset -= element_size; // the scan pointer was pre-incremented also |
3247 | 3247 |
3248 // Load next super to check | 3248 // Load next super to check |
3249 if (UseCompressedOops) { | |
3250 // Don't use load_heap_oop; we don't want to decode the element. | |
3251 lduw( scan_temp, elem_offset, scratch_reg ); | |
3252 } else { | |
3253 ld_ptr( scan_temp, elem_offset, scratch_reg ); | 3249 ld_ptr( scan_temp, elem_offset, scratch_reg ); |
3254 } | |
3255 | 3250 |
3256 // Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list | 3251 // Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list |
3257 cmp(scratch_reg, search_key); | 3252 cmp(scratch_reg, search_key); |
3258 | 3253 |
3259 // A miss means we are NOT a subtype and need to keep looping | 3254 // A miss means we are NOT a subtype and need to keep looping |
3260 brx(Assembler::notEqual, false, Assembler::pn, L_loop); | 3255 brx(Assembler::notEqual, false, Assembler::pn, L_loop); |
3261 delayed()->deccc(count_temp); // decrement trip counter in delay slot | 3256 delayed()->deccc(count_temp); // decrement trip counter in delay slot |
3262 | |
3263 // Falling out the bottom means we found a hit; we ARE a subtype | |
3264 if (decode_super_klass) decode_heap_oop(super_klass); | |
3265 | 3257 |
3266 // Success. Cache the super we found and proceed in triumph. | 3258 // Success. Cache the super we found and proceed in triumph. |
3267 st_ptr(super_klass, sub_klass, sc_offset); | 3259 st_ptr(super_klass, sub_klass, sc_offset); |
3268 | 3260 |
3269 if (L_success != &L_fallthrough) { | 3261 if (L_success != &L_fallthrough) { |
4656 | 4648 |
4657 void MacroAssembler::load_klass(Register src_oop, Register klass) { | 4649 void MacroAssembler::load_klass(Register src_oop, Register klass) { |
4658 // The number of bytes in this code is used by | 4650 // The number of bytes in this code is used by |
4659 // MachCallDynamicJavaNode::ret_addr_offset() | 4651 // MachCallDynamicJavaNode::ret_addr_offset() |
4660 // if this changes, change that. | 4652 // if this changes, change that. |
4661 if (UseCompressedOops) { | 4653 if (UseCompressedKlassPointers) { |
4662 lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass); | 4654 lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass); |
4663 decode_heap_oop_not_null(klass); | 4655 decode_heap_oop_not_null(klass); |
4664 } else { | 4656 } else { |
4665 ld_ptr(src_oop, oopDesc::klass_offset_in_bytes(), klass); | 4657 ld_ptr(src_oop, oopDesc::klass_offset_in_bytes(), klass); |
4666 } | 4658 } |
4667 } | 4659 } |
4668 | 4660 |
4669 void MacroAssembler::store_klass(Register klass, Register dst_oop) { | 4661 void MacroAssembler::store_klass(Register klass, Register dst_oop) { |
4670 if (UseCompressedOops) { | 4662 if (UseCompressedKlassPointers) { |
4671 assert(dst_oop != klass, "not enough registers"); | 4663 assert(dst_oop != klass, "not enough registers"); |
4672 encode_heap_oop_not_null(klass); | 4664 encode_heap_oop_not_null(klass); |
4673 st(klass, dst_oop, oopDesc::klass_offset_in_bytes()); | 4665 st(klass, dst_oop, oopDesc::klass_offset_in_bytes()); |
4674 } else { | 4666 } else { |
4675 st_ptr(klass, dst_oop, oopDesc::klass_offset_in_bytes()); | 4667 st_ptr(klass, dst_oop, oopDesc::klass_offset_in_bytes()); |
4676 } | 4668 } |
4677 } | 4669 } |
4678 | 4670 |
4679 void MacroAssembler::store_klass_gap(Register s, Register d) { | 4671 void MacroAssembler::store_klass_gap(Register s, Register d) { |
4680 if (UseCompressedOops) { | 4672 if (UseCompressedKlassPointers) { |
4681 assert(s != d, "not enough registers"); | 4673 assert(s != d, "not enough registers"); |
4682 st(s, d, oopDesc::klass_gap_offset_in_bytes()); | 4674 st(s, d, oopDesc::klass_gap_offset_in_bytes()); |
4683 } | 4675 } |
4684 } | 4676 } |
4685 | 4677 |