From b1aee2df264ea1afdb264fbfa793c2e9f9b32f08 Mon Sep 17 00:00:00 2001 From: kvn Date: Mon, 25 Feb 2008 15:05:44 -0800 Subject: [PATCH] 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM Summary: T_ADDRESS size is defined as 'int' size (4 bytes) but C2 use it for raw pointers and as memory type for StoreP and LoadP nodes. Reviewed-by: jrose --- src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 4 ++-- src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 2 +- src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 8 ++++---- src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 2 +- src/share/vm/c1/c1_LIR.cpp | 2 +- src/share/vm/ci/ciField.hpp | 2 +- src/share/vm/oops/arrayOop.hpp | 4 ++-- src/share/vm/oops/klass.cpp | 2 +- src/share/vm/opto/graphKit.cpp | 2 +- src/share/vm/opto/library_call.cpp | 10 +++++----- src/share/vm/opto/memnode.cpp | 2 +- src/share/vm/opto/memnode.hpp | 8 +++++++- src/share/vm/opto/superword.cpp | 5 +++-- src/share/vm/opto/vectornode.cpp | 2 +- src/share/vm/opto/vectornode.hpp | 6 +++--- src/share/vm/services/heapDumper.cpp | 2 +- src/share/vm/utilities/globalDefinitions.cpp | 10 ++++++++-- src/share/vm/utilities/globalDefinitions.hpp | 11 ++++++++++- 18 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index e59408550..8436fb856 100644 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -2037,7 +2037,7 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr int LIR_Assembler::shift_amount(BasicType t) { - int elem_size = type2aelembytes[t]; + int elem_size = type2aelembytes(t); switch (elem_size) { case 1 : return 0; case 2 : return 1; @@ -2360,7 +2360,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { op->tmp2()->as_register(), op->tmp3()->as_register(), arrayOopDesc::header_size(op->type()), - type2aelembytes[op->type()], + type2aelembytes(op->type()), op->klass()->as_register(), *op->stub()->entry()); } diff --git a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 443551871..74bc5ecf3 100644 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -179,7 +179,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); int shift = exact_log2(elem_size); LIR_Opr base_opr; diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index e87d55ce2..7c632cbab 100644 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -546,8 +546,8 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // set rsi.edi to the end of the arrays (arrays have same length) // negate the index - __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes[T_CHAR])); - __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes[T_CHAR])); + __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); __ negl(rax); // compare the strings in a loop @@ -1232,7 +1232,7 @@ void LIR_Assembler::prefetchw(LIR_Opr src) { NEEDS_CLEANUP; // This could be static? Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); switch (elem_size) { case 1: return Address::times_1; case 2: return Address::times_2; @@ -2739,7 +2739,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point"); - int elem_size = type2aelembytes[basic_type]; + int elem_size = type2aelembytes(basic_type); int shift_amount; Address::ScaleFactor scale; diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index a98d1b954..7c4861d61 100644 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -151,7 +151,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o LIR_Address* addr; if (index_opr->is_constant()) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); addr = new LIR_Address(array_opr, offset_in_bytes + index_opr->as_jint() * elem_size, type); } else { diff --git a/src/share/vm/c1/c1_LIR.cpp b/src/share/vm/c1/c1_LIR.cpp index 60e25387a..46e725b5a 100644 --- a/src/share/vm/c1/c1_LIR.cpp +++ b/src/share/vm/c1/c1_LIR.cpp @@ -105,7 +105,7 @@ LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) { LIR_Address::Scale LIR_Address::scale(BasicType type) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); switch (elem_size) { case 1: return LIR_Address::times_1; case 2: return LIR_Address::times_2; diff --git a/src/share/vm/ci/ciField.hpp b/src/share/vm/ci/ciField.hpp index 2498007f5..72a64c03a 100644 --- a/src/share/vm/ci/ciField.hpp +++ b/src/share/vm/ci/ciField.hpp @@ -102,7 +102,7 @@ public: BasicType layout_type() { return type2field[(_type == NULL) ? T_OBJECT : _type->basic_type()]; } // How big is this field in memory? - int size_in_bytes() { return type2aelembytes[layout_type()]; } + int size_in_bytes() { return type2aelembytes(layout_type()); } // What is the offset of this field? int offset() { diff --git a/src/share/vm/oops/arrayOop.hpp b/src/share/vm/oops/arrayOop.hpp index e9bde1d6c..49fc566a9 100644 --- a/src/share/vm/oops/arrayOop.hpp +++ b/src/share/vm/oops/arrayOop.hpp @@ -58,11 +58,11 @@ class arrayOopDesc : public oopDesc { // alignments. It gets the scale from the type2aelembytes array. static int32_t max_array_length(BasicType type) { assert(type >= 0 && type < T_CONFLICT, "wrong type"); - assert(type2aelembytes[type] != 0, "wrong type"); + assert(type2aelembytes(type) != 0, "wrong type"); // We use max_jint, since object_size is internally represented by an 'int' // This gives us an upper bound of max_jint words for the size of the oop. int32_t max_words = (max_jint - header_size(type) - 2); - int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes[type]; + int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type); jlong len = ((jlong)max_words * HeapWordSize) / elembytes; return (len > max_jint) ? max_jint : (int32_t)len; } diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp index c21393ce5..33e800a3c 100644 --- a/src/share/vm/oops/klass.cpp +++ b/src/share/vm/oops/klass.cpp @@ -182,7 +182,7 @@ jint Klass::array_layout_helper(BasicType etype) { assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype"); // Note that T_ARRAY is not allowed here. int hsize = arrayOopDesc::base_offset_in_bytes(etype); - int esize = type2aelembytes[etype]; + int esize = type2aelembytes(etype); bool isobj = (etype == T_OBJECT); int tag = isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value; int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize)); diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp index 642883ad6..45471f29f 100644 --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -1447,7 +1447,7 @@ Node* GraphKit::store_oop_to_unknown(Node* ctl, //-------------------------array_element_address------------------------- Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, const TypeInt* sizetype) { - uint shift = exact_log2(type2aelembytes[elembt]); + uint shift = exact_log2(type2aelembytes(elembt)); uint header = arrayOopDesc::base_offset_in_bytes(elembt); // short-circuit a common case (saves lots of confusing waste motion) diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index d78f62d40..e69e2d9e6 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -2097,7 +2097,7 @@ bool LibraryCallKit::inline_unsafe_CAS(BasicType type) { int type_words = type2size[type]; // Cannot inline wide CAS on machines that don't support it natively - if (type2aelembytes[type] > BytesPerInt && !VM_Version::supports_cx8()) + if (type2aelembytes(type) > BytesPerInt && !VM_Version::supports_cx8()) return false; C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". @@ -3975,7 +3975,7 @@ address LibraryCallKit::basictype2arraycopy(BasicType t, // both indices are constants int s_offs = src_offset_inttype->get_con(); int d_offs = dest_offset_inttype->get_con(); - int element_size = type2aelembytes[t]; + int element_size = type2aelembytes(t); aligned = ((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) && ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0); if (s_offs >= d_offs) disjoint = true; @@ -4389,7 +4389,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, if (alloc != NULL && use_ReduceInitialCardMarks()) { // If we do not need card marks, copy using the jint or jlong stub. copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT); - assert(type2aelembytes[basic_elem_type] == type2aelembytes[copy_type], + assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), "sizes agree"); } } @@ -4659,7 +4659,7 @@ LibraryCallKit::generate_clear_array(const TypePtr* adr_type, Node* mem = memory(adr_type); // memory slice to operate on // scaling and rounding of indexes: - int scale = exact_log2(type2aelembytes[basic_elem_type]); + int scale = exact_log2(type2aelembytes(basic_elem_type)); int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); int clear_low = (-1 << scale) & (BytesPerInt - 1); int bump_bit = (-1 << scale) & BytesPerInt; @@ -4753,7 +4753,7 @@ LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, Node* dest, Node* dest_offset, Node* dest_size) { // See if there is an advantage from block transfer. - int scale = exact_log2(type2aelembytes[basic_elem_type]); + int scale = exact_log2(type2aelembytes(basic_elem_type)); if (scale >= LogBytesPerLong) return false; // it is already a block transfer diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp index b65a03bbf..28f37d9a8 100644 --- a/src/share/vm/opto/memnode.cpp +++ b/src/share/vm/opto/memnode.cpp @@ -889,7 +889,7 @@ Node* LoadNode::eliminate_autobox(PhaseGVN* phase) { int shift = -1; Node* cache = NULL; if (is_autobox_cache(atp)) { - shift = exact_log2(type2aelembytes[T_OBJECT]); + shift = exact_log2(type2aelembytes(T_OBJECT)); cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset); } if (cache != NULL && base->in(Address)->is_AddP()) { diff --git a/src/share/vm/opto/memnode.hpp b/src/share/vm/opto/memnode.hpp index 34f36a271..505cbdf97 100644 --- a/src/share/vm/opto/memnode.hpp +++ b/src/share/vm/opto/memnode.hpp @@ -97,7 +97,13 @@ public: // What is the type of the value in memory? (T_VOID mean "unspecified".) virtual BasicType memory_type() const = 0; - virtual int memory_size() const { return type2aelembytes[memory_type()]; } + virtual int memory_size() const { +#ifdef ASSERT + return type2aelembytes(memory_type(), true); +#else + return type2aelembytes(memory_type()); +#endif + } // Search through memory states which precede this node (load or store). // Look for an exact match for the address, with no intervening diff --git a/src/share/vm/opto/superword.cpp b/src/share/vm/opto/superword.cpp index b1467fc9e..9b9ffdd02 100644 --- a/src/share/vm/opto/superword.cpp +++ b/src/share/vm/opto/superword.cpp @@ -159,7 +159,8 @@ void SuperWord::find_adjacent_refs() { Node_List memops; for (int i = 0; i < _block.length(); i++) { Node* n = _block.at(i); - if (n->is_Mem() && in_bb(n)) { + if (n->is_Mem() && in_bb(n) && + is_java_primitive(n->as_Mem()->memory_type())) { int align = memory_alignment(n->as_Mem(), 0); if (align != bottom_align) { memops.push(n); @@ -570,7 +571,7 @@ void SuperWord::set_alignment(Node* s1, Node* s2, int align) { int SuperWord::data_size(Node* s) { const Type* t = velt_type(s); BasicType bt = t->array_element_basic_type(); - int bsize = type2aelembytes[bt]; + int bsize = type2aelembytes(bt); assert(bsize != 0, "valid size"); return bsize; } diff --git a/src/share/vm/opto/vectornode.cpp b/src/share/vm/opto/vectornode.cpp index f13751605..7a581282d 100644 --- a/src/share/vm/opto/vectornode.cpp +++ b/src/share/vm/opto/vectornode.cpp @@ -135,7 +135,7 @@ Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) { int mid = lo + ct/2; Node* n1 = ct == 2 ? in(lo) : binaryTreePack(C, lo, mid); Node* n2 = ct == 2 ? in(lo+1) : binaryTreePack(C, mid, hi ); - int rslt_bsize = ct * type2aelembytes[elt_basic_type()]; + int rslt_bsize = ct * type2aelembytes(elt_basic_type()); if (bottom_type()->is_floatingpoint()) { switch (rslt_bsize) { case 8: return new (C, 3) PackFNode(n1, n2); diff --git a/src/share/vm/opto/vectornode.hpp b/src/share/vm/opto/vectornode.hpp index c06386777..ed442b973 100644 --- a/src/share/vm/opto/vectornode.hpp +++ b/src/share/vm/opto/vectornode.hpp @@ -48,7 +48,7 @@ class VectorNode : public Node { uint length() const { return _length; } // Vector length static uint max_vlen(BasicType bt) { // max vector length - return (uint)(Matcher::vector_width_in_bytes() / type2aelembytes[bt]); + return (uint)(Matcher::vector_width_in_bytes() / type2aelembytes(bt)); } // Element and vector type @@ -392,7 +392,7 @@ class VectorLoadNode : public LoadNode { virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(); } virtual BasicType memory_type() const { return T_VOID; } - virtual int memory_size() const { return length()*type2aelembytes[elt_basic_type()]; } + virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); } // Vector opcode from scalar opcode static int opcode(int sopc, uint vlen); @@ -620,7 +620,7 @@ class VectorStoreNode : public StoreNode { virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(); } virtual BasicType memory_type() const { return T_VOID; } - virtual int memory_size() const { return length()*type2aelembytes[elt_basic_type()]; } + virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); } // Vector opcode from scalar opcode static int opcode(int sopc, uint vlen); diff --git a/src/share/vm/services/heapDumper.cpp b/src/share/vm/services/heapDumper.cpp index cdd79a618..afb7d9cbb 100644 --- a/src/share/vm/services/heapDumper.cpp +++ b/src/share/vm/services/heapDumper.cpp @@ -997,7 +997,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) { } // If the byte ordering is big endian then we can copy most types directly - int length_in_bytes = array->length() * type2aelembytes[type]; + int length_in_bytes = array->length() * type2aelembytes(type); assert(length_in_bytes > 0, "nothing to copy"); switch (type) { diff --git a/src/share/vm/utilities/globalDefinitions.cpp b/src/share/vm/utilities/globalDefinitions.cpp index 12edbeff7..89373ef28 100644 --- a/src/share/vm/utilities/globalDefinitions.cpp +++ b/src/share/vm/utilities/globalDefinitions.cpp @@ -214,7 +214,7 @@ BasicType type2wfield[T_CONFLICT+1] = { }; -int type2aelembytes[T_CONFLICT+1] = { +int _type2aelembytes[T_CONFLICT+1] = { 0, // 0 0, // 1 0, // 2 @@ -230,10 +230,16 @@ int type2aelembytes[T_CONFLICT+1] = { T_OBJECT_aelem_bytes, // T_OBJECT = 12, T_ARRAY_aelem_bytes, // T_ARRAY = 13, 0, // T_VOID = 14, - T_INT_aelem_bytes, // T_ADDRESS = 15, + T_OBJECT_aelem_bytes, // T_ADDRESS = 15, 0 // T_CONFLICT = 16, }; +#ifdef ASSERT +int type2aelembytes(BasicType t, bool allow_address) { + assert(allow_address || t != T_ADDRESS, " "); + return _type2aelembytes[t]; +} +#endif // Support for 64-bit integer arithmetic diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp index 460cd1f34..0feceb5de 100644 --- a/src/share/vm/utilities/globalDefinitions.hpp +++ b/src/share/vm/utilities/globalDefinitions.hpp @@ -392,6 +392,10 @@ enum BasicType { T_ILLEGAL = 99 }; +inline bool is_java_primitive(BasicType t) { + return T_BOOLEAN <= t && t <= T_LONG; +} + // Convert a char from a classfile signature to a BasicType inline BasicType char2type(char c) { switch( c ) { @@ -464,7 +468,12 @@ enum ArrayElementSize { T_VOID_aelem_bytes = 0 }; -extern int type2aelembytes[T_CONFLICT+1]; // maps a BasicType to nof bytes used by its array element +extern int _type2aelembytes[T_CONFLICT+1]; // maps a BasicType to nof bytes used by its array element +#ifdef ASSERT +extern int type2aelembytes(BasicType t, bool allow_address = false); // asserts +#else +inline int type2aelembytes(BasicType t) { return _type2aelembytes[t]; } +#endif // JavaValue serves as a container for arbitrary Java values. -- GitLab