duke@435: /* coleenp@4037: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "runtime/os.hpp" stefank@2314: #include "utilities/globalDefinitions.hpp" stefank@2314: #include "utilities/top.hpp" stefank@2314: coleenp@548: // Basic error support duke@435: coleenp@548: // Info for oops within a java object. Defaults are zero so coleenp@548: // things will break badly if incorrectly initialized. coleenp@548: int heapOopSize = 0; coleenp@548: int LogBytesPerHeapOop = 0; coleenp@548: int LogBitsPerHeapOop = 0; coleenp@548: int BytesPerHeapOop = 0; coleenp@548: int BitsPerHeapOop = 0; duke@435: kvn@1926: // Object alignment, in units of HeapWords. kvn@1926: // Defaults are -1 so things will break badly if incorrectly initialized. kvn@1926: int MinObjAlignment = -1; kvn@1926: int MinObjAlignmentInBytes = -1; kvn@1926: int MinObjAlignmentInBytesMask = 0; kvn@1926: kvn@1926: int LogMinObjAlignment = -1; kvn@1926: int LogMinObjAlignmentInBytes = -1; kvn@1926: kvn@1926: // Oop encoding heap max kvn@1926: uint64_t OopEncodingHeapMax = 0; kvn@1926: duke@435: void basic_fatal(const char* msg) { duke@435: fatal(msg); duke@435: } duke@435: duke@435: // Something to help porters sleep at night duke@435: coleenp@548: void basic_types_init() { duke@435: #ifdef ASSERT duke@435: #ifdef _LP64 duke@435: assert(min_intx == (intx)CONST64(0x8000000000000000), "correct constant"); duke@435: assert(max_intx == CONST64(0x7FFFFFFFFFFFFFFF), "correct constant"); duke@435: assert(max_uintx == CONST64(0xFFFFFFFFFFFFFFFF), "correct constant"); duke@435: assert( 8 == sizeof( intx), "wrong size for basic type"); duke@435: assert( 8 == sizeof( jobject), "wrong size for basic type"); duke@435: #else duke@435: assert(min_intx == (intx)0x80000000, "correct constant"); duke@435: assert(max_intx == 0x7FFFFFFF, "correct constant"); duke@435: assert(max_uintx == 0xFFFFFFFF, "correct constant"); duke@435: assert( 4 == sizeof( intx), "wrong size for basic type"); duke@435: assert( 4 == sizeof( jobject), "wrong size for basic type"); duke@435: #endif duke@435: assert( (~max_juint) == 0, "max_juint has all its bits"); duke@435: assert( (~max_uintx) == 0, "max_uintx has all its bits"); duke@435: assert( (~max_julong) == 0, "max_julong has all its bits"); duke@435: assert( 1 == sizeof( jbyte), "wrong size for basic type"); duke@435: assert( 2 == sizeof( jchar), "wrong size for basic type"); duke@435: assert( 2 == sizeof( jshort), "wrong size for basic type"); duke@435: assert( 4 == sizeof( juint), "wrong size for basic type"); duke@435: assert( 4 == sizeof( jint), "wrong size for basic type"); duke@435: assert( 1 == sizeof( jboolean), "wrong size for basic type"); duke@435: assert( 8 == sizeof( jlong), "wrong size for basic type"); duke@435: assert( 4 == sizeof( jfloat), "wrong size for basic type"); duke@435: assert( 8 == sizeof( jdouble), "wrong size for basic type"); duke@435: assert( 1 == sizeof( u1), "wrong size for basic type"); duke@435: assert( 2 == sizeof( u2), "wrong size for basic type"); duke@435: assert( 4 == sizeof( u4), "wrong size for basic type"); duke@435: duke@435: int num_type_chars = 0; duke@435: for (int i = 0; i < 99; i++) { duke@435: if (type2char((BasicType)i) != 0) { duke@435: assert(char2type(type2char((BasicType)i)) == i, "proper inverses"); duke@435: num_type_chars++; duke@435: } duke@435: } duke@435: assert(num_type_chars == 11, "must have tested the right number of mappings"); duke@435: assert(char2type(0) == T_ILLEGAL, "correct illegality"); duke@435: duke@435: { duke@435: for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) { duke@435: BasicType vt = (BasicType)i; duke@435: BasicType ft = type2field[vt]; duke@435: switch (vt) { duke@435: // the following types might plausibly show up in memory layouts: duke@435: case T_BOOLEAN: duke@435: case T_BYTE: duke@435: case T_CHAR: duke@435: case T_SHORT: duke@435: case T_INT: duke@435: case T_FLOAT: duke@435: case T_DOUBLE: duke@435: case T_LONG: duke@435: case T_OBJECT: roland@4159: case T_ADDRESS: // random raw pointer roland@4159: case T_METADATA: // metadata pointer roland@4159: case T_NARROWOOP: // compressed pointer roland@4159: case T_NARROWKLASS: // compressed klass pointer roland@4159: case T_CONFLICT: // might as well support a bottom type roland@4159: case T_VOID: // padding or other unaddressed word duke@435: // layout type must map to itself duke@435: assert(vt == ft, ""); duke@435: break; duke@435: default: duke@435: // non-layout type must map to a (different) layout type duke@435: assert(vt != ft, ""); duke@435: assert(ft == type2field[ft], ""); duke@435: } duke@435: // every type must map to same-sized layout type: duke@435: assert(type2size[vt] == type2size[ft], ""); duke@435: } duke@435: } duke@435: // These are assumed, e.g., when filling HeapWords with juints. duke@435: assert(is_power_of_2(sizeof(juint)), "juint must be power of 2"); duke@435: assert(is_power_of_2(HeapWordSize), "HeapWordSize must be power of 2"); duke@435: assert((size_t)HeapWordSize >= sizeof(juint), duke@435: "HeapWord should be at least as large as juint"); duke@435: assert(sizeof(NULL) == sizeof(char*), "NULL must be same size as pointer"); duke@435: #endif duke@435: duke@435: if( JavaPriority1_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[1] = JavaPriority1_To_OSPriority; duke@435: if( JavaPriority2_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[2] = JavaPriority2_To_OSPriority; duke@435: if( JavaPriority3_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[3] = JavaPriority3_To_OSPriority; duke@435: if( JavaPriority4_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[4] = JavaPriority4_To_OSPriority; duke@435: if( JavaPriority5_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[5] = JavaPriority5_To_OSPriority; duke@435: if( JavaPriority6_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[6] = JavaPriority6_To_OSPriority; duke@435: if( JavaPriority7_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[7] = JavaPriority7_To_OSPriority; duke@435: if( JavaPriority8_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[8] = JavaPriority8_To_OSPriority; duke@435: if( JavaPriority9_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[9] = JavaPriority9_To_OSPriority; duke@435: if(JavaPriority10_To_OSPriority != -1 ) duke@435: os::java_to_os_priority[10] = JavaPriority10_To_OSPriority; coleenp@548: coleenp@548: // Set the size of basic types here (after argument parsing but before coleenp@548: // stub generation). coleenp@548: if (UseCompressedOops) { coleenp@548: // Size info for oops within java objects is fixed coleenp@548: heapOopSize = jintSize; coleenp@548: LogBytesPerHeapOop = LogBytesPerInt; coleenp@548: LogBitsPerHeapOop = LogBitsPerInt; coleenp@548: BytesPerHeapOop = BytesPerInt; coleenp@548: BitsPerHeapOop = BitsPerInt; coleenp@548: } else { coleenp@548: heapOopSize = oopSize; coleenp@548: LogBytesPerHeapOop = LogBytesPerWord; coleenp@548: LogBitsPerHeapOop = LogBitsPerWord; coleenp@548: BytesPerHeapOop = BytesPerWord; coleenp@548: BitsPerHeapOop = BitsPerWord; coleenp@548: } coleenp@548: _type2aelembytes[T_OBJECT] = heapOopSize; coleenp@548: _type2aelembytes[T_ARRAY] = heapOopSize; duke@435: } duke@435: duke@435: duke@435: // Map BasicType to signature character roland@4159: char type2char_tab[T_CONFLICT+1]={ 0, 0, 0, 0, 'Z', 'C', 'F', 'D', 'B', 'S', 'I', 'J', 'L', '[', 'V', 0, 0, 0, 0, 0}; duke@435: duke@435: // Map BasicType to Java type name duke@435: const char* type2name_tab[T_CONFLICT+1] = { duke@435: NULL, NULL, NULL, NULL, duke@435: "boolean", duke@435: "char", duke@435: "float", duke@435: "double", duke@435: "byte", duke@435: "short", duke@435: "int", duke@435: "long", duke@435: "object", duke@435: "array", duke@435: "void", duke@435: "*address*", coleenp@548: "*narrowoop*", coleenp@4037: "*metadata*", roland@4159: "*narrowklass*", duke@435: "*conflict*" duke@435: }; duke@435: duke@435: duke@435: BasicType name2type(const char* name) { duke@435: for (int i = T_BOOLEAN; i <= T_VOID; i++) { duke@435: BasicType t = (BasicType)i; duke@435: if (type2name_tab[t] != NULL && 0 == strcmp(type2name_tab[t], name)) duke@435: return t; duke@435: } duke@435: return T_ILLEGAL; duke@435: } duke@435: duke@435: duke@435: // Map BasicType to size in words roland@4159: int type2size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1, 1, -1}; duke@435: duke@435: BasicType type2field[T_CONFLICT+1] = { duke@435: (BasicType)0, // 0, duke@435: (BasicType)0, // 1, duke@435: (BasicType)0, // 2, duke@435: (BasicType)0, // 3, duke@435: T_BOOLEAN, // T_BOOLEAN = 4, duke@435: T_CHAR, // T_CHAR = 5, duke@435: T_FLOAT, // T_FLOAT = 6, duke@435: T_DOUBLE, // T_DOUBLE = 7, duke@435: T_BYTE, // T_BYTE = 8, duke@435: T_SHORT, // T_SHORT = 9, duke@435: T_INT, // T_INT = 10, duke@435: T_LONG, // T_LONG = 11, duke@435: T_OBJECT, // T_OBJECT = 12, duke@435: T_OBJECT, // T_ARRAY = 13, duke@435: T_VOID, // T_VOID = 14, duke@435: T_ADDRESS, // T_ADDRESS = 15, coleenp@548: T_NARROWOOP, // T_NARROWOOP= 16, coleenp@4037: T_METADATA, // T_METADATA = 17, roland@4159: T_NARROWKLASS, // T_NARROWKLASS = 18, roland@4159: T_CONFLICT // T_CONFLICT = 19, duke@435: }; duke@435: duke@435: duke@435: BasicType type2wfield[T_CONFLICT+1] = { duke@435: (BasicType)0, // 0, duke@435: (BasicType)0, // 1, duke@435: (BasicType)0, // 2, duke@435: (BasicType)0, // 3, duke@435: T_INT, // T_BOOLEAN = 4, duke@435: T_INT, // T_CHAR = 5, duke@435: T_FLOAT, // T_FLOAT = 6, duke@435: T_DOUBLE, // T_DOUBLE = 7, duke@435: T_INT, // T_BYTE = 8, duke@435: T_INT, // T_SHORT = 9, duke@435: T_INT, // T_INT = 10, duke@435: T_LONG, // T_LONG = 11, duke@435: T_OBJECT, // T_OBJECT = 12, duke@435: T_OBJECT, // T_ARRAY = 13, duke@435: T_VOID, // T_VOID = 14, duke@435: T_ADDRESS, // T_ADDRESS = 15, coleenp@548: T_NARROWOOP, // T_NARROWOOP = 16, coleenp@4037: T_METADATA, // T_METADATA = 17, roland@4159: T_NARROWKLASS, // T_NARROWKLASS = 18, roland@4159: T_CONFLICT // T_CONFLICT = 19, duke@435: }; duke@435: duke@435: kvn@464: int _type2aelembytes[T_CONFLICT+1] = { roland@4159: 0, // 0 roland@4159: 0, // 1 roland@4159: 0, // 2 roland@4159: 0, // 3 roland@4159: T_BOOLEAN_aelem_bytes, // T_BOOLEAN = 4, roland@4159: T_CHAR_aelem_bytes, // T_CHAR = 5, roland@4159: T_FLOAT_aelem_bytes, // T_FLOAT = 6, roland@4159: T_DOUBLE_aelem_bytes, // T_DOUBLE = 7, roland@4159: T_BYTE_aelem_bytes, // T_BYTE = 8, roland@4159: T_SHORT_aelem_bytes, // T_SHORT = 9, roland@4159: T_INT_aelem_bytes, // T_INT = 10, roland@4159: T_LONG_aelem_bytes, // T_LONG = 11, roland@4159: T_OBJECT_aelem_bytes, // T_OBJECT = 12, roland@4159: T_ARRAY_aelem_bytes, // T_ARRAY = 13, roland@4159: 0, // T_VOID = 14, roland@4159: T_OBJECT_aelem_bytes, // T_ADDRESS = 15, roland@4159: T_NARROWOOP_aelem_bytes, // T_NARROWOOP= 16, roland@4159: T_OBJECT_aelem_bytes, // T_METADATA = 17, roland@4159: T_NARROWKLASS_aelem_bytes, // T_NARROWKLASS= 18, roland@4159: 0 // T_CONFLICT = 19, duke@435: }; duke@435: kvn@464: #ifdef ASSERT kvn@464: int type2aelembytes(BasicType t, bool allow_address) { kvn@464: assert(allow_address || t != T_ADDRESS, " "); kvn@464: return _type2aelembytes[t]; kvn@464: } kvn@464: #endif duke@435: duke@435: // Support for 64-bit integer arithmetic duke@435: duke@435: // The following code is mostly taken from JVM typedefs_md.h and system_md.c duke@435: coleenp@548: static const jlong high_bit = (jlong)1 << (jlong)63; duke@435: static const jlong other_bits = ~high_bit; duke@435: duke@435: jlong float2long(jfloat f) { duke@435: jlong tmp = (jlong) f; duke@435: if (tmp != high_bit) { duke@435: return tmp; duke@435: } else { duke@435: if (g_isnan((jdouble)f)) { duke@435: return 0; duke@435: } duke@435: if (f < 0) { duke@435: return high_bit; duke@435: } else { duke@435: return other_bits; duke@435: } duke@435: } duke@435: } duke@435: duke@435: duke@435: jlong double2long(jdouble f) { duke@435: jlong tmp = (jlong) f; duke@435: if (tmp != high_bit) { duke@435: return tmp; duke@435: } else { duke@435: if (g_isnan(f)) { duke@435: return 0; duke@435: } duke@435: if (f < 0) { duke@435: return high_bit; duke@435: } else { duke@435: return other_bits; duke@435: } duke@435: } duke@435: } duke@435: duke@435: // least common multiple duke@435: size_t lcm(size_t a, size_t b) { duke@435: size_t cur, div, next; duke@435: duke@435: cur = MAX2(a, b); duke@435: div = MIN2(a, b); duke@435: duke@435: assert(div != 0, "lcm requires positive arguments"); duke@435: duke@435: duke@435: while ((next = cur % div) != 0) { duke@435: cur = div; div = next; duke@435: } duke@435: duke@435: duke@435: julong result = julong(a) * b / div; duke@435: assert(result <= (size_t)max_uintx, "Integer overflow in lcm"); duke@435: duke@435: return size_t(result); duke@435: } mikael@4889: mikael@4889: #ifndef PRODUCT mikael@4889: mikael@4889: void GlobalDefinitions::test_globals() { mikael@4889: intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 }; mikael@4889: const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]); mikael@4889: mikael@4889: for (int i = 0; i < num_page_sizes; i++) { mikael@4889: intptr_t page_size = page_sizes[i]; mikael@4889: mikael@4889: address a_page = (address)(10*page_size); mikael@4889: mikael@4889: // Check that address within page is returned as is mikael@4889: assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect"); mikael@4889: mikael@4889: // Check that address above page returns start of next page mikael@4889: assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect"); mikael@4889: mikael@4889: // Check that address below page returns start of page mikael@4889: assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect"); mikael@4889: assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect"); mikael@4889: } mikael@4889: } mikael@4889: mikael@4889: #endif // PRODUCT