2013 } |
2013 } |
2014 |
2014 |
2015 int vep_offset = ((intptr_t)__ pc()) - start; |
2015 int vep_offset = ((intptr_t)__ pc()) - start; |
2016 |
2016 |
2017 #ifdef COMPILER1 |
2017 #ifdef COMPILER1 |
2018 if (InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) { |
2018 if ((InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) || (method->intrinsic_id() == vmIntrinsics::_identityHashCode)) { |
2019 // Object.hashCode can pull the hashCode from the header word |
2019 // Object.hashCode, System.identityHashCode can pull the hashCode from the |
2020 // instead of doing a full VM transition once it's been computed. |
2020 // header word instead of doing a full VM transition once it's been computed. |
2021 // Since hashCode is usually polymorphic at call sites we can't do |
2021 // Since hashCode is usually polymorphic at call sites we can't do this |
2022 // this optimization at the call site without a lot of work. |
2022 // optimization at the call site without a lot of work. |
2023 Label slowCase; |
2023 Label slowCase; |
2024 Register receiver = O0; |
2024 Label done; |
|
2025 Register obj_reg = O0; |
2025 Register result = O0; |
2026 Register result = O0; |
2026 Register header = G3_scratch; |
2027 Register header = G3_scratch; |
2027 Register hash = G3_scratch; // overwrite header value with hash value |
2028 Register hash = G3_scratch; // overwrite header value with hash value |
2028 Register mask = G1; // to get hash field from header |
2029 Register mask = G1; // to get hash field from header |
2029 |
2030 |
|
2031 // Unlike for Object.hashCode, System.identityHashCode is static method and |
|
2032 // gets object as argument instead of the receiver. |
|
2033 if (method->intrinsic_id() == vmIntrinsics::_identityHashCode) { |
|
2034 assert(method->is_static(), "method should be static"); |
|
2035 // return 0 for null reference input |
|
2036 __ br_null(obj_reg, false, Assembler::pn, done); |
|
2037 __ delayed()->mov(obj_reg, hash); |
|
2038 } |
|
2039 |
2030 // Read the header and build a mask to get its hash field. Give up if the object is not unlocked. |
2040 // Read the header and build a mask to get its hash field. Give up if the object is not unlocked. |
2031 // We depend on hash_mask being at most 32 bits and avoid the use of |
2041 // We depend on hash_mask being at most 32 bits and avoid the use of |
2032 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit |
2042 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit |
2033 // vm: see markOop.hpp. |
2043 // vm: see markOop.hpp. |
2034 __ ld_ptr(receiver, oopDesc::mark_offset_in_bytes(), header); |
2044 __ ld_ptr(obj_reg, oopDesc::mark_offset_in_bytes(), header); |
2035 __ sethi(markOopDesc::hash_mask, mask); |
2045 __ sethi(markOopDesc::hash_mask, mask); |
2036 __ btst(markOopDesc::unlocked_value, header); |
2046 __ btst(markOopDesc::unlocked_value, header); |
2037 __ br(Assembler::zero, false, Assembler::pn, slowCase); |
2047 __ br(Assembler::zero, false, Assembler::pn, slowCase); |
2038 if (UseBiasedLocking) { |
2048 if (UseBiasedLocking) { |
2039 // Check if biased and fall through to runtime if so |
2049 // Check if biased and fall through to runtime if so |