#ifdef ASSERT
int type2aelembytes(BasicType t, bool allow_address) {
assert(allow_address || t != T_ADDRESS, " ");
return _type2aelembytes[t];
}
#endif
static const jlong high_bit = (jlong)1 << (jlong)63;
static const jlong other_bits = ~high_bit;
jlong float2long(jfloat f) {
jlong tmp = (jlong) f;
if (tmp != high_bit) {
return tmp;
} else {
if (g_isnan((jdouble)f)) {
return 0;
}
if (f < 0) {
return high_bit;
} else {
return other_bits;
}
}
}
jlong double2long(jdouble f) {
jlong tmp = (jlong) f;
if (tmp != high_bit) {
return tmp;
} else {
if (g_isnan(f)) {
return 0;
}
if (f < 0) {
return high_bit;
} else {
return other_bits;
}
}
}
size_t lcm(size_t a, size_t b) {
size_t cur, div, next;
cur = MAX2(a, b);
div = MIN2(a, b);
assert(div != 0, "lcm requires positive arguments");
while ((next = cur % div) != 0) {
cur = div; div = next;
}
julong result = julong(a) * b / div;
assert(result <= (size_t)max_uintx, "Integer overflow in lcm");
return size_t(result);
}
#ifndef PRODUCT
void GlobalDefinitions::test_globals() {
intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
for (int i = 0; i < num_page_sizes; i++) {
intptr_t page_size = page_sizes[i];
address a_page = (address)(10*page_size);
assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
}
}
#define EXPECT_EQ(expected, actual) \
assert(expected == actual, "Test failed");
#define EXPECT_STREQ(expected, actual) \
assert(strcmp(expected, actual) == 0, "Test failed");
void GlobalDefinitions::test_proper_unit() {
EXPECT_EQ(0u, byte_size_in_proper_unit(0u));
EXPECT_STREQ("B", proper_unit_for_byte_size(0u));
EXPECT_EQ(1u, byte_size_in_proper_unit(1u));
EXPECT_STREQ("B", proper_unit_for_byte_size(1u));
EXPECT_EQ(1023u, byte_size_in_proper_unit(K - 1));
EXPECT_STREQ("B", proper_unit_for_byte_size(K - 1));
EXPECT_EQ(1024u, byte_size_in_proper_unit(K));
EXPECT_STREQ("B", proper_unit_for_byte_size(K));
EXPECT_EQ(1025u, byte_size_in_proper_unit(K + 1));
EXPECT_STREQ("B", proper_unit_for_byte_size(K + 1));
EXPECT_EQ(51200u, byte_size_in_proper_unit(50*K));
EXPECT_STREQ("B", proper_unit_for_byte_size(50*K));
EXPECT_EQ(1023u, byte_size_in_proper_unit(M - 1));
EXPECT_STREQ("K", proper_unit_for_byte_size(M - 1));
EXPECT_EQ(1024u, byte_size_in_proper_unit(M));
EXPECT_STREQ("K", proper_unit_for_byte_size(M));
EXPECT_EQ(1024u, byte_size_in_proper_unit(M + 1));
EXPECT_STREQ("K", proper_unit_for_byte_size(M + 1));
EXPECT_EQ(1025u, byte_size_in_proper_unit(M + K));
EXPECT_STREQ("K", proper_unit_for_byte_size(M + K));
EXPECT_EQ(51200u, byte_size_in_proper_unit(50*M));
EXPECT_STREQ("K", proper_unit_for_byte_size(50*M));
#ifdef _LP64
EXPECT_EQ(1023u, byte_size_in_proper_unit(G - 1));
EXPECT_STREQ("M", proper_unit_for_byte_size(G - 1));
EXPECT_EQ(1024u, byte_size_in_proper_unit(G));
EXPECT_STREQ("M", proper_unit_for_byte_size(G));
EXPECT_EQ(1024u, byte_size_in_proper_unit(G + 1));
EXPECT_STREQ("M", proper_unit_for_byte_size(G + 1));
EXPECT_EQ(1024u, byte_size_in_proper_unit(G + K));
EXPECT_STREQ("M", proper_unit_for_byte_size(G + K));
EXPECT_EQ(1025u, byte_size_in_proper_unit(G + M));
EXPECT_STREQ("M", proper_unit_for_byte_size(G + M));
EXPECT_EQ(51200u, byte_size_in_proper_unit(50*G));
EXPECT_STREQ("M", proper_unit_for_byte_size(50*G));
#endif
}
#undef EXPECT_EQ
#undef EXPECT_STREQ
#endif // PRODUCT
C:\hotspot-69087d08d473\src\share\vm/utilities/globalDefinitions.hpp
#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#ifdef TARGET_COMPILER_gcc
# include "utilities/globalDefinitions_gcc.hpp"
#endif
#ifdef TARGET_COMPILER_visCPP
# include "utilities/globalDefinitions_visCPP.hpp"
#endif
#ifdef TARGET_COMPILER_sparcWorks
# include "utilities/globalDefinitions_sparcWorks.hpp"
#endif
#ifdef TARGET_COMPILER_xlc
# include "utilities/globalDefinitions_xlc.hpp"
#endif
#ifndef NOINLINE
#define NOINLINE
#endif
#ifndef ALWAYSINLINE
#define ALWAYSINLINE inline
#endif
#ifndef PRAGMA_DIAG_PUSH
#define PRAGMA_DIAG_PUSH
#endif
#ifndef PRAGMA_DIAG_POP
#define PRAGMA_DIAG_POP
#endif
#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED
#define PRAGMA_FORMAT_NONLITERAL_IGNORED
#endif
#ifndef PRAGMA_FORMAT_IGNORED
#define PRAGMA_FORMAT_IGNORED
#endif
#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
#endif
#ifndef PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
#endif
#ifndef PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#endif
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(fmt, vargs)
#endif
#include "utilities/macros.hpp"
const int LogBytesPerShort = 1;
const int LogBytesPerInt = 2;
#ifdef _LP64
const int LogBytesPerWord = 3;
#else
const int LogBytesPerWord = 2;
#endif
const int LogBytesPerLong = 3;
const int BytesPerShort = 1 << LogBytesPerShort;
const int BytesPerInt = 1 << LogBytesPerInt;
const int BytesPerWord = 1 << LogBytesPerWord;
const int BytesPerLong = 1 << LogBytesPerLong;
const int LogBitsPerByte = 3;
const int LogBitsPerShort = LogBitsPerByte + LogBytesPerShort;
const int LogBitsPerInt = LogBitsPerByte + LogBytesPerInt;
const int LogBitsPerWord = LogBitsPerByte + LogBytesPerWord;
const int LogBitsPerLong = LogBitsPerByte + LogBytesPerLong;
const int BitsPerByte = 1 << LogBitsPerByte;
const int BitsPerShort = 1 << LogBitsPerShort;
const int BitsPerInt = 1 << LogBitsPerInt;
const int BitsPerWord = 1 << LogBitsPerWord;
const int BitsPerLong = 1 << LogBitsPerLong;
const int WordAlignmentMask = (1 << LogBytesPerWord) - 1;
const int LongAlignmentMask = (1 << LogBytesPerLong) - 1;
const int WordsPerLong = 2; // Number of stack entries for longs
const int oopSize = sizeof(char*); // Full-width oop
extern int heapOopSize; // Oop within a java object
const int wordSize = sizeof(char*);
const int longSize = sizeof(jlong);
const int jintSize = sizeof(jint);
const int size_tSize = sizeof(size_t);
const int BytesPerOop = BytesPerWord; // Full-width oop
extern int LogBytesPerHeapOop; // Oop within a java object
extern int LogBitsPerHeapOop;
extern int BytesPerHeapOop;
extern int BitsPerHeapOop;
extern uint64_t OopEncodingHeapMax;
const int BitsPerJavaInteger = 32;
const int BitsPerJavaLong = 64;
const int BitsPerSize_t = size_tSize * BitsPerByte;
const int jintAsStringSize = 12;
#ifdef _LP64
const int SerializePageShiftCount = 4;
#else
const int SerializePageShiftCount = 3;
#endif
class HeapWord {
friend class VMStructs;
private:
char* i;
#ifndef PRODUCT
public:
char* value() { return i; }
#endif
};
class MetaWord {
friend class VMStructs;
private:
char* i;
};
const int HeapWordSize = sizeof(HeapWord);
#ifdef _LP64
const int LogHeapWordSize = 3;
#else
const int LogHeapWordSize = 2;
#endif
const int HeapWordsPerLong = BytesPerLong / HeapWordSize;
const int LogHeapWordsPerLong = LogBytesPerLong - LogHeapWordSize;
#ifdef _LP64
#define ScaleForWordSize(x) align_size_down_((x) * 13 / 10, HeapWordSize)
#else
#define ScaleForWordSize(x) (x)
#endif
inline size_t heap_word_size(size_t byte_size) {
return (byte_size + (HeapWordSize-1)) >> LogHeapWordSize;
}
const size_t K = 1024;
const size_t M = K*K;
const size_t G = M*K;
const size_t HWperKB = K / sizeof(HeapWord);
const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
const jint max_jint = (juint)min_jint - 1; // 0x7FFFFFFF == largest jint
const int MILLIUNITS = 1000; // milli units per base unit
const int MICROUNITS = 1000000; // micro units per base unit
const int NANOUNITS = 1000000000; // nano units per base unit
const jlong NANOSECS_PER_SEC = CONST64(1000000000);
const jint NANOSECS_PER_MILLISEC = 1000000;
inline const char* proper_unit_for_byte_size(size_t s) {
#ifdef _LP64
if (s >= 100*G) {
return "G";
}
#endif
if (s >= 100*M) {
return "M";
} else if (s >= 100*K) {
return "K";
} else {
return "B";
}
}
template <class T>
inline T byte_size_in_proper_unit(T s) {
#ifdef _LP64
if (s >= 100*G) {
return (T)(s/G);
}
#endif
if (s >= 100*M) {
return (T)(s/M);
} else if (s >= 100*K) {
return (T)(s/K);
} else {
return s;
}
}
typedef intptr_t intx;
typedef uintptr_t uintx;
const intx min_intx = (intx)1 << (sizeof(intx)*BitsPerByte-1);
const intx max_intx = (uintx)min_intx - 1;
const uintx max_uintx = (uintx)-1;
typedef unsigned int uint; NEEDS_CLEANUP
typedef signed char s_char;
typedef unsigned char u_char;
typedef u_char* address;
typedef uintptr_t address_word; // unsigned integer which will hold a pointer
inline address set_address_bits(address x, int m) { return address(intptr_t(x) | m); }
inline address clear_address_bits(address x, int m) { return address(intptr_t(x) & ~m); }
inline address_word mask_address_bits(address x, int m) { return address_word(x) & m; }
inline address_word castable_address(address x) { return address_word(x) ; }
inline address_word castable_address(void* x) { return address_word(x) ; }
inline size_t pointer_delta(const void* left,
const void* right,
size_t element_size) {
return (((uintptr_t) left) - ((uintptr_t) right)) / element_size;
}
inline size_t pointer_delta(const HeapWord* left, const HeapWord* right) {
return pointer_delta(left, right, sizeof(HeapWord));
}
inline size_t pointer_delta(const MetaWord* left, const MetaWord* right) {
return pointer_delta(left, right, sizeof(MetaWord));
}
#define CAST_TO_FN_PTR(func_type, value) (reinterpret_cast<func_type>(value))
#define CAST_FROM_FN_PTR(new_type, func_ptr) ((new_type)((address_word)(func_ptr)))
typedef jubyte u1;
typedef jushort u2;
typedef juint u4;
typedef julong u8;
const jubyte max_jubyte = (jubyte)-1; // 0xFF largest jubyte
const jushort max_jushort = (jushort)-1; // 0xFFFF largest jushort
const juint max_juint = (juint)-1; // 0xFFFFFFFF largest juint
const julong max_julong = (julong)-1; // 0xFF....FF largest julong
typedef jbyte s1;
typedef jshort s2;
typedef jint s4;
typedef jlong s8;
const int max_method_code_size = 64*K - 1; // JVM spec, 2nd ed. section 4.8.1 (p.134)
const int defaultProtectionDomainCacheSize = NOT_LP64(137) LP64_ONLY(2017);
const int defaultStringTableSize = NOT_LP64(1009) LP64_ONLY(60013);
const int minimumStringTableSize = 1009;
const int defaultSymbolTableSize = 20011;
const int minimumSymbolTableSize = 1009;
#define HOTSWAP
extern int MinObjAlignment;
extern int MinObjAlignmentInBytes;
extern int MinObjAlignmentInBytesMask;
extern int LogMinObjAlignment;
extern int LogMinObjAlignmentInBytes;
const int LogKlassAlignmentInBytes = 3;
const int LogKlassAlignment = LogKlassAlignmentInBytes - LogHeapWordSize;
const int KlassAlignmentInBytes = 1 << LogKlassAlignmentInBytes;
const int KlassAlignment = KlassAlignmentInBytes / HeapWordSize;
const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes;
#if defined(X86) && defined(COMPILER2) && !defined(JAVASE_EMBEDDED)
#define INCLUDE_RTM_OPT 1
#define RTM_OPT_ONLY(code) code
#else
#define INCLUDE_RTM_OPT 0
#define RTM_OPT_ONLY(code)
#endif
enum RTMState {
NoRTM = 0x2, // Don't use RTM
UseRTM = 0x1, // Use RTM
ProfileRTM = 0x0 // Use RTM with abort ratio calculation
};
#define CODE_CACHE_SIZE_LIMIT (2*G)
#define CODE_CACHE_DEFAULT_LIMIT CODE_CACHE_SIZE_LIMIT
#ifdef TARGET_ARCH_x86
# include "globalDefinitions_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "globalDefinitions_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "globalDefinitions_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "globalDefinitions_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "globalDefinitions_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "globalDefinitions_ppc.hpp"
#endif
#ifndef PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
#define PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1
#endif
#ifdef CPU_NOT_MULTIPLE_COPY_ATOMIC
const bool support_IRIW_for_not_multiple_copy_atomic_cpu = true;
#else
const bool support_IRIW_for_not_multiple_copy_atomic_cpu = false;
#endif
#define ARENA_AMALLOC_ALIGNMENT (2*BytesPerWord)
#define align_size_up_(size, alignment) (((size) + ((alignment) - 1)) & ~((alignment) - 1))
inline bool is_size_aligned(size_t size, size_t alignment) {
return align_size_up_(size, alignment) == size;
}
inline bool is_ptr_aligned(void* ptr, size_t alignment) {
return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr;
}
inline intptr_t align_size_up(intptr_t size, intptr_t alignment) {
return align_size_up_(size, alignment);
}
#define align_size_down_(size, alignment) ((size) & ~((alignment) - 1))
inline intptr_t align_size_down(intptr_t size, intptr_t alignment) {
return align_size_down_(size, alignment);
}
#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
inline void* align_ptr_up(void* ptr, size_t alignment) {
return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
}
inline void* align_ptr_down(void* ptr, size_t alignment) {
return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
}
#define align_object_size_(size) align_size_up_(size, MinObjAlignment)
inline intptr_t align_object_size(intptr_t size) {
return align_size_up(size, MinObjAlignment);
}
inline bool is_object_aligned(intptr_t addr) {
return addr == align_object_size(addr);
}
inline intptr_t align_object_offset(intptr_t offset) {
return align_size_up(offset, HeapWordsPerLong);
}
inline void* align_pointer_up(const void* addr, size_t size) {
return (void*) align_size_up_((uintptr_t)addr, size);
}
inline size_t align_size_down_bounded(size_t size, size_t alignment) {
size_t aligned_size = align_size_down_(size, alignment);
return aligned_size > 0 ? aligned_size : alignment;
}
inline address clamp_address_in_page(address addr, address page_address, intptr_t page_size) {
if (align_size_down(intptr_t(addr), page_size) == align_size_down(intptr_t(page_address), page_size)) {
return addr;
} else if (addr > page_address) {
return (address)align_size_down(intptr_t(page_address), page_size) + page_size;
} else {
return (address)align_size_down(intptr_t(page_address), page_size);
}
}
#define DEFAULT_CACHE_LINE_SIZE 64
#define Unused_Variable(var) var
inline double fabsd(double value) {
return fabs(value);
}
typedef union {
jfloat f;
jint i;
} FloatIntConv;
typedef union {
jdouble d;
jlong l;
julong ul;
} DoubleLongConv;
inline jint jint_cast (jfloat x) { return ((FloatIntConv*)&x)->i; }
inline jfloat jfloat_cast (jint x) { return ((FloatIntConv*)&x)->f; }
inline jlong jlong_cast (jdouble x) { return ((DoubleLongConv*)&x)->l; }
inline julong julong_cast (jdouble x) { return ((DoubleLongConv*)&x)->ul; }
inline jdouble jdouble_cast (jlong x) { return ((DoubleLongConv*)&x)->d; }
inline jint low (jlong value) { return jint(value); }
inline jint high(jlong value) { return jint(value >> 32); }
inline void set_low (jlong* value, jint low ) { *value &= (jlong)0xffffffff << 32;
inline void set_high(jlong* value, jint high) { *value &= (jlong)(julong)(juint)0xffffffff;
inline jlong jlong_from(jint h, jint l) {
jlong result = 0; // initialization to avoid warning
set_high(&result, h);
set_low(&result, l);
return result;
}
union jlong_accessor {
jint words[2];
jlong long_value;
};
void basic_types_init(); // cannot define here; uses assert
enum BasicType {
T_BOOLEAN = 4,
T_CHAR = 5,
T_FLOAT = 6,
T_DOUBLE = 7,
T_BYTE = 8,
T_SHORT = 9,
T_INT = 10,
T_LONG = 11,
T_OBJECT = 12,
T_ARRAY = 13,
T_VOID = 14,
T_ADDRESS = 15,
T_NARROWOOP = 16,
T_METADATA = 17,
T_NARROWKLASS = 18,
T_CONFLICT = 19, // for stack value type with conflicting contents
T_ILLEGAL = 99
};
inline bool is_java_primitive(BasicType t) {
return T_BOOLEAN <= t && t <= T_LONG;
}
inline bool is_subword_type(BasicType t) {
return (t == T_BOOLEAN || t == T_CHAR || t == T_BYTE || t == T_SHORT);
}
inline bool is_signed_subword_type(BasicType t) {
return (t == T_BYTE || t == T_SHORT);
}
inline bool is_reference_type(BasicType t) {
return (t == T_OBJECT || t == T_ARRAY);
}
inline BasicType char2type(char c) {
switch( c ) {
case 'B': return T_BYTE;
case 'C': return T_CHAR;
case 'D': return T_DOUBLE;
case 'F': return T_FLOAT;
case 'I': return T_INT;
case 'J': return T_LONG;
case 'S': return T_SHORT;
case 'Z': return T_BOOLEAN;
case 'V': return T_VOID;
case 'L': return T_OBJECT;
case '[': return T_ARRAY;
}
return T_ILLEGAL;
}
extern char type2char_tab[T_CONFLICT+1]; // Map a BasicType to a jchar
inline char type2char(BasicType t) { return (uint)t < T_CONFLICT+1 ? type2char_tab[t] : 0; }
extern int type2size[T_CONFLICT+1]; // Map BasicType to result stack elements
extern const char* type2name_tab[T_CONFLICT+1]; // Map a BasicType to a jchar
inline const char* type2name(BasicType t) { return (uint)t < T_CONFLICT+1 ? type2name_tab[t] : NULL; }
extern BasicType name2type(const char* name);
extern size_t lcm(size_t a, size_t b);
enum BasicTypeSize {
T_BOOLEAN_size = 1,
T_CHAR_size = 1,
T_FLOAT_size = 1,
T_DOUBLE_size = 2,
T_BYTE_size = 1,
T_SHORT_size = 1,
T_INT_size = 1,
T_LONG_size = 2,
T_OBJECT_size = 1,
T_ARRAY_size = 1,
T_NARROWOOP_size = 1,
T_NARROWKLASS_size = 1,
T_VOID_size = 0
};
extern BasicType type2field[T_CONFLICT+1];
extern BasicType type2wfield[T_CONFLICT+1];
enum ArrayElementSize {
T_BOOLEAN_aelem_bytes = 1,
T_CHAR_aelem_bytes = 2,
T_FLOAT_aelem_bytes = 4,
T_DOUBLE_aelem_bytes = 8,
T_BYTE_aelem_bytes = 1,
T_SHORT_aelem_bytes = 2,
T_INT_aelem_bytes = 4,
T_LONG_aelem_bytes = 8,
#ifdef _LP64
T_OBJECT_aelem_bytes = 8,
T_ARRAY_aelem_bytes = 8,
#else
T_OBJECT_aelem_bytes = 4,
T_ARRAY_aelem_bytes = 4,
#endif
T_NARROWOOP_aelem_bytes = 4,
T_NARROWKLASS_aelem_bytes = 4,
T_VOID_aelem_bytes = 0
};
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, bool allow_address = false) { return _type2aelembytes[t]; }
#endif
class JavaValue {
public:
typedef union JavaCallValue {
jfloat f;
jdouble d;
jint i;
jlong l;
jobject h;
} JavaCallValue;
private:
BasicType _type;
JavaCallValue _value;
public:
JavaValue(BasicType t = T_ILLEGAL) { _type = t; }
JavaValue(jfloat value) {
_type = T_FLOAT;
_value.f = value;
}
JavaValue(jdouble value) {
_type = T_DOUBLE;
_value.d = value;
}
jfloat get_jfloat() const { return _value.f; }
jdouble get_jdouble() const { return _value.d; }
jint get_jint() const { return _value.i; }
jlong get_jlong() const { return _value.l; }
jobject get_jobject() const { return _value.h; }
JavaCallValue* get_value_addr() { return &_value; }
BasicType get_type() const { return _type; }
void set_jfloat(jfloat f) { _value.f = f;}
void set_jdouble(jdouble d) { _value.d = d;}
void set_jint(jint i) { _value.i = i;}
void set_jlong(jlong l) { _value.l = l;}
void set_jobject(jobject h) { _value.h = h;}
void set_type(BasicType t) { _type = t; }
jboolean get_jboolean() const { return (jboolean) (_value.i);}
jbyte get_jbyte() const { return (jbyte) (_value.i);}
jchar get_jchar() const { return (jchar) (_value.i);}
jshort get_jshort() const { return (jshort) (_value.i);}
};
#define STACK_BIAS 0
#if defined(SPARC) && defined(_LP64)
#undef STACK_BIAS
#define STACK_BIAS 0x7ff
#endif
enum TosState { // describes the tos cache contents
btos = 0, // byte, bool tos cached
ztos = 1, // byte, bool tos cached
ctos = 2, // char tos cached
stos = 3, // short tos cached
itos = 4, // int tos cached
ltos = 5, // long tos cached
ftos = 6, // float tos cached
dtos = 7, // double tos cached
atos = 8, // object cached
vtos = 9, // tos not cached
number_of_states,
ilgl // illegal state: should not occur
};
inline TosState as_TosState(BasicType type) {
switch (type) {
case T_BYTE : return btos;
case T_BOOLEAN: return ztos;
case T_CHAR : return ctos;
case T_SHORT : return stos;
case T_INT : return itos;
case T_LONG : return ltos;
case T_FLOAT : return ftos;
case T_DOUBLE : return dtos;
case T_VOID : return vtos;
case T_ARRAY : // fall through
case T_OBJECT : return atos;
}
return ilgl;
}
inline BasicType as_BasicType(TosState state) {
switch (state) {
case btos : return T_BYTE;
case ztos : return T_BOOLEAN;
case ctos : return T_CHAR;
case stos : return T_SHORT;
case itos : return T_INT;
case ltos : return T_LONG;
case ftos : return T_FLOAT;
case dtos : return T_DOUBLE;
case atos : return T_OBJECT;
case vtos : return T_VOID;
}
return T_ILLEGAL;
}
TosState as_TosState(BasicType type);
enum JavaThreadState {
_thread_uninitialized = 0, // should never happen (missing initialization)
_thread_new = 2, // just starting up, i.e., in process of being initialized
_thread_new_trans = 3, // corresponding transition state (not used, included for completness)
_thread_in_native = 4, // running in native code
_thread_in_native_trans = 5, // corresponding transition state
_thread_in_vm = 6, // running in VM
_thread_in_vm_trans = 7, // corresponding transition state
_thread_in_Java = 8, // running in Java or in stub code
_thread_in_Java_trans = 9, // corresponding transition state (not used, included for completness)
_thread_blocked = 10, // blocked in vm
_thread_blocked_trans = 11, // corresponding transition state
_thread_max_state = 12 // maximum thread state+1 - used for statistics allocation
};
enum MethodCompilation {
InvocationEntryBci = -1, // i.e., not a on-stack replacement compilation
InvalidOSREntryBci = -2
};
enum CompLevel {
CompLevel_any = -1,
CompLevel_all = -1,
CompLevel_none = 0, // Interpreter
CompLevel_simple = 1, // C1
CompLevel_limited_profile = 2, // C1, invocation & backedge counters
CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo
CompLevel_full_optimization = 4, // C2 or Shark
#if defined(COMPILER2) || defined(SHARK)
CompLevel_highest_tier = CompLevel_full_optimization, // pure C2 and tiered
#elif defined(COMPILER1)
CompLevel_highest_tier = CompLevel_simple, // pure C1
#else
CompLevel_highest_tier = CompLevel_none,
#endif
#if defined(TIERED)
CompLevel_initial_compile = CompLevel_full_profile // tiered
#elif defined(COMPILER1)
CompLevel_initial_compile = CompLevel_simple // pure C1
#elif defined(COMPILER2) || defined(SHARK)
CompLevel_initial_compile = CompLevel_full_optimization // pure C2
#else
CompLevel_initial_compile = CompLevel_none
#endif
};
inline bool is_c1_compile(int comp_level) {
return comp_level > CompLevel_none && comp_level < CompLevel_full_optimization;
}
inline bool is_c2_compile(int comp_level) {
return comp_level == CompLevel_full_optimization;
}
inline bool is_highest_tier_compile(int comp_level) {
return comp_level == CompLevel_highest_tier;
}
inline bool is_compile(int comp_level) {
return is_c1_compile(comp_level) || is_c2_compile(comp_level);
}
class symbolTable;
class ClassFileStream;
class Event;
class Thread;
class VMThread;
class JavaThread;
class Threads;
class VM_Operation;
class VMOperationQueue;
class CodeBlob;
class nmethod;
class OSRAdapter;
class I2CAdapter;
class C2IAdapter;
class CompiledIC;
class relocInfo;
class ScopeDesc;
class PcDesc;
class Recompiler;
class Recompilee;
class RecompilationPolicy;
class RFrame;
class CompiledRFrame;
class InterpretedRFrame;
class frame;
class vframe;
class javaVFrame;
class interpretedVFrame;
class compiledVFrame;
class deoptimizedVFrame;
class externalVFrame;
class entryVFrame;
class RegisterMap;
class Mutex;
class Monitor;
class BasicLock;
class BasicObjectLock;
class PeriodicTask;
class JavaCallWrapper;
class oopDesc;
class metaDataOopDesc;
class NativeCall;
class zone;
class StubQueue;
class outputStream;
class ResourceArea;
class DebugInformationRecorder;
class ScopeValue;
class CompressedStream;
class DebugInfoReadStream;
class DebugInfoWriteStream;
class LocationValue;
class ConstantValue;
class IllegalValue;
class PrivilegedElement;
class MonitorArray;
class MonitorInfo;
class OffsetClosure;
class OopMapCache;
class InterpreterOopMap;
class OopMapCacheEntry;
class OSThread;
typedef int (*OSThreadStartFunc)(void*);
class Space;
class JavaValue;
class methodHandle;
class JavaCallArguments;
extern void basic_fatal(const char* msg);
const jint badInt = -3; // generic "bad int" value
const intptr_t badAddressVal = -2; // generic "bad address" value
const intptr_t badOopVal = -1; // generic "bad oop" value
const intptr_t badHeapOopVal = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC
const int badStackSegVal = 0xCA; // value used to zap stack segments
const int badHandleValue = 0xBC; // value used to zap vm handle area
const int badResourceValue = 0xAB; // value used to zap resource area
const int freeBlockPad = 0xBA; // value used to pad freed blocks.
const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks.
const intptr_t badJNIHandleVal = (intptr_t) CONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC
const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC
const int badCodeHeapNewVal= 0xCC; // value used to zap Code heap at allocation
const int badCodeHeapFreeVal = 0xDD; // value used to zap Code heap at deallocation
#define badAddress ((address)::badAddressVal)
#define badOop (cast_to_oop(::badOopVal))
#define badHeapWord (::badHeapWordVal)
#define badJNIHandle (cast_to_oop(::badJNIHandleVal))
#define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17))
const intptr_t AllBits = ~0; // all bits set in a word
const intptr_t NoBits = 0; // no bits set in a word
const jlong NoLongBits = 0; // no bits set in a long
const intptr_t OneBit = 1; // only right_most bit set in a word
#define nth_bit(n) (n >= BitsPerWord ? 0 : OneBit << (n))
#define right_n_bits(n) (nth_bit(n) - 1)
#define left_n_bits(n) (right_n_bits(n) << (n >= BitsPerWord ? 0 : (BitsPerWord - n)))
inline void set_bits (intptr_t& x, intptr_t m) { x |= m; }
inline void clear_bits (intptr_t& x, intptr_t m) { x &= ~m; }
inline intptr_t mask_bits (intptr_t x, intptr_t m) { return x & m; }
inline jlong mask_long_bits (jlong x, jlong m) { return x & m; }
inline bool mask_bits_are_true (intptr_t flags, intptr_t mask) { return (flags & mask) == mask; }
inline void set_nth_bit(intptr_t& x, int n) { set_bits (x, nth_bit(n)); }
inline void clear_nth_bit(intptr_t& x, int n) { clear_bits(x, nth_bit(n)); }
inline bool is_set_nth_bit(intptr_t x, int n) { return mask_bits (x, nth_bit(n)) != NoBits; }
inline intptr_t bitfield(intptr_t x, int start_bit_no, int field_length) {
return mask_bits(x >> start_bit_no, right_n_bits(field_length));
}
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#define max(a,b) Do_not_use_max_use_MAX2_instead
#define min(a,b) Do_not_use_min_use_MIN2_instead
template<class T> inline T MAX2(T a, T b) { return (a > b) ? a : b; }
template<class T> inline T MIN2(T a, T b) { return (a < b) ? a : b; }
template<class T> inline T MAX3(T a, T b, T c) { return MAX2(MAX2(a, b), c); }
template<class T> inline T MIN3(T a, T b, T c) { return MIN2(MIN2(a, b), c); }
template<class T> inline T MAX4(T a, T b, T c, T d) { return MAX2(MAX3(a, b, c), d); }
template<class T> inline T MIN4(T a, T b, T c, T d) { return MIN2(MIN3(a, b, c), d); }
template<class T> inline T ABS(T x) { return (x > 0) ? x : -x; }
inline bool is_power_of_2(intptr_t x) {
return ((x != NoBits) && (mask_bits(x, x - 1) == NoBits));
}
inline bool is_power_of_2_long(jlong x) {
return ((x != NoLongBits) && (mask_long_bits(x, x - 1) == NoLongBits));
}
inline int log2_intptr(uintptr_t x) {
int i = -1;
uintptr_t p = 1;
while (p != 0 && p <= x) {
i++; p *= 2;
}
return i;
}
inline int log2_long(julong x) {
int i = -1;
julong p = 1;
while (p != 0 && p <= x) {
i++; p *= 2;
}
return i;
}
inline int log2_intptr(intptr_t x) {
return log2_intptr((uintptr_t)x);
}
inline int log2_int(int x) {
return log2_intptr((uintptr_t)x);
}
inline int log2_jint(jint x) {
return log2_intptr((uintptr_t)x);
}
inline int log2_uint(uint x) {
return log2_intptr((uintptr_t)x);
}
inline int log2_jlong(jlong x) {
return log2_long((julong)x);
}
inline int exact_log2(intptr_t x) {
#ifdef ASSERT
if (!is_power_of_2(x)) basic_fatal("x must be a power of 2");
#endif
return log2_intptr(x);
}
inline int exact_log2_long(jlong x) {
#ifdef ASSERT
if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2");
#endif
return log2_long(x);
}
inline intptr_t round_to(intptr_t x, uintx s) {
#ifdef ASSERT
if (!is_power_of_2(s)) basic_fatal("s must be a power of 2");
#endif
const uintx m = s - 1;
return mask_bits(x + m, ~m);
}
inline intptr_t round_down(intptr_t x, uintx s) {
#ifdef ASSERT
if (!is_power_of_2(s)) basic_fatal("s must be a power of 2");
#endif
const uintx m = s - 1;
return mask_bits(x, ~m);
}
inline bool is_odd (intx x) { return x & 1; }
inline bool is_even(intx x) { return !is_odd(x); }
static inline unsigned int uabs(unsigned int n) {
union {
unsigned int result;
int value;
};
result = n;
if (value < 0) result = 0-result;
return result;
}
static inline julong uabs(julong n) {
union {
julong result;
jlong value;
};
result = n;
if (value < 0) result = 0-result;
return result;
}
static inline julong uabs(jlong n) { return uabs((julong)n); }
static inline unsigned int uabs(int n) { return uabs((unsigned int)n); }
inline intx byte_size(void* from, void* to) {
return (address)to - (address)from;
}
inline u8 build_u8_from( u1 c1, u1 c2, u1 c3, u1 c4, u1 c5, u1 c6, u1 c7, u1 c8 ) {
return (( u8(c1) << 56 ) & ( u8(0xff) << 56 ))
| (( u8(c2) << 48 ) & ( u8(0xff) << 48 ))
| (( u8(c3) << 40 ) & ( u8(0xff) << 40 ))
| (( u8(c4) << 32 ) & ( u8(0xff) << 32 ))
| (( u8(c5) << 24 ) & ( u8(0xff) << 24 ))
| (( u8(c6) << 16 ) & ( u8(0xff) << 16 ))
| (( u8(c7) << 8 ) & ( u8(0xff) << 8 ))
| (( u8(c8) << 0 ) & ( u8(0xff) << 0 ));
}
inline u4 build_u4_from( u1 c1, u1 c2, u1 c3, u1 c4 ) {
return (( u4(c1) << 24 ) & 0xff000000)
| (( u4(c2) << 16 ) & 0x00ff0000)
| (( u4(c3) << 8 ) & 0x0000ff00)
| (( u4(c4) << 0 ) & 0x000000ff);
}
inline u4 build_u4_from( u1* p ) {
return build_u4_from( p[0], p[1], p[2], p[3] );
}
inline u2 build_u2_from( u1 c1, u1 c2 ) {
return u2((( u2(c1) << 8 ) & 0xff00)
| (( u2(c2) << 0 ) & 0x00ff));
}
inline u2 build_u2_from( u1* p ) {
return build_u2_from( p[0], p[1] );
}
inline jfloat build_float_from( u1 c1, u1 c2, u1 c3, u1 c4 ) {
u4 u = build_u4_from( c1, c2, c3, c4 );
return *(jfloat*)&u;
}
inline jfloat build_float_from( u1* p ) {
u4 u = build_u4_from( p );
return *(jfloat*)&u;
}
inline jlong build_long_from( u1 c1, u1 c2, u1 c3, u1 c4, u1 c5, u1 c6, u1 c7, u1 c8 ) {
return (( jlong(c1) << 56 ) & ( jlong(0xff) << 56 ))
| (( jlong(c2) << 48 ) & ( jlong(0xff) << 48 ))
| (( jlong(c3) << 40 ) & ( jlong(0xff) << 40 ))
| (( jlong(c4) << 32 ) & ( jlong(0xff) << 32 ))
| (( jlong(c5) << 24 ) & ( jlong(0xff) << 24 ))
| (( jlong(c6) << 16 ) & ( jlong(0xff) << 16 ))
| (( jlong(c7) << 8 ) & ( jlong(0xff) << 8 ))
| (( jlong(c8) << 0 ) & ( jlong(0xff) << 0 ));
}
inline jlong build_long_from( u1* p ) {
return build_long_from( p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] );
}
inline jdouble build_double_from( u1 c1, u1 c2, u1 c3, u1 c4, u1 c5, u1 c6, u1 c7, u1 c8 ) {
jlong u = build_long_from( c1, c2, c3, c4, c5, c6, c7, c8 );
return *(jdouble*)&u;
}
inline jdouble build_double_from( u1* p ) {
jlong u = build_long_from( p );
return *(jdouble*)&u;
}
inline void explode_short_to( u2 x, u1& c1, u1& c2 ) {
c1 = u1(x >> 8);
c2 = u1(x);
}
inline void explode_short_to( u2 x, u1* p ) {
explode_short_to( x, p[0], p[1]);
}
inline void explode_int_to( u4 x, u1& c1, u1& c2, u1& c3, u1& c4 ) {
c1 = u1(x >> 24);
c2 = u1(x >> 16);
c3 = u1(x >> 8);
c4 = u1(x);
}
inline void explode_int_to( u4 x, u1* p ) {
explode_int_to( x, p[0], p[1], p[2], p[3]);
}
inline int extract_low_short_from_int(jint x) {
return x & 0xffff;
}
inline int extract_high_short_from_int(jint x) {
return (x >> 16) & 0xffff;
}
inline int build_int_from_shorts( jushort low, jushort high ) {
return ((int)((unsigned int)high << 16) | (unsigned int)low);
}
inline intptr_t p2i(const void * p) {
return (intptr_t) p;
}
#define BOOL_TO_STR(_b_) ((_b_) ? "true" : "false")
#define INT32_FORMAT "%" PRId32
#define UINT32_FORMAT "%" PRIu32
#define INT32_FORMAT_W(width) "%" #width PRId32
#define UINT32_FORMAT_W(width) "%" #width PRIu32
#define PTR32_FORMAT "0x%08" PRIx32
#define INT64_FORMAT "%" PRId64
#define UINT64_FORMAT "%" PRIu64
#define UINT64_FORMAT_X "%" PRIx64
#define INT64_FORMAT_W(width) "%" #width PRId64
#define UINT64_FORMAT_W(width) "%" #width PRIu64
#define PTR64_FORMAT "0x%016" PRIx64
#ifndef JLONG_FORMAT
#define JLONG_FORMAT INT64_FORMAT
#endif
#ifndef JULONG_FORMAT
#define JULONG_FORMAT UINT64_FORMAT
#endif
#ifdef _LP64
#define INTPTR_FORMAT "0x%016" PRIxPTR
#define PTR_FORMAT "0x%016" PRIxPTR
#else // !_LP64
#define INTPTR_FORMAT "0x%08" PRIxPTR
#define PTR_FORMAT "0x%08" PRIxPTR
#endif // _LP64
#define INTPTR_FORMAT_W(width) "%" #width PRIxPTR
#define SSIZE_FORMAT "%" PRIdPTR
#define SIZE_FORMAT "%" PRIuPTR
#define SIZE_FORMAT_HEX "0x%" PRIxPTR
#define SSIZE_FORMAT_W(width) "%" #width PRIdPTR
#define SIZE_FORMAT_W(width) "%" #width PRIuPTR
#define SIZE_FORMAT_HEX_W(width) "0x%" #width PRIxPTR
#define INTX_FORMAT "%" PRIdPTR
#define UINTX_FORMAT "%" PRIuPTR
#define INTX_FORMAT_W(width) "%" #width PRIdPTR
#define UINTX_FORMAT_W(width) "%" #width PRIuPTR
# ifdef ASSERT
# ifdef COMPILER2
# define ENABLE_ZAP_DEAD_LOCALS
#endif /* COMPILER2 */
# endif /* ASSERT */
#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
#define JAVA_INTEGER_OP(OP, NAME, TYPE, UNSIGNED_TYPE) \
inline TYPE NAME (TYPE in1, TYPE in2) { \
UNSIGNED_TYPE ures = static_cast<UNSIGNED_TYPE>(in1); \
ures OP ## = static_cast<UNSIGNED_TYPE>(in2); \
return reinterpret_cast<TYPE&>(ures); \
}
JAVA_INTEGER_OP(+, java_add, jint, juint)
JAVA_INTEGER_OP(-, java_subtract, jint, juint)
JAVA_INTEGER_OP(*, java_multiply, jint, juint)
JAVA_INTEGER_OP(+, java_add, jlong, julong)
JAVA_INTEGER_OP(-, java_subtract, jlong, julong)
JAVA_INTEGER_OP(*, java_multiply, jlong, julong)
#undef JAVA_INTEGER_OP
static inline void* dereference_vptr(const void* addr) {
return *(void**)addr;
}
#ifndef PRODUCT
class GlobalDefinitions {
public:
static void test_globals();
static void test_proper_unit();
};
#endif // PRODUCT
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/globalDefinitions_gcc.hpp
#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
#include "prims/jni.h"
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#ifdef SOLARIS
#include <ieeefp.h>
#endif // SOLARIS
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <pthread.h>
#ifdef SOLARIS
#include <thread.h>
#endif // SOLARIS
#include <limits.h>
#include <errno.h>
#ifdef SOLARIS
#include <sys/trap.h>
#include <sys/regset.h>
#include <sys/procset.h>
#include <ucontext.h>
#include <setjmp.h>
#endif // SOLARIS
# ifdef SOLARIS_MUTATOR_LIBTHREAD
# include <sys/procfs.h>
# endif
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif // __STDC_LIMIT_MACROS
#include <inttypes.h>
#include <signal.h>
#ifndef __OpenBSD__
#include <ucontext.h>
#endif
#ifdef __APPLE__
#include <AvailabilityMacros.h>
#include <mach/mach.h>
#endif
#include <sys/time.h>
#endif // LINUX || _ALLBSD_SOURCE
#ifdef SOLARIS
#ifdef _LP64
#undef NULL
#define NULL 0L
#else
#ifndef NULL
#define NULL 0
#endif
#endif
#endif
#ifdef __GNUC__
#ifdef _LP64
#define NULL_WORD 0L
#else
#define NULL_WORD ((intptr_t)0)
#endif
#else
#define NULL_WORD NULL
#endif
#if !defined(LINUX) && !defined(_ALLBSD_SOURCE)
typedef unsigned short uint16_t;
#ifndef _UINT32_T
#define _UINT32_T
typedef unsigned int uint32_t;
#endif // _UINT32_T
#if !defined(_SYS_INT_TYPES_H)
#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
#endif // _UINT64_T
typedef int intptr_t;
typedef unsigned int uintptr_t;
#endif // _SYS_INT_TYPES_H
#endif // !LINUX && !_ALLBSD_SOURCE
typedef uint8_t jubyte;
typedef uint16_t jushort;
typedef uint32_t juint;
typedef uint64_t julong;
#define CONST64(x) (x ## LL)
#define UCONST64(x) (x ## ULL)
const jlong min_jlong = CONST64(0x8000000000000000);
const jlong max_jlong = CONST64(0x7fffffffffffffff);
#ifdef SOLARIS
extern "C" {
typedef int (*int_fnP_thread_t_iP_uP_stack_tP_gregset_t)(thread_t, int*, unsigned *, stack_t*, gregset_t);
typedef int (*int_fnP_thread_t_i_gregset_t)(thread_t, int, gregset_t);
typedef int (*int_fnP_thread_t_i)(thread_t, int);
typedef int (*int_fnP_thread_t)(thread_t);
typedef int (*int_fnP_cond_tP_mutex_tP_timestruc_tP)(cond_t *cv, mutex_t *mx, timestruc_t *abst);
typedef int (*int_fnP_cond_tP_mutex_tP)(cond_t *cv, mutex_t *mx);
typedef int (*int_fnP_mutex_tP_i_vP)(mutex_t *, int, void *);
typedef int (*int_fnP_mutex_tP)(mutex_t *);
typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg);
typedef int (*int_fnP_cond_tP)(cond_t *cv);
};
#endif // SOLARIS
#define DEBUG_EXCEPTION ::abort();
#ifdef ARM32
#ifdef SOLARIS
#define BREAKPOINT __asm__ volatile (".long 0xe1200070")
#else
#define BREAKPOINT __asm__ volatile (".long 0xe7f001f0")
#endif
#else
extern "C" void breakpoint();
#define BREAKPOINT ::breakpoint()
#endif
#ifdef SOLARIS
#ifdef SPARC
inline int g_isnan(float f) { return isnanf(f); }
#else
inline int g_isnan(float f) { return isnand(f); }
#endif
inline int g_isnan(double f) { return isnand(f); }
#elif defined(__APPLE__)
inline int g_isnan(double f) { return isnan(f); }
#elif defined(LINUX) || defined(_ALLBSD_SOURCE)
inline int g_isnan(float f) { return isnanf(f); }
inline int g_isnan(double f) { return isnan(f); }
#else
#error "missing platform-specific definition here"
#endif
#if (__GNUC__ == 4) && (__GNUC_MINOR__ > 2)
#define CAN_USE_NAN_DEFINE 1
#endif
inline int g_isfinite(jfloat f) { return finite(f); }
inline int g_isfinite(jdouble f) { return finite(f); }
inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
#define PRAGMA_INTERFACE #pragma interface
#define PRAGMA_IMPLEMENTATION #pragma implementation
#define VALUE_OBJ_CLASS_SPEC
#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ > 4)
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(fmt,vargs) __attribute__((format(printf, fmt, vargs)))
#endif
#ifndef ATTRIBUTE_SCANF
#define ATTRIBUTE_SCANF(fmt,vargs) __attribute__((format(scanf, fmt, vargs)))
#endif
#endif // gcc version check
#define PRAGMA_FORMAT_NONLITERAL_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \
_Pragma("GCC diagnostic ignored \"-Wformat-security\"")
#define PRAGMA_FORMAT_IGNORED _Pragma("GCC diagnostic ignored \"-Wformat\"")
#if defined(__clang_major__) && \
(__clang_major__ >= 4 || \
(__clang_major__ >= 3 && __clang_minor__ >= 1)) || \
((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push")
#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop")
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
#else
#define PRAGMA_DIAG_PUSH
#define PRAGMA_DIAG_POP
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
#endif
#ifndef __clang_major__
#define PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC _Pragma("GCC diagnostic ignored \"-Wformat\"") _Pragma("GCC diagnostic error \"-Wformat-nonliteral\"") _Pragma("GCC diagnostic error \"-Wformat-security\"")
#endif
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
#define TEMPLATE_TABLE_BUG
#endif
#if (__GNUC__ == 2) && (__GNUC_MINOR__ >= 96)
#define CONST_SDM_BUG
#endif
#ifdef _LP64
#define FORMAT64_MODIFIER "l"
#else // !_LP64
#define FORMAT64_MODIFIER "ll"
#endif // _LP64
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
#ifdef offsetof
# undef offsetof
#endif
#define offsetof(klass,field) offset_of(klass,field)
#if defined(_LP64) && defined(__APPLE__)
#define JLONG_FORMAT "%ld"
#endif // _LP64 && __APPLE__
#define NOINLINE __attribute__ ((noinline))
#define ALWAYSINLINE inline __attribute__ ((always_inline))
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/globalDefinitions_sparcWorks.hpp
#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_SPARCWORKS_HPP
#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_SPARCWORKS_HPP
#include "prims/jni.h"
# include <ctype.h>
#define __USE_LEGACY_PROTOTYPES__
# include <dirent.h>
#undef __USE_LEGACY_PROTOTYPES__
# include <string.h>
# include <strings.h> // for bsd'isms
# include <stdarg.h>
# include <stddef.h> // for offsetof
# include <stdio.h>
# include <stdlib.h>
# include <wchar.h>
# include <stdarg.h>
#ifdef SOLARIS
# include <ieeefp.h>
#endif
# include <math.h>
# include <time.h>
# include <fcntl.h>
# include <dlfcn.h>
# include <pthread.h>
#ifdef SOLARIS
# include <thread.h>
#endif
# include <limits.h>
# include <errno.h>
#ifdef SOLARIS
# include <sys/trap.h>
# include <sys/regset.h>
# include <sys/procset.h>
# include <ucontext.h>
# include <setjmp.h>
#endif
# ifdef SOLARIS_MUTATOR_LIBTHREAD
# include <sys/procfs.h>
# endif
#include <inttypes.h>
#ifdef SOLARIS
#ifndef PRIdPTR
#if defined(_LP64)
#define PRIdPTR "ld"
#define PRIuPTR "lu"
#define PRIxPTR "lx"
#else
#define PRIdPTR "d"
#define PRIuPTR "u"
#define PRIxPTR "x"
#endif
#endif
#endif
#ifdef LINUX
# include <signal.h>
# include <ucontext.h>
# include <sys/time.h>
#endif
#ifdef SOLARIS
#ifdef _LP64
#undef NULL
#define NULL 0L
#else
#ifndef NULL
#define NULL 0
#endif
#endif
#endif
#ifdef LINUX
#ifdef _LP64
#define NULL_WORD 0L
#else
#define NULL_WORD ((intptr_t)0)
#endif
#else
#define NULL_WORD NULL
#endif
#ifndef LINUX
typedef unsigned short uint16_t;
#ifndef _UINT32_T
#define _UINT32_T
typedef unsigned int uint32_t;
#endif
#if !defined(_SYS_INT_TYPES_H)
#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
#endif
typedef int intptr_t;
typedef unsigned int uintptr_t;
#endif
#endif
#if UINTPTR_MAX - 1 == -1
#undef UINTPTR_MAX
#ifdef _LP64
#define UINTPTR_MAX UINT64_MAX
#else
#define UINTPTR_MAX UINT32_MAX
#endif /* ifdef _LP64 */
#endif
typedef unsigned char jubyte;
typedef unsigned short jushort;
typedef unsigned int juint;
typedef unsigned long long julong;
#define CONST64(x) (x ## LL)
#define UCONST64(x) (x ## ULL)
const jlong min_jlong = CONST64(0x8000000000000000);
const jlong max_jlong = CONST64(0x7fffffffffffffff);
#ifdef SOLARIS
extern "C" {
typedef int (*int_fnP_thread_t_iP_uP_stack_tP_gregset_t)(thread_t, int*, unsigned *, stack_t*, gregset_t);
typedef int (*int_fnP_thread_t_i_gregset_t)(thread_t, int, gregset_t);
typedef int (*int_fnP_thread_t_i)(thread_t, int);
typedef int (*int_fnP_thread_t)(thread_t);
typedef int (*int_fnP_cond_tP_mutex_tP_timestruc_tP)(cond_t *cv, mutex_t *mx, timestruc_t *abst);
typedef int (*int_fnP_cond_tP_mutex_tP)(cond_t *cv, mutex_t *mx);
typedef int (*int_fnP_mutex_tP_i_vP)(mutex_t *, int, void *);
typedef int (*int_fnP_mutex_tP)(mutex_t *);
typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg);
typedef int (*int_fnP_cond_tP)(cond_t *cv);
};
#endif
#define DEBUG_EXCEPTION ::abort();
extern "C" void breakpoint();
#define BREAKPOINT ::breakpoint()
#ifdef SOLARIS
#ifdef SPARC
inline int g_isnan(float f) { return isnanf(f); }
#else
inline int g_isnan(float f) { return isnand(f); }
#endif
inline int g_isnan(double f) { return isnand(f); }
#elif LINUX
inline int g_isnan(float f) { return isnanf(f); }
inline int g_isnan(double f) { return isnan(f); }
#else
#error "missing platform-specific definition here"
#endif
inline int g_isfinite(jfloat f) { return finite(f); }
inline int g_isfinite(jdouble f) { return finite(f); }
inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
#ifndef LINUX
int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr);
#define vsnprintf local_vsnprintf
#endif
#define PRAGMA_INTERFACE
#define PRAGMA_IMPLEMENTATION
#define PRAGMA_IMPLEMENTATION_(arg)
#define VALUE_OBJ_CLASS_SPEC : public _ValueObj
#ifdef _LP64
#define FORMAT64_MODIFIER "l"
#else // !_LP64
#define FORMAT64_MODIFIER "ll"
#endif // _LP64
#define offset_of(klass,field) offsetof(klass,field)
#define NOINLINE
#define ALWAYSINLINE inline __attribute__((always_inline))
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_SPARCWORKS_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/globalDefinitions_visCPP.hpp
#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
#include "prims/jni.h"
# include <ctype.h>
# include <string.h>
# include <stdarg.h>
# include <stdlib.h>
# include <stddef.h>// for offsetof
# include <io.h> // for stream.cpp
# include <float.h> // for _isnan
# include <stdio.h> // for va_list
# include <time.h>
# include <fcntl.h>
# include <limits.h>
#define _USE_MATH_DEFINES
# include <math.h>
#ifdef _LP64
#undef NULL
#define NULL 0i64
#else
#ifndef NULL
#define NULL 0
#endif
#endif
#define NULL_WORD NULL
#ifndef INT64_C
#define INT64_C(c) (c ## i64)
#endif
#ifndef UINT64_C
#define UINT64_C(c) (c ## ui64)
#endif
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
#ifdef _WIN64
typedef signed __int64 intptr_t;
typedef signed __int64 ssize_t;
#else
typedef signed int intptr_t;
typedef signed int ssize_t;
#endif
#ifndef UINTPTR_MAX
#ifdef _WIN64
#define UINTPTR_MAX _UI64_MAX
#else
#define UINTPTR_MAX _UI32_MAX
#endif
#endif
typedef unsigned char jubyte;
typedef unsigned short jushort;
typedef unsigned int juint;
typedef unsigned __int64 julong;
inline int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1,s2); }
inline int strncasecmp(const char *s1, const char *s2, size_t n) {
return _strnicmp(s1,s2,n);
}
#if _WIN64
extern "C" void breakpoint();
#define BREAKPOINT ::breakpoint()
#else
#define BREAKPOINT __asm { int 3 }
#endif
inline int g_isnan(jfloat f) { return _isnan(f); }
inline int g_isnan(jdouble f) { return _isnan(f); }
inline int g_isfinite(jfloat f) { return _finite(f); }
inline int g_isfinite(jdouble f) { return _finite(f); }
#define CONST64(x) (x ## i64)
#define UCONST64(x) ((uint64_t)CONST64(x))
const jlong min_jlong = CONST64(0x8000000000000000);
const jlong max_jlong = CONST64(0x7fffffffffffffff);
#if _MSC_VER >= 1400
#define open _open
#define close _close
#define read _read
#define write _write
#define lseek _lseek
#define unlink _unlink
#define strdup _strdup
#endif
#if _MSC_VER < 1800
#pragma warning( disable : 4355 )
#endif
#pragma warning( disable : 4100 ) // unreferenced formal parameter
#pragma warning( disable : 4127 ) // conditional expression is constant
#pragma warning( disable : 4514 ) // unreferenced inline function has been removed
#pragma warning( disable : 4244 ) // possible loss of data
#pragma warning( disable : 4512 ) // assignment operator could not be generated
#pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union (needed in windows.h)
#pragma warning( disable : 4511 ) // copy constructor could not be generated
#pragma warning( disable : 4291 ) // no matching operator delete found; memory will not be freed if initialization thows an exception
#ifdef CHECK_UNHANDLED_OOPS
#pragma warning( disable : 4521 ) // class has multiple copy ctors of a single type
#pragma warning( disable : 4522 ) // class has multiple assignment operators of a single type
#endif // CHECK_UNHANDLED_OOPS
#if _MSC_VER >= 1400
#pragma warning( disable : 4996 ) // unsafe string functions. Same as define _CRT_SECURE_NO_WARNINGS/_CRT_SECURE_NO_DEPRICATE
#endif
#define PRAGMA_INTERFACE
#define PRAGMA_IMPLEMENTATION
#define PRAGMA_IMPLEMENTATION_(arg)
#define VALUE_OBJ_CLASS_SPEC : public _ValueObj
#define FORMAT64_MODIFIER "I64"
#define PRId32 "d"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRId64 "I64d"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#ifdef _LP64
#define PRIdPTR "I64d"
#define PRIuPTR "I64u"
#define PRIxPTR "I64x"
#else
#define PRIdPTR "d"
#define PRIuPTR "u"
#define PRIxPTR "x"
#endif
#define offset_of(klass,field) offsetof(klass,field)
#define NOINLINE __declspec(noinline)
#define ALWAYSINLINE __forceinline
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/globalDefinitions_xlc.hpp
#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
#include "prims/jni.h"
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <math.h>
#include <time.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <pthread.h>
#include <limits.h>
#include <errno.h>
#include <stdint.h>
#define USE_XLC_BUILTINS
#ifdef USE_XLC_BUILTINS
#include <builtins.h>
#if __IBMCPP__ < 1000
#else
#define USE_XLC_PREFETCH_WRITE_BUILTIN
#endif
#endif // USE_XLC_BUILTINS
#ifdef __GNUC__
#error XLC and __GNUC__?
#else
#define NULL_WORD NULL
#endif
#ifdef AIX
#ifdef _LP64
#undef NULL
#define NULL 0L
#else
#ifndef NULL
#define NULL 0
#endif
#endif
#endif // AIX
typedef uint8_t jubyte;
typedef uint16_t jushort;
typedef uint32_t juint;
typedef uint64_t julong;
#define CONST64(x) (x ## LL)
#define UCONST64(x) (x ## ULL)
const jlong min_jlong = CONST64(0x8000000000000000);
const jlong max_jlong = CONST64(0x7fffffffffffffff);
#define DEBUG_EXCEPTION ::abort();
extern "C" void breakpoint();
#define BREAKPOINT ::breakpoint()
#ifdef AIX
inline int g_isnan(float f) { return isnan(f); }
inline int g_isnan(double f) { return isnan(f); }
#else
#error "missing platform-specific definition here"
#endif
inline int g_isfinite(jfloat f) { return finite(f); }
inline int g_isfinite(jdouble f) { return finite(f); }
inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
#define PRAGMA_INTERFACE #pragma interface
#define PRAGMA_IMPLEMENTATION #pragma implementation
#define VALUE_OBJ_CLASS_SPEC
#ifdef _LP64
#define FORMAT64_MODIFIER "l"
#else // !_LP64
#define FORMAT64_MODIFIER "ll"
#endif // _LP64
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
#define SIZE_1K ((uint64_t) 0x400ULL)
#define SIZE_4K ((uint64_t) 0x1000ULL)
#define SIZE_64K ((uint64_t) 0x10000ULL)
#define SIZE_1M ((uint64_t) 0x100000ULL)
#define SIZE_4M ((uint64_t) 0x400000ULL)
#define SIZE_8M ((uint64_t) 0x800000ULL)
#define SIZE_16M ((uint64_t) 0x1000000ULL)
#define SIZE_256M ((uint64_t) 0x10000000ULL)
#define SIZE_1G ((uint64_t) 0x40000000ULL)
#define SIZE_2G ((uint64_t) 0x80000000ULL)
#define SIZE_4G ((uint64_t) 0x100000000ULL)
#define SIZE_16G ((uint64_t) 0x400000000ULL)
#define SIZE_32G ((uint64_t) 0x800000000ULL)
#define SIZE_64G ((uint64_t) 0x1000000000ULL)
#define SIZE_1T ((uint64_t) 0x10000000000ULL)
#define NOINLINE __attribute__((__noinline__))
#define ALWAYSINLINE inline __attribute__((__always_inline__))
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/growableArray.cpp
#include "precompiled.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/growableArray.hpp"
#ifdef ASSERT
void GenericGrowableArray::set_nesting() {
if (on_stack()) {
_nesting = Thread::current()->resource_area()->nesting();
}
}
void GenericGrowableArray::check_nesting() {
if (on_stack() &&
_nesting != Thread::current()->resource_area()->nesting()) {
fatal("allocation bug: GrowableArray could grow within nested ResourceMark");
}
}
#endif
void* GenericGrowableArray::raw_allocate(int elementSize) {
assert(_max >= 0, "integer overflow");
size_t byte_size = elementSize * (size_t) _max;
if (on_stack()) {
return (void*)resource_allocate_bytes(byte_size);
} else if (on_C_heap()) {
return (void*)AllocateHeap(byte_size, _memflags);
} else {
return _arena->Amalloc(byte_size);
}
}
C:\hotspot-69087d08d473\src\share\vm/utilities/growableArray.hpp
#ifndef SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
#define SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/top.hpp"
#include <new>
extern "C" {
typedef int (*_sort_Fn)(const void *, const void *);
}
class GenericGrowableArray : public ResourceObj {
friend class VMStructs;
protected:
int _len; // current length
int _max; // maximum length
Arena* _arena; // Indicates where allocation occurs:
MEMFLAGS _memflags; // memory type if allocation in C heap
#ifdef ASSERT
int _nesting; // resource area nesting at creation
void set_nesting();
void check_nesting();
#else
#define set_nesting();
#define check_nesting();
#endif
bool on_C_heap() { return _arena == (Arena*)1; }
bool on_stack () { return _arena == NULL; }
bool on_arena () { return _arena > (Arena*)1; }
GenericGrowableArray(int initial_size, int initial_len, bool c_heap, MEMFLAGS flags = mtNone) {
_len = initial_len;
_max = initial_size;
_memflags = flags;
assert(!(c_heap && flags == mtNone), "memory type not specified for C heap object");
assert(_len >= 0 && _len <= _max, "initial_len too big");
_arena = (c_heap ? (Arena*)1 : NULL);
set_nesting();
assert(!on_C_heap() || allocated_on_C_heap(), "growable array must be on C heap if elements are");
assert(!on_stack() ||
(allocated_on_res_area() || allocated_on_stack()),
"growable array must be on stack if elements are not on arena and not on C heap");
}
GenericGrowableArray(Arena* arena, int initial_size, int initial_len) {
_len = initial_len;
_max = initial_size;
assert(_len >= 0 && _len <= _max, "initial_len too big");
_arena = arena;
_memflags = mtNone;
assert(on_arena(), "arena has taken on reserved value 0 or 1");
assert(allocated_on_arena() || allocated_on_stack(),
"growable array must be on arena or on stack if elements are on arena");
}
void* raw_allocate(int elementSize);
void* raw_allocate(Thread* thread, int elementSize) {
assert(on_stack(), "fast ResourceObj path only");
return (void*)resource_allocate_bytes(thread, elementSize * _max);
}
};
template<class E> class GrowableArrayIterator;
template<class E, class UnaryPredicate> class GrowableArrayFilterIterator;
template<class E> class GrowableArray : public GenericGrowableArray {
friend class VMStructs;
private:
E* _data; // data array
void grow(int j);
void raw_at_put_grow(int i, const E& p, const E& fill);
void clear_and_deallocate();
public:
GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) {
_data = (E*)raw_allocate(thread, sizeof(E));
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
}
GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal)
: GenericGrowableArray(initial_size, 0, C_heap, F) {
_data = (E*)raw_allocate(sizeof(E));
#ifdef _MSC_VER
#pragma warning(suppress: 4345)
#endif
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
}
GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false, MEMFLAGS memflags = mtInternal)
: GenericGrowableArray(initial_size, initial_len, C_heap, memflags) {
_data = (E*)raw_allocate(sizeof(E));
int i = 0;
for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler);
for (; i < _max; i++) ::new ((void*)&_data[i]) E();
}
GrowableArray(Arena* arena, int initial_size, int initial_len, const E& filler) : GenericGrowableArray(arena, initial_size, initial_len) {
_data = (E*)raw_allocate(sizeof(E));
int i = 0;
for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler);
for (; i < _max; i++) ::new ((void*)&_data[i]) E();
}
GrowableArray() : GenericGrowableArray(2, 0, false) {
_data = (E*)raw_allocate(sizeof(E));
::new ((void*)&_data[0]) E();
::new ((void*)&_data[1]) E();
}
~GrowableArray() { if (on_C_heap()) clear_and_deallocate(); }
void clear() { _len = 0; }
int length() const { return _len; }
int max_length() const { return _max; }
void trunc_to(int l) { assert(l <= _len,"cannot increase length"); _len = l; }
bool is_empty() const { return _len == 0; }
bool is_nonempty() const { return _len != 0; }
bool is_full() const { return _len == _max; }
DEBUG_ONLY(E* data_addr() const { return _data; })
void print();
int append(const E& elem) {
check_nesting();
if (_len == _max) grow(_len);
int idx = _len++;
_data[idx] = elem;
return idx;
}
bool append_if_missing(const E& elem) {
bool missed = !contains(elem);
if (missed) append(elem);
return missed;
}
E& at(int i) {
assert(0 <= i && i < _len, "illegal index");
return _data[i];
}
E const& at(int i) const {
assert(0 <= i && i < _len, "illegal index");
return _data[i];
}
E* adr_at(int i) const {
assert(0 <= i && i < _len, "illegal index");
return &_data[i];
}
E first() const {
assert(_len > 0, "empty list");
return _data[0];
}
E top() const {
assert(_len > 0, "empty list");
return _data[_len-1];
}
GrowableArrayIterator<E> begin() const {
return GrowableArrayIterator<E>(this, 0);
}
GrowableArrayIterator<E> end() const {
return GrowableArrayIterator<E>(this, length());
}
void push(const E& elem) { append(elem); }
E pop() {
assert(_len > 0, "empty list");
return _data[--_len];
}
void at_put(int i, const E& elem) {
assert(0 <= i && i < _len, "illegal index");
_data[i] = elem;
}
E at_grow(int i, const E& fill = E()) {
assert(0 <= i, "negative index");
check_nesting();
if (i >= _len) {
if (i >= _max) grow(i);
for (int j = _len; j <= i; j++)
_data[j] = fill;
_len = i+1;
}
return _data[i];
}
void at_put_grow(int i, const E& elem, const E& fill = E()) {
assert(0 <= i, "negative index");
check_nesting();
raw_at_put_grow(i, elem, fill);
}
bool contains(const E& elem) const {
for (int i = 0; i < _len; i++) {
if (_data[i] == elem) return true;
}
return false;
}
int find(const E& elem) const {
for (int i = 0; i < _len; i++) {
if (_data[i] == elem) return i;
}
return -1;
}
int find_from_end(const E& elem) const {
for (int i = _len-1; i >= 0; i--) {
if (_data[i] == elem) return i;
}
return -1;
}
int find(void* token, bool f(void*, E)) const {
for (int i = 0; i < _len; i++) {
if (f(token, _data[i])) return i;
}
return -1;
}
int find_from_end(void* token, bool f(void*, E)) const {
for (int i = _len-1; i >= 0; i--) {
if (f(token, _data[i])) return i;
}
return -1;
}
void remove(const E& elem) {
for (int i = 0; i < _len; i++) {
if (_data[i] == elem) {
for (int j = i + 1; j < _len; j++) _data[j-1] = _data[j];
_len--;
return;
}
}
ShouldNotReachHere();
}
void remove_at(int index) {
assert(0 <= index && index < _len, "illegal index");
for (int j = index + 1; j < _len; j++) _data[j-1] = _data[j];
_len--;
}
void delete_at(int index) {
assert(0 <= index && index < _len, "illegal index");
if (index < --_len) {
_data[index] = _data[_len];
}
}
void insert_before(const int idx, const E& elem) {
assert(0 <= idx && idx <= _len, "illegal index");
check_nesting();
if (_len == _max) grow(_len);
for (int j = _len - 1; j >= idx; j--) {
_data[j + 1] = _data[j];
}
_len++;
_data[idx] = elem;
}
void appendAll(const GrowableArray<E>* l) {
for (int i = 0; i < l->_len; i++) {
raw_at_put_grow(_len, l->_data[i], E());
}
}
void sort(int f(E*,E*)) {
qsort(_data, length(), sizeof(E), (_sort_Fn)f);
}
void sort(int f(E*,E*), int stride) {
qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f);
}
template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
bool found;
int location = find_sorted<E, compare>(key, found);
if (!found) {
insert_before(location, key);
}
return at(location);
}
template <typename K, int compare(const K&, const E&)> int find_sorted(const K& key, bool& found) {
found = false;
int min = 0;
int max = length() - 1;
while (max >= min) {
int mid = (int)(((uint)max + min) / 2);
E value = at(mid);
int diff = compare(key, value);
if (diff > 0) {
min = mid + 1;
} else if (diff < 0) {
max = mid - 1;
} else {
found = true;
return mid;
}
}
return min;
}
};
template<class E> void GrowableArray<E>::grow(int j) {
int old_max = _max;
if (_max == 0) _max = 1; // prevent endless loop
while (j >= _max) _max = _max*2;
E* newData = (E*)raw_allocate(sizeof(E));
int i = 0;
for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]);
#ifdef _MSC_VER
#pragma warning(suppress: 4345)
#endif
for ( ; i < _max; i++) ::new ((void*)&newData[i]) E();
for (i = 0; i < old_max; i++) _data[i].~E();
if (on_C_heap() && _data != NULL) {
FreeHeap(_data);
}
_data = newData;
}
template<class E> void GrowableArray<E>::raw_at_put_grow(int i, const E& p, const E& fill) {
if (i >= _len) {
if (i >= _max) grow(i);
for (int j = _len; j < i; j++)
_data[j] = fill;
_len = i+1;
}
_data[i] = p;
}
template<class E> void GrowableArray<E>::clear_and_deallocate() {
assert(on_C_heap(),
"clear_and_deallocate should only be called when on C heap");
clear();
if (_data != NULL) {
for (int i = 0; i < _max; i++) _data[i].~E();
FreeHeap(_data);
_data = NULL;
}
}
template<class E> void GrowableArray<E>::print() {
tty->print("Growable Array " INTPTR_FORMAT, this);
tty->print(": length %ld (_max %ld) { ", _len, _max);
for (int i = 0; i < _len; i++) tty->print(INTPTR_FORMAT " ", *(intptr_t*)&(_data[i]));
tty->print("}\n");
}
template<class E> class GrowableArrayIterator : public StackObj {
friend class GrowableArray<E>;
template<class F, class UnaryPredicate> friend class GrowableArrayFilterIterator;
private:
const GrowableArray<E>* _array; // GrowableArray we iterate over
int _position; // The current position in the GrowableArray
GrowableArrayIterator(const GrowableArray<E>* array, int position) : _array(array), _position(position) {
assert(0 <= position && position <= _array->length(), "illegal position");
}
public:
GrowableArrayIterator<E>& operator++() { ++_position; return *this; }
E operator*() { return _array->at(_position); }
bool operator==(const GrowableArrayIterator<E>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position == rhs._position;
}
bool operator!=(const GrowableArrayIterator<E>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position != rhs._position;
}
};
template<class E, class UnaryPredicate> class GrowableArrayFilterIterator : public StackObj {
friend class GrowableArray<E>;
private:
const GrowableArray<E>* _array; // GrowableArray we iterate over
int _position; // Current position in the GrowableArray
UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
public:
GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate)
: _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
while(_position != _array->length() && !_predicate(_array->at(_position))) {
++_position;
}
}
GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
do {
++_position;
} while(_position != _array->length() && !_predicate(_array->at(_position)));
return *this;
}
E operator*() { return _array->at(_position); }
bool operator==(const GrowableArrayIterator<E>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position == rhs._position;
}
bool operator!=(const GrowableArrayIterator<E>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position != rhs._position;
}
bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position == rhs._position;
}
bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
assert(_array == rhs._array, "iterator belongs to different array");
return _position != rhs._position;
}
};
#endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/hashtable.cpp
#include "precompiled.hpp"
#include "classfile/altHashing.hpp"
#include "classfile/javaClasses.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/safepoint.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/numberSeq.hpp"
template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry_free_list() {
BasicHashtableEntry<F>* entry = NULL;
if (_free_list != NULL) {
entry = _free_list;
_free_list = _free_list->next();
}
return entry;
}
template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) {
BasicHashtableEntry<F>* entry = new_entry_free_list();
if (entry == NULL) {
if (_first_free_entry + _entry_size >= _end_block) {
int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
int len = _entry_size * block_size;
len = 1 << log2_int(len); // round down to power of 2
assert(len >= _entry_size, "");
_first_free_entry = NEW_C_HEAP_ARRAY2(char, len, F, CURRENT_PC);
_end_block = _first_free_entry + len;
}
entry = (BasicHashtableEntry<F>*)_first_free_entry;
_first_free_entry += _entry_size;
}
assert(_entry_size % HeapWordSize == 0, "");
entry->set_hash(hashValue);
return entry;
}
template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::new_entry(unsigned int hashValue, T obj) {
HashtableEntry<T, F>* entry;
entry = (HashtableEntry<T, F>*)BasicHashtable<F>::new_entry(hashValue);
entry->set_literal(obj);
return entry;
}
template <class T, MEMFLAGS F> bool RehashableHashtable<T, F>::check_rehash_table(int count) {
assert(this->table_size() != 0, "underflow");
if (count > (((double)this->number_of_entries()/(double)this->table_size())*rehash_multiple)) {
return true;
}
return false;
}
template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::move_to(RehashableHashtable<T, F>* new_table) {
_seed = AltHashing::compute_seed();
assert(seed() != 0, "shouldn't be zero");
int saved_entry_count = this->number_of_entries();
for (int i = 0; i < new_table->table_size(); ++i) {
for (HashtableEntry<T, F>* p = this->bucket(i); p != NULL; ) {
HashtableEntry<T, F>* next = p->next();
T string = p->literal();
unsigned int hashValue = string->new_hash(seed());
int index = new_table->hash_to_index(hashValue);
p->set_hash(hashValue);
bool keep_shared = p->is_shared();
this->unlink_entry(p);
new_table->add_entry(index, p);
if (keep_shared) {
p->set_shared();
}
p = next;
}
}
new_table->copy_freelist(this);
assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?");
BasicHashtable<F>::free_buckets();
}
template <MEMFLAGS F> void BasicHashtable<F>::free_buckets() {
if (NULL != _buckets) {
if (!UseSharedSpaces ||
!FileMapInfo::current_info()->is_in_shared_space(_buckets)) {
FREE_C_HEAP_ARRAY(HashtableBucket, _buckets, F);
}
_buckets = NULL;
}
}
template <MEMFLAGS F> void BasicHashtable<F>::reverse() {
for (int i = 0; i < _table_size; ++i) {
BasicHashtableEntry<F>* new_list = NULL;
BasicHashtableEntry<F>* p = bucket(i);
while (p != NULL) {
BasicHashtableEntry<F>* next = p->next();
p->set_next(new_list);
new_list = p;
p = next;
}
}
}
template <MEMFLAGS F> void BasicHashtable<F>::BucketUnlinkContext::free_entry(BasicHashtableEntry<F>* entry) {
entry->set_next(_removed_head);
_removed_head = entry;
if (_removed_tail == NULL) {
_removed_tail = entry;
}
_num_removed++;
}
template <MEMFLAGS F> void BasicHashtable<F>::bulk_free_entries(BucketUnlinkContext* context) {
if (context->_num_removed == 0) {
assert(context->_removed_head == NULL && context->_removed_tail == NULL,
err_msg("Zero entries in the unlink context, but elements linked from " PTR_FORMAT " to " PTR_FORMAT,
p2i(context->_removed_head), p2i(context->_removed_tail)));
return;
}
BasicHashtableEntry<F>* current = _free_list;
while (true) {
context->_removed_tail->set_next(current);
BasicHashtableEntry<F>* old = (BasicHashtableEntry<F>*)Atomic::cmpxchg_ptr(context->_removed_head, &_free_list, current);
if (old == current) {
break;
}
current = old;
}
Atomic::add(-context->_num_removed, &_number_of_entries);
}
template <MEMFLAGS F> void BasicHashtable<F>::copy_table(char** top, char* end) {
intptr_t *plen = (intptr_t*)(*top);
int i;
for (i = 0; i < _table_size; ++i) {
for (BasicHashtableEntry<F>** p = _buckets[i].entry_addr();
p = (*p)->next_addr()) {
if (*top + entry_size() > end) {
report_out_of_shared_space(SharedMiscData);
}
}
}
for (i = 0; i < _table_size; ++i) {
for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
p->set_shared();
}
}
}
template <class T, MEMFLAGS F> void Hashtable<T, F>::reverse(void* boundary) {
for (int i = 0; i < this->table_size(); ++i) {
HashtableEntry<T, F>* high_list = NULL;
HashtableEntry<T, F>* low_list = NULL;
HashtableEntry<T, F>* last_low_entry = NULL;
HashtableEntry<T, F>* p = bucket(i);
while (p != NULL) {
HashtableEntry<T, F>* next = p->next();
if ((void*)p->literal() >= boundary) {
p->set_next(high_list);
high_list = p;
} else {
p->set_next(low_list);
low_list = p;
if (last_low_entry == NULL) {
last_low_entry = p;
}
}
p = next;
}
if (low_list != NULL) {
last_low_entry->set_next(high_list);
} else {
}
}
}
template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) {
return symbol->size() * HeapWordSize;
}
template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) {
assert(oop != NULL && oop->klass() == SystemDictionary::String_klass(), "only strings are supported");
return (oop->size() + java_lang_String::value(oop)->size()) * HeapWordSize;
}
template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::dump_table(outputStream* st, const char *table_name) {
NumberSeq summary;
int literal_bytes = 0;
for (int i = 0; i < this->table_size(); ++i) {
int count = 0;
for (HashtableEntry<T, F>* e = this->bucket(i);
e != NULL; e = e->next()) {
count++;
literal_bytes += literal_size(e->literal());
}
summary.add((double)count);
}
double num_buckets = summary.num();
double num_entries = summary.sum();
int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>);
int entry_bytes = (int)num_entries * sizeof(HashtableEntry<T, F>);
int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
double bucket_avg = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets);
double entry_avg = (num_entries <= 0) ? 0 : (entry_bytes / num_entries);
double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries);
st->print_cr("%s statistics:", table_name);
st->print_cr("Number of buckets : %9d = %9d bytes, avg %7.3f", (int)num_buckets, bucket_bytes, bucket_avg);
st->print_cr("Number of entries : %9d = %9d bytes, avg %7.3f", (int)num_entries, entry_bytes, entry_avg);
st->print_cr("Number of literals : %9d = %9d bytes, avg %7.3f", (int)num_entries, literal_bytes, literal_avg);
st->print_cr("Total footprint : %9s = %9d bytes", "", total_bytes);
st->print_cr("Average bucket size : %9.3f", summary.avg());
st->print_cr("Variance of bucket size : %9.3f", summary.variance());
st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
st->print_cr("Maximum bucket size : %9d", (int)summary.maximum());
}
template <MEMFLAGS F> void BasicHashtable<F>::copy_buckets(char** top, char* end) {
intptr_t len = _table_size * sizeof(HashtableBucket<F>);
if (*top + len > end) {
report_out_of_shared_space(SharedMiscData);
}
_buckets = (HashtableBucket<F>*)memcpy(*top, (void*)_buckets, len);
}
#ifndef PRODUCT
template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
ResourceMark rm;
for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
HashtableEntry<T, F>* entry = bucket(i);
while(entry != NULL) {
tty->print("%d : ", i);
entry->literal()->print();
tty->cr();
entry = entry->next();
}
}
}
template <MEMFLAGS F> void BasicHashtable<F>::verify() {
int count = 0;
for (int i = 0; i < table_size(); i++) {
for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
++count;
}
}
assert(count == number_of_entries(), "number of hashtable entries incorrect");
}
#endif // PRODUCT
#ifdef ASSERT
template <MEMFLAGS F> void BasicHashtable<F>::verify_lookup_length(double load) {
if ((double)_lookup_length / (double)_lookup_count > load * 2.0) {
warning("Performance bug: SystemDictionary lookup_count=%d "
"lookup_length=%d average=%lf load=%f",
_lookup_count, _lookup_length,
(double) _lookup_length / _lookup_count, load);
}
}
#endif
#if INCLUDE_ALL_GCS
template class Hashtable<nmethod*, mtGC>;
template class HashtableEntry<nmethod*, mtGC>;
template class BasicHashtable<mtGC>;
#endif
template class Hashtable<ConstantPool*, mtClass>;
template class RehashableHashtable<Symbol*, mtSymbol>;
template class RehashableHashtable<oopDesc*, mtSymbol>;
template class Hashtable<Symbol*, mtSymbol>;
template class Hashtable<Klass*, mtClass>;
template class Hashtable<oop, mtClass>;
#if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
template class Hashtable<oop, mtSymbol>;
template class RehashableHashtable<oop, mtSymbol>;
#endif // SOLARIS || CHECK_UNHANDLED_OOPS
template class Hashtable<oopDesc*, mtSymbol>;
template class Hashtable<Symbol*, mtClass>;
template class HashtableEntry<Symbol*, mtSymbol>;
template class HashtableEntry<Symbol*, mtClass>;
template class HashtableEntry<oop, mtSymbol>;
template class BasicHashtableEntry<mtSymbol>;
template class BasicHashtableEntry<mtCode>;
template class BasicHashtable<mtClass>;
template class BasicHashtable<mtSymbol>;
template class BasicHashtable<mtCode>;
template class BasicHashtable<mtInternal>;
C:\hotspot-69087d08d473\src\share\vm/utilities/hashtable.hpp
#ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP
#define SHARE_VM_UTILITIES_HASHTABLE_HPP
#include "classfile/classLoaderData.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.hpp"
template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
friend class VMStructs;
private:
unsigned int _hash; // 32-bit hash for item
BasicHashtableEntry<F>* _next;
protected:
BasicHashtableEntry() { ShouldNotReachHere(); }
~BasicHashtableEntry() { ShouldNotReachHere(); }
public:
unsigned int hash() const { return _hash; }
void set_hash(unsigned int hash) { _hash = hash; }
unsigned int* hash_addr() { return &_hash; }
static BasicHashtableEntry<F>* make_ptr(BasicHashtableEntry<F>* p) {
return (BasicHashtableEntry*)((intptr_t)p & -2);
}
BasicHashtableEntry<F>* next() const {
return make_ptr(_next);
}
void set_next(BasicHashtableEntry<F>* next) {
_next = next;
}
BasicHashtableEntry<F>** next_addr() {
return &_next;
}
bool is_shared() const {
return ((intptr_t)_next & 1) != 0;
}
void set_shared() {
_next = (BasicHashtableEntry<F>*)((intptr_t)_next | 1);
}
};
template <class T, MEMFLAGS F> class HashtableEntry : public BasicHashtableEntry<F> {
friend class VMStructs;
private:
T _literal; // ref to item in table.
public:
T literal() const { return _literal; }
T* literal_addr() { return &_literal; }
void set_literal(T s) { _literal = s; }
HashtableEntry* next() const {
return (HashtableEntry*)BasicHashtableEntry<F>::next();
}
HashtableEntry** next_addr() {
return (HashtableEntry**)BasicHashtableEntry<F>::next_addr();
}
};
template <MEMFLAGS F> class HashtableBucket : public CHeapObj<F> {
friend class VMStructs;
private:
BasicHashtableEntry<F>* _entry;
public:
void clear() { _entry = NULL; }
BasicHashtableEntry<F>* get_entry() const;
void set_entry(BasicHashtableEntry<F>* l);
BasicHashtableEntry<F>** entry_addr() { return &_entry; }
};
template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
friend class VMStructs;
public:
BasicHashtable(int table_size, int entry_size);
BasicHashtable(int table_size, int entry_size,
HashtableBucket<F>* buckets, int number_of_entries);
void copy_buckets(char** top, char* end);
void copy_table(char** top, char* end);
int hash_to_index(unsigned int full_hash) {
int h = full_hash % _table_size;
assert(h >= 0 && h < _table_size, "Illegal hash value");
return h;
}
void reverse();
private:
int _table_size;
HashtableBucket<F>* _buckets;
BasicHashtableEntry<F>* volatile _free_list;
char* _first_free_entry;
char* _end_block;
int _entry_size;
volatile int _number_of_entries;
protected:
#ifdef ASSERT
int _lookup_count;
int _lookup_length;
void verify_lookup_length(double load);
#endif
void initialize(int table_size, int entry_size, int number_of_entries);
int entry_size() const { return _entry_size; }
BasicHashtableEntry<F>* bucket(int i);
BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
BasicHashtableEntry<F>* new_entry_free_list();
BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
void unlink_entry(BasicHashtableEntry<F>* entry) {
entry->set_next(NULL);
--_number_of_entries;
}
void copy_freelist(BasicHashtable* src) {
_free_list = src->_free_list;
src->_free_list = NULL;
_first_free_entry = src->_first_free_entry;
src->_first_free_entry = NULL;
_end_block = src->_end_block;
src->_end_block = NULL;
}
void free_buckets();
struct BucketUnlinkContext {
int _num_processed;
int _num_removed;
BasicHashtableEntry<F>* _removed_head;
BasicHashtableEntry<F>* _removed_tail;
BucketUnlinkContext() : _num_processed(0), _num_removed(0), _removed_head(NULL), _removed_tail(NULL) {
}
void free_entry(BasicHashtableEntry<F>* entry);
};
void bulk_free_entries(BucketUnlinkContext* context);
public:
int table_size() { return _table_size; }
void set_entry(int index, BasicHashtableEntry<F>* entry);
void add_entry(int index, BasicHashtableEntry<F>* entry);
void free_entry(BasicHashtableEntry<F>* entry);
int number_of_entries() { return _number_of_entries; }
void verify() PRODUCT_RETURN;
};
template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
friend class VMStructs;
public:
Hashtable(int table_size, int entry_size)
: BasicHashtable<F>(table_size, entry_size) { }
Hashtable(int table_size, int entry_size,
HashtableBucket<F>* buckets, int number_of_entries)
: BasicHashtable<F>(table_size, entry_size, buckets, number_of_entries) { }
void print() PRODUCT_RETURN;
void reverse(void* boundary = NULL);
protected:
unsigned int compute_hash(Symbol* name) {
return (unsigned int) name->identity_hash();
}
int index_for(Symbol* name) {
return this->hash_to_index(compute_hash(name));
}
HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
HashtableEntry<T, F>* bucket(int i) {
return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
}
HashtableEntry<T, F>** bucket_addr(int i) {
return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
}
};
template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
protected:
enum {
rehash_count = 100,
rehash_multiple = 60
};
bool check_rehash_table(int count);
public:
RehashableHashtable(int table_size, int entry_size)
: Hashtable<T, F>(table_size, entry_size) { }
RehashableHashtable(int table_size, int entry_size,
HashtableBucket<F>* buckets, int number_of_entries)
: Hashtable<T, F>(table_size, entry_size, buckets, number_of_entries) { }
void move_to(RehashableHashtable<T, F>* new_table);
static bool use_alternate_hashcode();
static juint seed();
static int literal_size(Symbol *symbol);
static int literal_size(oop oop);
static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
static int literal_size(Klass *k) {Unimplemented(); return 0;}
void dump_table(outputStream* st, const char *table_name);
private:
static juint _seed;
};
template <class T, MEMFLAGS F> juint RehashableHashtable<T, F>::_seed = 0;
template <class T, MEMFLAGS F> juint RehashableHashtable<T, F>::seed() { return _seed; };
template <class T, MEMFLAGS F> bool RehashableHashtable<T, F>::use_alternate_hashcode() { return _seed != 0; };
template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
friend class VMStructs;
protected:
TwoOopHashtable(int table_size, int entry_size)
: Hashtable<T, F>(table_size, entry_size) {}
TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
int number_of_entries)
: Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
public:
unsigned int compute_hash(Symbol* name, ClassLoaderData* loader_data) {
unsigned int name_hash = name->identity_hash();
assert(loader_data != NULL || UseSharedSpaces || DumpSharedSpaces,
"only allowed with shared spaces");
unsigned int loader_hash = loader_data == NULL ? 0 : loader_data->identity_hash();
return name_hash ^ loader_hash;
}
int index_for(Symbol* name, ClassLoaderData* loader_data) {
return this->hash_to_index(compute_hash(name, loader_data));
}
};
#endif // SHARE_VM_UTILITIES_HASHTABLE_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/hashtable.inline.hpp
#ifndef SHARE_VM_UTILITIES_HASHTABLE_INLINE_HPP
#define SHARE_VM_UTILITIES_HASHTABLE_INLINE_HPP
#include "memory/allocation.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/dtrace.hpp"
template <MEMFLAGS F> inline BasicHashtable<F>::BasicHashtable(int table_size, int entry_size) {
initialize(table_size, entry_size, 0);
_buckets = NEW_C_HEAP_ARRAY2(HashtableBucket<F>, table_size, F, CURRENT_PC);
for (int index = 0; index < _table_size; index++) {
_buckets[index].clear();
}
}
template <MEMFLAGS F> inline BasicHashtable<F>::BasicHashtable(int table_size, int entry_size,
HashtableBucket<F>* buckets,
int number_of_entries) {
initialize(table_size, entry_size, number_of_entries);
_buckets = buckets;
}
template <MEMFLAGS F> inline void BasicHashtable<F>::initialize(int table_size, int entry_size,
int number_of_entries) {
_table_size = table_size;
_entry_size = entry_size;
_free_list = NULL;
_first_free_entry = NULL;
_end_block = NULL;
_number_of_entries = number_of_entries;
#ifdef ASSERT
_lookup_count = 0;
_lookup_length = 0;
#endif
}
template <MEMFLAGS F> inline BasicHashtableEntry<F>* BasicHashtable<F>::bucket(int i) {
return _buckets[i].get_entry();
}
template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEntry<F>* l) {
OrderAccess::release_store_ptr(&_entry, l);
}
template <MEMFLAGS F> inline BasicHashtableEntry<F>* HashtableBucket<F>::get_entry() const {
return (BasicHashtableEntry<F>*) OrderAccess::load_ptr_acquire(&_entry);
}
template <MEMFLAGS F> inline void BasicHashtable<F>::set_entry(int index, BasicHashtableEntry<F>* entry) {
_buckets[index].set_entry(entry);
}
template <MEMFLAGS F> inline void BasicHashtable<F>::add_entry(int index, BasicHashtableEntry<F>* entry) {
entry->set_next(bucket(index));
_buckets[index].set_entry(entry);
++_number_of_entries;
}
template <MEMFLAGS F> inline void BasicHashtable<F>::free_entry(BasicHashtableEntry<F>* entry) {
entry->set_next(_free_list);
_free_list = entry;
--_number_of_entries;
}
#endif // SHARE_VM_UTILITIES_HASHTABLE_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/histogram.cpp
#include "precompiled.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/histogram.hpp"
#ifdef ASSERT
HistogramElement::HistogramElement() {
_count = 0;
}
int HistogramElement::count() {
return _count;
}
const char* HistogramElement::name() {
return _name;
}
void HistogramElement::increment_count() {
Atomic::inc(&_count);
}
int HistogramElement::compare(HistogramElement* e1,HistogramElement* e2) {
if(e1->count() > e2->count()) {
return -1;
} else if(e1->count() < e2->count()) {
return 1;
}
return 0;
}
void HistogramElement::print_on(outputStream* st) const {
st->print("%10d ",((HistogramElement*)this)->count());
st->print_cr("%s",((HistogramElement*)this)->name());
}
int Histogram::sort_helper(HistogramElement** e1, HistogramElement** e2) {
return (*e1)->compare(*e1,*e2);
}
Histogram::Histogram(const char* title,int estimatedCount) {
_title = title;
_elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<HistogramElement*>(estimatedCount,true);
}
void Histogram::add_element(HistogramElement* element) {
elements()->append(element);
}
void Histogram::print_header(outputStream* st) {
st->print_cr("%s",title());
st->print_cr("--------------------------------------------------");
}
void Histogram::print_elements(outputStream* st) {
elements()->sort(Histogram::sort_helper);
jint total = 0;
for(int i=0; i < elements()->length(); i++) {
elements()->at(i)->print();
total += elements()->at(i)->count();
}
st->print("%10d ", total);
st->print_cr("Total");
}
void Histogram::print_on(outputStream* st) const {
((Histogram*)this)->print_header(st);
((Histogram*)this)->print_elements(st);
}
#endif
C:\hotspot-69087d08d473\src\share\vm/utilities/histogram.hpp
#ifndef SHARE_VM_UTILITIES_HISTOGRAM_HPP
#define SHARE_VM_UTILITIES_HISTOGRAM_HPP
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "utilities/growableArray.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "os_aix.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
#ifdef ASSERT
class HistogramElement : public CHeapObj<mtInternal> {
protected:
jint _count;
const char* _name;
public:
HistogramElement();
virtual int count();
virtual const char* name();
virtual void increment_count();
void print_on(outputStream* st) const;
virtual int compare(HistogramElement* e1,HistogramElement* e2);
};
class Histogram : public CHeapObj<mtInternal> {
protected:
GrowableArray<HistogramElement*>* _elements;
GrowableArray<HistogramElement*>* elements() { return _elements; }
const char* _title;
const char* title() { return _title; }
static int sort_helper(HistogramElement** e1,HistogramElement** e2);
virtual void print_header(outputStream* st);
virtual void print_elements(outputStream* st);
public:
Histogram(const char* title,int estimatedSize);
virtual void add_element(HistogramElement* element);
void print_on(outputStream* st) const;
};
#endif
#endif // SHARE_VM_UTILITIES_HISTOGRAM_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/intHisto.cpp
#include "precompiled.hpp"
#include "utilities/intHisto.hpp"
IntHistogram::IntHistogram(int est, int max) : _max(max), _tot(0) {
assert(0 <= est && est <= max, "Preconditions");
_elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(est, true);
guarantee(_elements != NULL, "alloc failure");
}
void IntHistogram::add_entry(int outcome) {
if (outcome > _max) outcome = _max;
int new_count = _elements->at_grow(outcome) + 1;
_elements->at_put(outcome, new_count);
_tot++;
}
int IntHistogram::entries_for_outcome(int outcome) {
return _elements->at_grow(outcome);
}
void IntHistogram::print_on(outputStream* st) const {
double tot_d = (double)_tot;
st->print_cr("Outcome # of occurrences %% of occurrences");
st->print_cr("-----------------------------------------------");
for (int i=0; i < _elements->length()-2; i++) {
int cnt = _elements->at(i);
if (cnt != 0) {
st->print_cr("%7d %10d %8.4f",
i, cnt, (double)cnt/tot_d);
}
}
if (_elements->length()-1 == _max) {
int cnt = _elements->at(_max);
st->print_cr(">= %4d %10d %8.4f",
_max, cnt, (double)cnt/tot_d);
}
st->print_cr("-----------------------------------------------");
st->print_cr(" All %10d %8.4f", _tot, 1.0);
}
C:\hotspot-69087d08d473\src\share\vm/utilities/intHisto.hpp
#ifndef SHARE_VM_UTILITIES_INTHISTO_HPP
#define SHARE_VM_UTILITIES_INTHISTO_HPP
#include "memory/allocation.hpp"
#include "utilities/growableArray.hpp"
class IntHistogram : public CHeapObj<mtInternal> {
protected:
int _max;
int _tot;
GrowableArray<int>* _elements;
public:
IntHistogram(int est, int max);
void add_entry(int outcome);
int entries_for_outcome(int outcome);
int total_entries() { return _tot; }
double fraction_for_outcome(int outcome) {
return
(double)entries_for_outcome(outcome)/
(double)total_entries();
}
void print_on(outputStream* st) const;
};
#endif // SHARE_VM_UTILITIES_INTHISTO_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/linkedlist.cpp
#include "precompiled.hpp"
#ifndef PRODUCT
#include "runtime/os.hpp"
#include "utilities/linkedlist.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
class Integer : public StackObj {
private:
int _value;
public:
Integer(int i) : _value(i) { }
int value() const { return _value; }
bool equals(const Integer& i) const {
return _value == i.value();
}
};
int compare_Integer(const Integer& i1, const Integer& i2) {
return i1.value() - i2.value();
}
void check_list_values(const int* expected, const LinkedList<Integer>* list) {
LinkedListNode<Integer>* head = list->head();
int index = 0;
while (head != NULL) {
assert(head->peek()->value() == expected[index], "Unexpected value");
head = head->next();
index ++;
}
}
void Test_linked_list() {
LinkedListImpl<Integer, ResourceObj::C_HEAP, mtTest> ll;
assert(ll.is_empty(), "Start with empty list");
Integer one(1), two(2), three(3), four(4), five(5), six(6);
ll.add(six);
assert(!ll.is_empty(), "Should not be empty");
Integer* i = ll.find(six);
assert(i != NULL, "Should find it");
i = ll.find(three);
assert(i == NULL, "Not in the list");
LinkedListNode<Integer>* node = ll.find_node(six);
assert(node != NULL, "6 is in the list");
ll.insert_after(three, node);
ll.insert_before(one, node);
int expected[3] = {1, 6, 3};
check_list_values(expected, &ll);
ll.add(two);
ll.add(four);
ll.add(five);
SortedLinkedList<Integer, compare_Integer, ResourceObj::C_HEAP, mtTest> sl;
assert(sl.is_empty(), "Start with empty list");
size_t ll_size = ll.size();
sl.move(&ll);
size_t sl_size = sl.size();
assert(ll_size == sl_size, "Should be the same size");
assert(ll.is_empty(), "No more entires");
int sorted_result[] = {1, 2, 3, 4, 5, 6};
check_list_values(sorted_result, &sl);
node = sl.find_node(four);
assert(node != NULL, "4 is in the list");
sl.remove_before(node);
sl.remove_after(node);
int remains[] = {1, 2, 4, 6};
check_list_values(remains, &sl);
}
#endif // PRODUCT
C:\hotspot-69087d08d473\src\share\vm/utilities/linkedlist.hpp
#ifndef SHARE_VM_UTILITIES_LINKED_LIST_HPP
#define SHARE_VM_UTILITIES_LINKED_LIST_HPP
#include "memory/allocation.hpp"
template <class E> class LinkedListNode : public ResourceObj {
private:
E _data; // embedded content
LinkedListNode<E>* _next; // next entry
protected:
LinkedListNode() : _next(NULL) { }
public:
LinkedListNode(const E& e): _data(e), _next(NULL) { }
inline void set_next(LinkedListNode<E>* node) { _next = node; }
inline LinkedListNode<E> * next() const { return _next; }
E* data() { return &_data; }
const E* peek() const { return &_data; }
};
template <class E> class LinkedList : public ResourceObj {
protected:
LinkedListNode<E>* _head;
public:
LinkedList() : _head(NULL) { }
inline void set_head(LinkedListNode<E>* h) { _head = h; }
inline LinkedListNode<E>* head() const { return _head; }
inline bool is_empty() const { return head() == NULL; }
inline size_t size() const {
LinkedListNode<E>* p;
size_t count = 0;
for (p = head(); p != NULL; count++, p = p->next());
return count;
}
virtual void move(LinkedList<E>* list) = 0;
virtual LinkedListNode<E>* add(const E& e) = 0;
virtual void add(LinkedListNode<E>* node) = 0;
virtual bool add(const LinkedList<E>* list) = 0;
virtual LinkedListNode<E>* find_node(const E& e) = 0;
virtual E* find(const E& e) = 0;
virtual LinkedListNode<E>* insert_before(const E& e, LinkedListNode<E>* ref) = 0;
virtual LinkedListNode<E>* insert_after (const E& e, LinkedListNode<E>* ref) = 0;
virtual bool remove(const E& e) = 0;
virtual bool remove(LinkedListNode<E>* node) = 0;
virtual bool remove_before(LinkedListNode<E>* ref) = 0;
virtual bool remove_after(LinkedListNode<E>* ref) = 0;
LinkedListNode<E>* unlink_head() {
LinkedListNode<E>* h = this->head();
if (h != NULL) {
this->set_head(h->next());
}
return h;
}
DEBUG_ONLY(virtual ResourceObj::allocation_type storage_type() = 0;)
};
template <class E, ResourceObj::allocation_type T = ResourceObj::C_HEAP,
MEMFLAGS F = mtNMT, AllocFailType alloc_failmode = AllocFailStrategy::RETURN_NULL>
class LinkedListImpl : public LinkedList<E> {
protected:
Arena* _arena;
public:
LinkedListImpl() : _arena(NULL) { }
LinkedListImpl(Arena* a) : _arena(a) { }
virtual ~LinkedListImpl() {
clear();
}
virtual void clear() {
LinkedListNode<E>* p = this->head();
this->set_head(NULL);
while (p != NULL) {
LinkedListNode<E>* to_delete = p;
p = p->next();
delete_node(to_delete);
}
}
virtual LinkedListNode<E>* add(const E& e) {
LinkedListNode<E>* node = this->new_node(e);
if (node != NULL) {
this->add(node);
}
return node;
}
virtual void add(LinkedListNode<E>* node) {
assert(node != NULL, "NULL pointer");
node->set_next(this->head());
this->set_head(node);
}
virtual void move(LinkedList<E>* list) {
assert(list->storage_type() == this->storage_type(), "Different storage type");
LinkedListNode<E>* node = this->head();
while (node != NULL && node->next() != NULL) {
node = node->next();
}
if (node == NULL) {
this->set_head(list->head());
} else {
node->set_next(list->head());
}
list->set_head(NULL);
}
virtual bool add(const LinkedList<E>* list) {
LinkedListNode<E>* node = list->head();
while (node != NULL) {
if (this->add(*node->peek()) == NULL) {
return false;
}
node = node->next();
}
return true;
}
virtual LinkedListNode<E>* find_node(const E& e) {
LinkedListNode<E>* p = this->head();
while (p != NULL && !p->peek()->equals(e)) {
p = p->next();
}
return p;
}
E* find(const E& e) {
LinkedListNode<E>* node = find_node(e);
return (node == NULL) ? NULL : node->data();
}
LinkedListNode<E>* insert_before(const E& e, LinkedListNode<E>* ref_node) {
LinkedListNode<E>* node = this->new_node(e);
if (node == NULL) return NULL;
if (ref_node == this->head()) {
node->set_next(ref_node);
this->set_head(node);
} else {
LinkedListNode<E>* p = this->head();
while (p != NULL && p->next() != ref_node) {
p = p->next();
}
assert(p != NULL, "ref_node not in the list");
node->set_next(ref_node);
p->set_next(node);
}
return node;
}
LinkedListNode<E>* insert_after(const E& e, LinkedListNode<E>* ref_node) {
LinkedListNode<E>* node = this->new_node(e);
if (node == NULL) return NULL;
node->set_next(ref_node->next());
ref_node->set_next(node);
return node;
}
virtual bool remove(const E& e) {
LinkedListNode<E>* tmp = this->head();
LinkedListNode<E>* prev = NULL;
while (tmp != NULL) {
if (tmp->peek()->equals(e)) {
return remove_after(prev);
}
prev = tmp;
tmp = tmp->next();
}
return false;
}
virtual bool remove_after(LinkedListNode<E>* prev) {
LinkedListNode<E>* to_delete;
if (prev == NULL) {
to_delete = this->unlink_head();
} else {
to_delete = prev->next();
if (to_delete != NULL) {
prev->set_next(to_delete->next());
}
}
if (to_delete != NULL) {
delete_node(to_delete);
return true;
}
return false;
}
virtual bool remove(LinkedListNode<E>* node) {
LinkedListNode<E>* p = this->head();
while (p != NULL && p->next() != node) {
p = p->next();
}
if (p != NULL) {
p->set_next(node->next());
delete_node(node);
return true;
} else {
return false;
}
}
virtual bool remove_before(LinkedListNode<E>* ref) {
assert(ref != NULL, "NULL pointer");
LinkedListNode<E>* p = this->head();
LinkedListNode<E>* to_delete = NULL; // to be deleted
LinkedListNode<E>* prev = NULL; // node before the node to be deleted
while (p != NULL && p != ref) {
prev = to_delete;
to_delete = p;
p = p->next();
}
if (p == NULL || to_delete == NULL) return false;
assert(to_delete->next() == ref, "Wrong node to delete");
assert(prev == NULL || prev->next() == to_delete,
"Sanity check");
if (prev == NULL) {
assert(to_delete == this->head(), "Must be head");
this->set_head(to_delete->next());
} else {
prev->set_next(to_delete->next());
}
delete_node(to_delete);
return true;
}
DEBUG_ONLY(ResourceObj::allocation_type storage_type() { return T; })
protected:
LinkedListNode<E>* new_node(const E& e) const {
switch(T) {
case ResourceObj::ARENA: {
assert(_arena != NULL, "Arena not set");
return new(_arena) LinkedListNode<E>(e);
}
case ResourceObj::RESOURCE_AREA:
case ResourceObj::C_HEAP: {
if (alloc_failmode == AllocFailStrategy::RETURN_NULL) {
return new(std::nothrow, T, F) LinkedListNode<E>(e);
} else {
return new(T, F) LinkedListNode<E>(e);
}
}
default:
ShouldNotReachHere();
}
return NULL;
}
void delete_node(LinkedListNode<E>* node) {
if (T == ResourceObj::C_HEAP) {
delete node;
}
}
};
template <class E, int (*FUNC)(const E&, const E&),
ResourceObj::allocation_type T = ResourceObj::C_HEAP,
MEMFLAGS F = mtNMT, AllocFailType alloc_failmode = AllocFailStrategy::RETURN_NULL>
class SortedLinkedList : public LinkedListImpl<E, T, F, alloc_failmode> {
public:
SortedLinkedList() { }
SortedLinkedList(Arena* a) : LinkedListImpl<E, T, F, alloc_failmode>(a) { }
virtual LinkedListNode<E>* add(const E& e) {
return LinkedListImpl<E, T, F, alloc_failmode>::add(e);
}
virtual void move(LinkedList<E>* list) {
assert(list->storage_type() == this->storage_type(), "Different storage type");
LinkedListNode<E>* node;
while ((node = list->unlink_head()) != NULL) {
this->add(node);
}
assert(list->is_empty(), "All entries are moved");
}
virtual void add(LinkedListNode<E>* node) {
assert(node != NULL, "NULL pointer");
LinkedListNode<E>* tmp = this->head();
LinkedListNode<E>* prev = NULL;
int cmp_val;
while (tmp != NULL) {
cmp_val = FUNC(*tmp->peek(), *node->peek());
if (cmp_val >= 0) {
break;
}
prev = tmp;
tmp = tmp->next();
}
if (prev != NULL) {
node->set_next(prev->next());
prev->set_next(node);
} else {
node->set_next(this->head());
this->set_head(node);
}
}
virtual bool add(const LinkedList<E>* list) {
return LinkedListImpl<E, T, F, alloc_failmode>::add(list);
}
virtual LinkedListNode<E>* find_node(const E& e) {
LinkedListNode<E>* p = this->head();
while (p != NULL) {
int comp_val = FUNC(*p->peek(), e);
if (comp_val == 0) {
return p;
} else if (comp_val > 0) {
return NULL;
}
p = p->next();
}
return NULL;
}
};
template <class E> class LinkedListIterator : public StackObj {
private:
LinkedListNode<E>* _p;
bool _is_empty;
public:
LinkedListIterator(LinkedListNode<E>* head) : _p(head) {
_is_empty = (head == NULL);
}
bool is_empty() const { return _is_empty; }
const E* next() {
if (_p == NULL) return NULL;
const E* e = _p->peek();
_p = _p->next();
return e;
}
};
#endif
C:\hotspot-69087d08d473\src\share\vm/utilities/macros.hpp
#ifndef SHARE_VM_UTILITIES_MACROS_HPP
#define SHARE_VM_UTILITIES_MACROS_HPP
#define NEEDS_CLEANUP
#define STR(a) #a
#define XSTR(a) STR(a)
#ifndef INCLUDE_JVMTI
#define INCLUDE_JVMTI 1
#endif // INCLUDE_JVMTI
#if INCLUDE_JVMTI
#define JVMTI_ONLY(x) x
#define NOT_JVMTI(x)
#define NOT_JVMTI_RETURN
#define NOT_JVMTI_RETURN_(code) /* next token must be ; */
#else
#define JVMTI_ONLY(x)
#define NOT_JVMTI(x) x
#define NOT_JVMTI_RETURN { return; }
#define NOT_JVMTI_RETURN_(code) { return code; }
#endif // INCLUDE_JVMTI
#ifndef INCLUDE_FPROF
#define INCLUDE_FPROF 1
#endif
#if INCLUDE_FPROF
#define NOT_FPROF_RETURN /* next token must be ; */
#define NOT_FPROF_RETURN_(code) /* next token must be ; */
#else
#define NOT_FPROF_RETURN {}
#define NOT_FPROF_RETURN_(code) { return code; }
#endif // INCLUDE_FPROF
#ifndef INCLUDE_VM_STRUCTS
#define INCLUDE_VM_STRUCTS 1
#endif
#if INCLUDE_VM_STRUCTS
#define NOT_VM_STRUCTS_RETURN /* next token must be ; */
#define NOT_VM_STRUCTS_RETURN_(code) /* next token must be ; */
#else
#define NOT_VM_STRUCTS_RETURN {}
#define NOT_VM_STRUCTS_RETURN_(code) { return code; }
#endif // INCLUDE_VM_STRUCTS
#ifndef INCLUDE_JNI_CHECK
#define INCLUDE_JNI_CHECK 1
#endif
#if INCLUDE_JNI_CHECK
#define NOT_JNI_CHECK_RETURN /* next token must be ; */
#define NOT_JNI_CHECK_RETURN_(code) /* next token must be ; */
#else
#define NOT_JNI_CHECK_RETURN {}
#define NOT_JNI_CHECK_RETURN_(code) { return code; }
#endif // INCLUDE_JNI_CHECK
#ifndef INCLUDE_SERVICES
#define INCLUDE_SERVICES 1
#endif
#if INCLUDE_SERVICES
#define NOT_SERVICES_RETURN /* next token must be ; */
#define NOT_SERVICES_RETURN_(code) /* next token must be ; */
#else
#define NOT_SERVICES_RETURN {}
#define NOT_SERVICES_RETURN_(code) { return code; }
#endif // INCLUDE_SERVICES
#ifndef INCLUDE_CDS
#define INCLUDE_CDS 1
#endif
#if INCLUDE_CDS
#define CDS_ONLY(x) x
#define NOT_CDS(x)
#define NOT_CDS_RETURN /* next token must be ; */
#define NOT_CDS_RETURN_(code) /* next token must be ; */
#else
#define CDS_ONLY(x)
#define NOT_CDS(x) x
#define NOT_CDS_RETURN {}
#define NOT_CDS_RETURN_(code) { return code; }
#endif // INCLUDE_CDS
#ifndef INCLUDE_MANAGEMENT
#define INCLUDE_MANAGEMENT 1
#endif // INCLUDE_MANAGEMENT
#if INCLUDE_MANAGEMENT
#define NOT_MANAGEMENT_RETURN /* next token must be ; */
#define NOT_MANAGEMENT_RETURN_(code) /* next token must be ; */
#else
#define NOT_MANAGEMENT_RETURN {}
#define NOT_MANAGEMENT_RETURN_(code) { return code; }
#endif // INCLUDE_MANAGEMENT
#ifndef INCLUDE_ALL_GCS
#define INCLUDE_ALL_GCS 1
#endif // INCLUDE_ALL_GCS
#if INCLUDE_ALL_GCS
#define NOT_ALL_GCS_RETURN /* next token must be ; */
#define NOT_ALL_GCS_RETURN_(code) /* next token must be ; */
#else
#define NOT_ALL_GCS_RETURN {}
#define NOT_ALL_GCS_RETURN_(code) { return code; }
#endif // INCLUDE_ALL_GCS
#ifndef INCLUDE_NMT
#define INCLUDE_NMT 1
#endif // INCLUDE_NMT
#if INCLUDE_NMT
#define NOT_NMT_RETURN /* next token must be ; */
#define NOT_NMT_RETURN_(code) /* next token must be ; */
#else
#define NOT_NMT_RETURN {}
#define NOT_NMT_RETURN_(code) { return code; }
#endif // INCLUDE_NMT
#ifndef INCLUDE_JFR
#define INCLUDE_JFR 1
#endif
#if INCLUDE_JFR
#define JFR_ONLY(code) code
#else
#define JFR_ONLY(code)
#endif
#ifdef COMPILER1
#ifdef COMPILER2
#define TIERED
#endif
#define COMPILER1_PRESENT(code) code
#else // COMPILER1
#define COMPILER1_PRESENT(code)
#endif // COMPILER1
#ifdef COMPILER2
#define COMPILER2_PRESENT(code) code
#define NOT_COMPILER2(code)
#else // COMPILER2
#define COMPILER2_PRESENT(code)
#define NOT_COMPILER2(code) code
#endif // COMPILER2
#ifdef TIERED
#define TIERED_ONLY(code) code
#define NOT_TIERED(code)
#else
#define TIERED_ONLY(code)
#define NOT_TIERED(code) code
#endif // TIERED
#ifdef PRODUCT
#define PRODUCT_ONLY(code) code
#define NOT_PRODUCT(code)
#define NOT_PRODUCT_ARG(arg)
#define PRODUCT_RETURN {}
#define PRODUCT_RETURN0 { return 0; }
#define PRODUCT_RETURN_(code) { code }
#else // PRODUCT
#define PRODUCT_ONLY(code)
#define NOT_PRODUCT(code) code
#define NOT_PRODUCT_ARG(arg) arg,
#define PRODUCT_RETURN /*next token must be ;*/
#define PRODUCT_RETURN0 /*next token must be ;*/
#define PRODUCT_RETURN_(code) /*next token must be ;*/
#endif // PRODUCT
#ifdef CHECK_UNHANDLED_OOPS
#define CHECK_UNHANDLED_OOPS_ONLY(code) code
#define NOT_CHECK_UNHANDLED_OOPS(code)
#else
#define CHECK_UNHANDLED_OOPS_ONLY(code)
#define NOT_CHECK_UNHANDLED_OOPS(code) code
#endif // CHECK_UNHANDLED_OOPS
#ifdef CC_INTERP
#define CC_INTERP_ONLY(code) code
#define NOT_CC_INTERP(code)
#else
#define CC_INTERP_ONLY(code)
#define NOT_CC_INTERP(code) code
#endif // CC_INTERP
#ifdef ASSERT
#define DEBUG_ONLY(code) code
#define NOT_DEBUG(code)
#define NOT_DEBUG_RETURN /*next token must be ;*/
#define debug_only(code) code
#else // ASSERT
#define DEBUG_ONLY(code)
#define NOT_DEBUG(code) code
#define NOT_DEBUG_RETURN {}
#define debug_only(code)
#endif // ASSERT
#ifdef _LP64
#define LP64_ONLY(code) code
#define NOT_LP64(code)
#else // !_LP64
#define LP64_ONLY(code)
#define NOT_LP64(code) code
#endif // _LP64
#ifdef LINUX
#define LINUX_ONLY(code) code
#define NOT_LINUX(code)
#else
#define LINUX_ONLY(code)
#define NOT_LINUX(code) code
#endif
#ifdef AIX
#define AIX_ONLY(code) code
#define NOT_AIX(code)
#else
#define AIX_ONLY(code)
#define NOT_AIX(code) code
#endif
#ifdef SOLARIS
#define SOLARIS_ONLY(code) code
#define NOT_SOLARIS(code)
#else
#define SOLARIS_ONLY(code)
#define NOT_SOLARIS(code) code
#endif
#ifdef _WINDOWS
#define WINDOWS_ONLY(code) code
#define NOT_WINDOWS(code)
#else
#define WINDOWS_ONLY(code)
#define NOT_WINDOWS(code) code
#endif
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
#define BSD_ONLY(code) code
#define NOT_BSD(code)
#else
#define BSD_ONLY(code)
#define NOT_BSD(code) code
#endif
#ifdef _WIN64
#define WIN64_ONLY(code) code
#define NOT_WIN64(code)
#else
#define WIN64_ONLY(code)
#define NOT_WIN64(code) code
#endif
#if defined(ZERO)
#define ZERO_ONLY(code) code
#define NOT_ZERO(code)
#else
#define ZERO_ONLY(code)
#define NOT_ZERO(code) code
#endif
#if defined(SHARK)
#define SHARK_ONLY(code) code
#define NOT_SHARK(code)
#else
#define SHARK_ONLY(code)
#define NOT_SHARK(code) code
#endif
#if defined(IA32) || defined(AMD64)
#define X86
#define X86_ONLY(code) code
#define NOT_X86(code)
#else
#undef X86
#define X86_ONLY(code)
#define NOT_X86(code) code
#endif
#ifdef IA32
#define IA32_ONLY(code) code
#define NOT_IA32(code)
#else
#define IA32_ONLY(code)
#define NOT_IA32(code) code
#endif
#if defined(IA64) && !defined(AIX)
#define IA64_ONLY(code) code
#define NOT_IA64(code)
#else
#define IA64_ONLY(code)
#define NOT_IA64(code) code
#endif
#ifdef AMD64
#define AMD64_ONLY(code) code
#define NOT_AMD64(code)
#else
#define AMD64_ONLY(code)
#define NOT_AMD64(code) code
#endif
#ifdef AARCH64
#define AARCH64_ONLY(code) code
#define NOT_AARCH64(code)
#else
#define AARCH64_ONLY(code)
#define NOT_AARCH64(code) code
#endif
#ifdef SPARC
#define SPARC_ONLY(code) code
#define NOT_SPARC(code)
#else
#define SPARC_ONLY(code)
#define NOT_SPARC(code) code
#endif
#if defined(PPC32) || defined(PPC64)
#ifndef PPC
#define PPC
#endif
#define PPC_ONLY(code) code
#define NOT_PPC(code)
#else
#undef PPC
#define PPC_ONLY(code)
#define NOT_PPC(code) code
#endif
#ifdef PPC32
#define PPC32_ONLY(code) code
#define NOT_PPC32(code)
#else
#define PPC32_ONLY(code)
#define NOT_PPC32(code) code
#endif
#ifdef PPC64
#define PPC64_ONLY(code) code
#define NOT_PPC64(code)
#else
#define PPC64_ONLY(code)
#define NOT_PPC64(code) code
#endif
#ifdef E500V2
#define E500V2_ONLY(code) code
#define NOT_E500V2(code)
#else
#define E500V2_ONLY(code)
#define NOT_E500V2(code) code
#endif
#ifdef ARM
#define ARM_ONLY(code) code
#define NOT_ARM(code)
#else
#define ARM_ONLY(code)
#define NOT_ARM(code) code
#endif
#ifdef ARM32
#define ARM32_ONLY(code) code
#define NOT_ARM32(code)
#else
#define ARM32_ONLY(code)
#define NOT_ARM32(code) code
#endif
#ifdef JAVASE_EMBEDDED
#define EMBEDDED_ONLY(code) code
#define NOT_EMBEDDED(code)
#else
#define EMBEDDED_ONLY(code)
#define NOT_EMBEDDED(code) code
#endif
#ifdef VM_LITTLE_ENDIAN
#define LITTLE_ENDIAN_ONLY(code) code
#define BIG_ENDIAN_ONLY(code)
#else
#define LITTLE_ENDIAN_ONLY(code)
#define BIG_ENDIAN_ONLY(code) code
#endif
#define define_pd_global(type, name, value) const type pd_##name = value;
#endif // SHARE_VM_UTILITIES_MACROS_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/nativeCallStack.cpp
#include "precompiled.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/nativeCallStack.hpp"
NativeCallStack NativeCallStack::EMPTY_STACK(0, false);
NativeCallStack::NativeCallStack(int toSkip, bool fillStack) :
_hash_value(0) {
#if !PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
fillStack = false;
#endif
if (fillStack) {
os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip);
} else {
for (int index = 0; index < NMT_TrackingStackDepth; index ++) {
_stack[index] = NULL;
}
}
}
NativeCallStack::NativeCallStack(address* pc, int frameCount) {
int frameToCopy = (frameCount < NMT_TrackingStackDepth) ?
frameCount : NMT_TrackingStackDepth;
int index;
for (index = 0; index < frameToCopy; index ++) {
_stack[index] = pc[index];
}
for (; index < NMT_TrackingStackDepth; index ++) {
_stack[index] = NULL;
}
_hash_value = 0;
}
int NativeCallStack::frames() const {
int index;
for (index = 0; index < NMT_TrackingStackDepth; index ++) {
if (_stack[index] == NULL) {
break;
}
}
return index;
}
unsigned int NativeCallStack::hash() const {
uintptr_t hash_val = _hash_value;
if (hash_val == 0) {
for (int index = 0; index < NMT_TrackingStackDepth; index++) {
if (_stack[index] == NULL) break;
hash_val += (uintptr_t)_stack[index];
}
NativeCallStack* p = const_cast<NativeCallStack*>(this);
p->_hash_value = (unsigned int)(hash_val & 0xFFFFFFFF);
}
return _hash_value;
}
void NativeCallStack::print_on(outputStream* out) const {
print_on(out, 0);
}
void NativeCallStack::print_on(outputStream* out, int indent) const {
address pc;
char buf[1024];
int offset;
if (is_empty()) {
for (int index = 0; index < indent; index ++) out->print(" ");
#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
out->print("[BOOTSTRAP]");
#else
out->print("[No stack]");
#endif
} else {
for (int frame = 0; frame < NMT_TrackingStackDepth; frame ++) {
pc = get_frame(frame);
if (pc == NULL) break;
for (int index = 0; index < indent; index ++) out->print(" ");
if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
out->print_cr("[" PTR_FORMAT "] %s+0x%x", p2i(pc), buf, offset);
} else {
out->print_cr("[" PTR_FORMAT "]", p2i(pc));
}
}
}
}
C:\hotspot-69087d08d473\src\share\vm/utilities/nativeCallStack.hpp
#ifndef SHARE_VM_UTILITIES_NATIVE_CALL_STACK_HPP
#define SHARE_VM_UTILITIES_NATIVE_CALL_STACK_HPP
#include "memory/allocation.hpp"
#include "services/nmtCommon.hpp"
#include "utilities/ostream.hpp"
class MemTracker;
class NativeCallStack : public StackObj {
friend class MemTracker;
private:
address _stack[NMT_TrackingStackDepth];
unsigned int _hash_value;
static NativeCallStack EMPTY_STACK;
public:
NativeCallStack(int toSkip = 0, bool fillStack = false);
NativeCallStack(address* pc, int frameCount);
static inline const NativeCallStack& empty_stack() {
return EMPTY_STACK;
}
inline bool is_empty() const {
return _stack[0] == NULL;
}
int frames() const;
inline int compare(const NativeCallStack& other) const {
return memcmp(_stack, other._stack, sizeof(_stack));
}
inline bool equals(const NativeCallStack& other) const {
if (hash() != other.hash()) return false;
return compare(other) == 0;
}
inline address get_frame(int index) const {
assert(index >= 0 && index < NMT_TrackingStackDepth, "Index out of bound");
return _stack[index];
}
unsigned int hash() const;
void print_on(outputStream* out) const;
void print_on(outputStream* out, int indent) const;
};
#endif
C:\hotspot-69087d08d473\src\share\vm/utilities/numberSeq.cpp
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/numberSeq.hpp"
AbsSeq::AbsSeq(double alpha) :
_num(0), _sum(0.0), _sum_of_squares(0.0),
_davg(0.0), _dvariance(0.0), _alpha(alpha) {
}
void AbsSeq::add(double val) {
if (_num == 0) {
_davg = val;
_dvariance = 0.0;
} else {
_davg = (1.0 - _alpha) * val + _alpha * _davg;
double diff = val - _davg;
_dvariance = (1.0 - _alpha) * diff * diff + _alpha * _dvariance;
}
}
double AbsSeq::avg() const {
if (_num == 0)
return 0.0;
else
return _sum / total();
}
double AbsSeq::variance() const {
if (_num <= 1)
return 0.0;
double x_bar = avg();
double result = _sum_of_squares / total() - x_bar * x_bar;
if (result < 0.0) {
result = 0.0;
}
return result;
}
double AbsSeq::sd() const {
double var = variance();
guarantee( var >= 0.0, "variance should not be negative" );
return sqrt(var);
}
double AbsSeq::davg() const {
return _davg;
}
double AbsSeq::dvariance() const {
if (_num <= 1)
return 0.0;
double result = _dvariance;
if (result < 0.0) {
guarantee(-0.1 < result && result < 0.0,
"if variance is negative, it should be very small");
result = 0.0;
}
return result;
}
double AbsSeq::dsd() const {
double var = dvariance();
guarantee( var >= 0.0, "variance should not be negative" );
return sqrt(var);
}
NumberSeq::NumberSeq(double alpha) :
AbsSeq(alpha), _maximum(0.0), _last(0.0) {
}
bool NumberSeq::check_nums(NumberSeq *total, int n, NumberSeq **parts) {
for (int i = 0; i < n; ++i) {
if (parts[i] != NULL && total->num() != parts[i]->num())
return false;
}
return true;
}
void NumberSeq::add(double val) {
AbsSeq::add(val);
_last = val;
if (_num == 0) {
_maximum = val;
} else {
if (val > _maximum)
_maximum = val;
}
_sum += val;
_sum_of_squares += val * val;
++_num;
}
TruncatedSeq::TruncatedSeq(int length, double alpha):
AbsSeq(alpha), _length(length), _next(0) {
_sequence = NEW_C_HEAP_ARRAY(double, _length, mtInternal);
for (int i = 0; i < _length; ++i)
_sequence[i] = 0.0;
}
TruncatedSeq::~TruncatedSeq() {
FREE_C_HEAP_ARRAY(double, _sequence, mtGC);
}
void TruncatedSeq::add(double val) {
AbsSeq::add(val);
double old_val = _sequence[_next];
_sum -= old_val;
_sum_of_squares -= old_val * old_val;
_sum += val;
_sum_of_squares += val * val;
_sequence[_next] = val;
_next = (_next + 1) % _length;
if (_num < _length)
++_num;
guarantee( variance() > -1.0, "variance should be >= 0" );
}
double TruncatedSeq::maximum() const {
if (_num == 0)
return 0.0;
double ret = _sequence[0];
for (int i = 1; i < _num; ++i) {
double val = _sequence[i];
if (val > ret)
ret = val;
}
return ret;
}
double TruncatedSeq::last() const {
if (_num == 0)
return 0.0;
unsigned last_index = (_next + _length - 1) % _length;
return _sequence[last_index];
}
double TruncatedSeq::oldest() const {
if (_num == 0)
return 0.0;
else if (_num < _length)
return _sequence[0];
else {
return _sequence[_next];
}
}
double TruncatedSeq::predict_next() const {
if (_num == 0)
return 0.0;
double num = (double) _num;
double x_squared_sum = 0.0;
double x_sum = 0.0;
double y_sum = 0.0;
double xy_sum = 0.0;
double x_avg = 0.0;
double y_avg = 0.0;
int first = (_next + _length - _num) % _length;
for (int i = 0; i < _num; ++i) {
double x = (double) i;
double y = _sequence[(first + i) % _length];
x_squared_sum += x * x;
x_sum += x;
y_sum += y;
xy_sum += x * y;
}
x_avg = x_sum / num;
y_avg = y_sum / num;
double Sxx = x_squared_sum - x_sum * x_sum / num;
double Sxy = xy_sum - x_sum * y_sum / num;
double b1 = Sxy / Sxx;
double b0 = y_avg - b1 * x_avg;
return b0 + b1 * num;
}
void AbsSeq::dump() { dump_on(gclog_or_tty); }
void AbsSeq::dump_on(outputStream* s) {
s->print_cr("\t _num = %d, _sum = %7.3f, _sum_of_squares = %7.3f",
_num, _sum, _sum_of_squares);
s->print_cr("\t _davg = %7.3f, _dvariance = %7.3f, _alpha = %7.3f",
_davg, _dvariance, _alpha);
}
void NumberSeq::dump_on(outputStream* s) {
AbsSeq::dump_on(s);
s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f", _last, _maximum);
}
void TruncatedSeq::dump_on(outputStream* s) {
AbsSeq::dump_on(s);
s->print_cr("\t\t _length = %d, _next = %d", _length, _next);
for (int i = 0; i < _length; i++) {
if (i%5 == 0) {
s->cr();
s->print("\t");
}
s->print("\t[%d]=%7.3f", i, _sequence[i]);
}
s->cr();
}
C:\hotspot-69087d08d473\src\share\vm/utilities/numberSeq.hpp
#ifndef SHARE_VM_UTILITIES_NUMBERSEQ_HPP
#define SHARE_VM_UTILITIES_NUMBERSEQ_HPP
#include "memory/allocation.hpp"
#define DEFAULT_ALPHA_VALUE 0.7
class AbsSeq: public CHeapObj<mtInternal> {
private:
void init(double alpha);
protected:
int _num; // the number of elements in the sequence
double _sum; // the sum of the elements in the sequence
double _sum_of_squares; // the sum of squares of the elements in the sequence
double _davg; // decaying average
double _dvariance; // decaying variance
double _alpha; // factor for the decaying average / variance
virtual double total() const { return (double) _num; };
public:
AbsSeq(double alpha = DEFAULT_ALPHA_VALUE);
virtual void add(double val); // adds a new element to the sequence
void add(unsigned val) { add((double) val); }
virtual double maximum() const = 0; // maximum element in the sequence
virtual double last() const = 0; // last element added in the sequence
int num() const { return _num; }
double sum() const { return _sum; }
double avg() const; // the average of the sequence
double variance() const; // the variance of the sequence
double sd() const; // the standard deviation of the sequence
double davg() const; // decaying average
double dvariance() const; // decaying variance
double dsd() const; // decaying "standard deviation"
virtual void dump();
virtual void dump_on(outputStream* s);
};
class NumberSeq: public AbsSeq {
private:
bool check_nums(NumberSeq* total, int n, NumberSeq** parts);
protected:
double _last;
double _maximum; // keep track of maximum value
public:
NumberSeq(double alpha = DEFAULT_ALPHA_VALUE);
virtual void add(double val);
virtual double maximum() const { return _maximum; }
virtual double last() const { return _last; }
virtual void dump_on(outputStream* s);
};
class TruncatedSeq: public AbsSeq {
private:
enum PrivateConstants {
DefaultSeqLength = 10
};
void init();
protected:
double *_sequence; // buffers the last L elements in the sequence
int _length; // this is L
int _next; // oldest slot in the array, i.e. next to be overwritten
public:
TruncatedSeq(int length = DefaultSeqLength,
double alpha = DEFAULT_ALPHA_VALUE);
~TruncatedSeq();
virtual void add(double val);
virtual double maximum() const;
virtual double last() const; // the last value added to the sequence
double oldest() const; // the oldest valid value in the sequence
double predict_next() const; // prediction based on linear regression
virtual void dump_on(outputStream* s);
};
#endif // SHARE_VM_UTILITIES_NUMBERSEQ_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/ostream.cpp
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
#include "gc_implementation/shared/gcId.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/ostream.hpp"
#include "utilities/top.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "os_aix.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
extern "C" void jio_print(const char* s); // Declarationtion of jvm method
outputStream::outputStream(int width) {
_width = width;
_position = 0;
_newlines = 0;
_precount = 0;
_indentation = 0;
}
outputStream::outputStream(int width, bool has_time_stamps) {
_width = width;
_position = 0;
_newlines = 0;
_precount = 0;
_indentation = 0;
if (has_time_stamps) _stamp.update();
}
void outputStream::update_position(const char* s, size_t len) {
for (size_t i = 0; i < len; i++) {
char ch = s[i];
if (ch == '\n') {
_newlines += 1;
_precount += _position + 1;
_position = 0;
} else if (ch == '\t') {
int tw = 8 - (_position & 7);
_position += tw;
_precount -= tw-1; // invariant: _precount + _position == total count
} else {
_position += 1;
}
}
}
const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
const char* format, va_list ap,
bool add_cr,
size_t& result_len) {
assert(buflen >= 2, "buffer too small");
const char* result;
if (add_cr) buflen--;
if (!strchr(format, '%')) {
result = format;
result_len = strlen(result);
if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
} else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') {
result = va_arg(ap, const char*);
result_len = strlen(result);
if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
} else {
int written = os::vsnprintf(buffer, buflen, format, ap);
assert(written >= 0, "vsnprintf encoding error");
result = buffer;
if ((size_t)written < buflen) {
result_len = written;
} else {
DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
result_len = buflen - 1;
}
}
if (add_cr) {
if (result != buffer) {
memcpy(buffer, result, result_len);
result = buffer;
}
buffer[result_len++] = '\n';
buffer[result_len] = 0;
}
return result;
}
void outputStream::print(const char* format, ...) {
char buffer[O_BUFLEN];
va_list ap;
va_start(ap, format);
size_t len;
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
write(str, len);
va_end(ap);
}
void outputStream::print_cr(const char* format, ...) {
char buffer[O_BUFLEN];
va_list ap;
va_start(ap, format);
size_t len;
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len);
write(str, len);
va_end(ap);
}
void outputStream::vprint(const char *format, va_list argptr) {
char buffer[O_BUFLEN];
size_t len;
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len);
write(str, len);
}
void outputStream::vprint_cr(const char* format, va_list argptr) {
char buffer[O_BUFLEN];
size_t len;
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len);
write(str, len);
}
void outputStream::fill_to(int col) {
int need_fill = col - position();
sp(need_fill);
}
void outputStream::move_to(int col, int slop, int min_space) {
if (position() >= col + slop)
cr();
int need_fill = col - position();
if (need_fill < min_space)
need_fill = min_space;
sp(need_fill);
}
void outputStream::put(char ch) {
assert(ch != 0, "please fix call site");
char buf[] = { ch, '\0' };
write(buf, 1);
}
#define SP_USE_TABS false
void outputStream::sp(int count) {
if (count < 0) return;
if (SP_USE_TABS && count >= 8) {
int target = position() + count;
while (count >= 8) {
this->write("\t", 1);
count -= 8;
}
count = target - position();
}
while (count > 0) {
int nw = (count > 8) ? 8 : count;
this->write(" ", nw);
count -= nw;
}
}
void outputStream::cr() {
this->write("\n", 1);
}
void outputStream::stamp() {
if (! _stamp.is_updated()) {
_stamp.update(); // start at 0 on first call to stamp()
}
char buf[40];
jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds());
print_raw(buf);
}
void outputStream::stamp(bool guard,
const char* prefix,
const char* suffix) {
if (!guard) {
return;
}
print_raw(prefix);
stamp();
print_raw(suffix);
}
void outputStream::date_stamp(bool guard,
const char* prefix,
const char* suffix) {
if (!guard) {
return;
}
print_raw(prefix);
static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz";
static const int buffer_length = 32;
char buffer[buffer_length];
const char* iso8601_result = os::iso8601_time(buffer, buffer_length);
if (iso8601_result != NULL) {
print_raw(buffer);
} else {
print_raw(error_time);
}
print_raw(suffix);
return;
}
void outputStream::gclog_stamp(const GCId& gc_id) {
date_stamp(PrintGCDateStamps);
stamp(PrintGCTimeStamps);
if (PrintGCID) {
print("#%u: ", gc_id.id());
}
}
outputStream& outputStream::indent() {
while (_position < _indentation) sp();
return *this;
}
void outputStream::print_jlong(jlong value) {
print(JLONG_FORMAT, value);
}
void outputStream::print_julong(julong value) {
print(JULONG_FORMAT, value);
}
void outputStream::print_data(void* data, size_t len, bool with_ascii) {
size_t limit = (len + 16) / 16 * 16;
for (size_t i = 0; i < limit; ++i) {
if (i % 16 == 0) {
indent().print(SIZE_FORMAT_HEX_W(07) ":", i);
}
if (i % 2 == 0) {
print(" ");
}
if (i < len) {
print("%02x", ((unsigned char*)data)[i]);
} else {
print(" ");
}
if ((i + 1) % 16 == 0) {
if (with_ascii) {
print(" ");
for (size_t j = 0; j < 16; ++j) {
size_t idx = i + j - 15;
if (idx < len) {
char c = ((char*)data)[idx];
print("%c", c >= 32 && c <= 126 ? c : '.');
}
}
}
cr();
}
}
}
stringStream::stringStream(size_t initial_size) : outputStream() {
buffer_length = initial_size;
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
buffer_pos = 0;
buffer_fixed = false;
DEBUG_ONLY(rm = Thread::current()->current_resource_mark();)
}
stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() {
buffer_length = fixed_buffer_size;
buffer = fixed_buffer;
buffer_pos = 0;
buffer_fixed = true;
}
void stringStream::write(const char* s, size_t len) {
size_t write_len = len; // number of non-null bytes to write
size_t end = buffer_pos + len + 1; // position after write and final '\0'
if (end > buffer_length) {
if (buffer_fixed) {
end = buffer_length;
write_len = end - buffer_pos - 1; // leave room for the final '\0'
} else {
if (end < buffer_length * 2) {
end = buffer_length * 2;
}
char* oldbuf = buffer;
assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
"stringStream is re-allocated with a different ResourceMark");
buffer = NEW_RESOURCE_ARRAY(char, end);
if (buffer_pos > 0) {
memcpy(buffer, oldbuf, buffer_pos);
}
buffer_length = end;
}
}
guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
if (write_len > 0) {
buffer[buffer_pos + write_len] = 0;
memcpy(buffer + buffer_pos, s, write_len);
buffer_pos += write_len;
}
update_position(s, len);
}
char* stringStream::as_string() {
char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
strncpy(copy, buffer, buffer_pos);
copy[buffer_pos] = 0; // terminating null
return copy;
}
stringStream::~stringStream() {}
xmlStream* xtty;
outputStream* tty;
outputStream* gclog_or_tty;
CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
extern Mutex* tty_lock;
#define EXTRACHARLEN 32
#define CURRENTAPPX ".current"
char* get_datetime_string(char *buf, size_t len) {
os::local_time_string(buf, len);
int i = (int)strlen(buf);
while (i-- >= 0) {
if (buf[i] == ' ') buf[i] = '_';
else if (buf[i] == ':') buf[i] = '-';
}
return buf;
}
static const char* make_log_name_internal(const char* log_name, const char* force_directory,
int pid, const char* tms) {
const char* basename = log_name;
char file_sep = os::file_separator()[0];
const char* cp;
char pid_text[32];
for (cp = log_name; *cp != '\0'; cp++) {
if (*cp == '/' || *cp == file_sep) {
basename = cp + 1;
}
}
const char* nametail = log_name;
size_t buffer_length;
if (force_directory != NULL) {
buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
strlen(basename) + 1;
} else {
buffer_length = strlen(log_name) + 1;
}
const char* pts = strstr(basename, "%p");
int pid_pos = (pts == NULL) ? -1 : (pts - nametail);
if (pid_pos >= 0) {
jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid);
buffer_length += strlen(pid_text);
}
pts = strstr(basename, "%t");
int tms_pos = (pts == NULL) ? -1 : (pts - nametail);
if (tms_pos >= 0) {
buffer_length += strlen(tms);
}
if (buffer_length > JVM_MAXPATHLEN) {
return NULL;
}
char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
strcpy(buf, "");
if (force_directory != NULL) {
strcat(buf, force_directory);
strcat(buf, os::file_separator());
nametail = basename; // completely skip directory prefix
}
int first = -1, second = -1;
const char *p1st = NULL;
const char *p2nd = NULL;
if (pid_pos >= 0 && tms_pos >= 0) {
if (pid_pos < tms_pos) {
first = pid_pos;
p1st = pid_text;
second = tms_pos;
p2nd = tms;
} else {
first = tms_pos;
p1st = tms;
second = pid_pos;
p2nd = pid_text;
}
} else if (pid_pos >= 0) {
first = pid_pos;
p1st = pid_text;
} else if (tms_pos >= 0) {
first = tms_pos;
p1st = tms;
}
int buf_pos = (int)strlen(buf);
const char* tail = nametail;
if (first >= 0) {
tail = nametail + first + 2;
strncpy(&buf[buf_pos], nametail, first);
strcpy(&buf[buf_pos + first], p1st);
buf_pos = (int)strlen(buf);
if (second >= 0) {
strncpy(&buf[buf_pos], tail, second - first - 2);
strcpy(&buf[buf_pos + second - first - 2], p2nd);
tail = nametail + second + 2;
}
}
strcat(buf, tail); // append rest of name, or all of name
return buf;
}
static const char* make_log_name(const char* log_name, const char* force_directory) {
char timestr[32];
get_datetime_string(timestr, sizeof(timestr));
return make_log_name_internal(log_name, force_directory, os::current_process_id(),
timestr);
}
#ifndef PRODUCT
void test_loggc_filename() {
int pid;
char tms[32];
char i_result[JVM_MAXPATHLEN];
const char* o_result;
get_datetime_string(tms, sizeof(tms));
pid = os::current_process_id();
jio_snprintf(i_result, JVM_MAXPATHLEN, "test.log", tms);
o_result = make_log_name_internal("test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%s-pid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%spid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u%s.log", pid, tms);
o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u-test.log", pid);
o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
jio_snprintf(i_result, JVM_MAXPATHLEN, "%s.log", tms);
o_result = make_log_name_internal("%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
{
char longest_name[JVM_MAXPATHLEN];
memset(longest_name, 'a', sizeof(longest_name));
longest_name[JVM_MAXPATHLEN - 1] = '\0';
o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
assert(strcmp(longest_name, o_result) == 0, err_msg("longest name does not match. expected '%s' but got '%s'", longest_name, o_result));
FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
}
{
char too_long_name[JVM_MAXPATHLEN + 100];
int too_long_length = sizeof(too_long_name);
memset(too_long_name, 'a', too_long_length);
too_long_name[too_long_length - 1] = '\0';
o_result = make_log_name_internal((const char*)&too_long_name, NULL, pid, tms);
assert(o_result == NULL, err_msg("Too long file name should return NULL, but got '%s'", o_result));
}
{
char longest_name[JVM_MAXPATHLEN];
memset(longest_name, 'a', JVM_MAXPATHLEN);
longest_name[JVM_MAXPATHLEN - 3] = '%';
longest_name[JVM_MAXPATHLEN - 2] = 't';
longest_name[JVM_MAXPATHLEN - 1] = '\0';
o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
assert(o_result == NULL, err_msg("Too long file name after timestamp expansion should return NULL, but got '%s'", o_result));
}
{
char longest_name[JVM_MAXPATHLEN];
memset(longest_name, 'a', JVM_MAXPATHLEN);
longest_name[JVM_MAXPATHLEN - 3] = '%';
longest_name[JVM_MAXPATHLEN - 2] = 'p';
longest_name[JVM_MAXPATHLEN - 1] = '\0';
o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
assert(o_result == NULL, err_msg("Too long file name after pid expansion should return NULL, but got '%s'", o_result));
}
}
void check_snprintf_result(int expected, size_t limit, int actual, bool expect_count) {
if (expect_count || ((size_t)expected < limit)) {
assert(expected == actual, "snprintf result not expected value");
} else {
if (expected >= (int) limit) {
assert(actual == -1, "snprintf result should be -1 for expected >= limit");
} else {
assert(actual > 0, "snprintf result should be >0 for expected < limit");
}
}
}
template<typename PrintFn>
void test_snprintf(PrintFn pf, bool expect_count) {
const char expected[] = "abcdefghijklmnopqrstuvwxyz";
const int expected_len = sizeof(expected) - 1;
const size_t padding_size = 10;
char buffer[2 * (sizeof(expected) + padding_size)];
char check_buffer[sizeof(buffer)];
const char check_char = '1'; // Something not in expected.
memset(check_buffer, check_char, sizeof(check_buffer));
const size_t sizes_to_test[] = {
sizeof(buffer) - padding_size, // Fits, with plenty of space to spare.
sizeof(buffer)/2, // Fits, with space to spare.
sizeof(buffer)/4, // Doesn't fit.
sizeof(expected) + padding_size + 1, // Fits, with a little room to spare
sizeof(expected) + padding_size, // Fits exactly.
sizeof(expected) + padding_size - 1, // Doesn't quite fit.
2, // One char + terminating NUL.
1, // Only space for terminating NUL.
0 }; // No space at all.
for (unsigned i = 0; i < ARRAY_SIZE(sizes_to_test); ++i) {
memset(buffer, check_char, sizeof(buffer)); // To catch stray writes.
size_t test_size = sizes_to_test[i];
ResourceMark rm;
stringStream s;
s.print("test_size: " SIZE_FORMAT, test_size);
size_t prefix_size = padding_size;
guarantee(test_size <= (sizeof(buffer) - prefix_size), "invariant");
size_t write_size = MIN2(sizeof(expected), test_size);
size_t suffix_size = sizeof(buffer) - prefix_size - write_size;
char* write_start = buffer + prefix_size;
char* write_end = write_start + write_size;
int result = pf(write_start, test_size, "%s", expected);
check_snprintf_result(expected_len, test_size, result, expect_count);
if (test_size > 0) {
assert(0 == strncmp(write_start, expected, write_size - 1), "strncmp failure");
assert('\0' == write_start[write_size - 1], "null terminator failure");
} else {
guarantee(test_size == 0, "invariant");
guarantee(write_size == 0, "invariant");
guarantee(prefix_size + suffix_size == sizeof(buffer), "invariant");
guarantee(write_start == write_end, "invariant");
}
assert(0 == strncmp(buffer, check_buffer, prefix_size), "prefix scribble");
assert(0 == strncmp(write_end, check_buffer, suffix_size), "suffix scribble");
}
check_snprintf_result(0, 0, pf(NULL, 0, "%s", ""), expect_count);
check_snprintf_result(0, 0, pf(NULL, 0, ""), expect_count);
}
static int vsnprintf_wrapper(char* buf, size_t len, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
int result = os::vsnprintf(buf, len, fmt, args);
PRAGMA_DIAG_POP
va_end(args);
return result;
}
extern "C" {
int jio_vsnprintf(char*, size_t, const char*, va_list);
int jio_snprintf(char*, size_t, const char*, ...);
}
static int jio_vsnprintf_wrapper(char* buf, size_t len, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
int result = jio_vsnprintf(buf, len, fmt, args);
va_end(args);
return result;
}
void test_snprintf() {
test_snprintf(vsnprintf_wrapper, true);
test_snprintf(os::snprintf, true);
test_snprintf(jio_vsnprintf_wrapper, false); // jio_vsnprintf returns -1 on error including exceeding buffer size
test_snprintf(jio_snprintf, false); // jio_snprintf calls jio_vsnprintf
}
#endif // PRODUCT
fileStream::fileStream(const char* file_name) {
_file = fopen(file_name, "w");
if (_file != NULL) {
_need_close = true;
} else {
warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
_need_close = false;
}
}
fileStream::fileStream(const char* file_name, const char* opentype) {
_file = fopen(file_name, opentype);
if (_file != NULL) {
_need_close = true;
} else {
warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
_need_close = false;
}
}
void fileStream::write(const char* s, size_t len) {
if (_file != NULL) {
size_t count = fwrite(s, 1, len, _file);
}
update_position(s, len);
}
long fileStream::fileSize() {
long size = -1;
if (_file != NULL) {
long pos = ::ftell(_file);
if (::fseek(_file, 0, SEEK_END) == 0) {
size = ::ftell(_file);
}
::fseek(_file, pos, SEEK_SET);
}
return size;
}
char* fileStream::readln(char *data, int count ) {
char * ret = ::fgets(data, count, _file);
data[::strlen(data)-1] = '\0';
return ret;
}
fileStream::~fileStream() {
if (_file != NULL) {
if (_need_close) fclose(_file);
_file = NULL;
}
}
void fileStream::flush() {
fflush(_file);
}
fdStream::fdStream(const char* file_name) {
_fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
_need_close = true;
}
fdStream::~fdStream() {
if (_fd != -1) {
if (_need_close) close(_fd);
_fd = -1;
}
}
void fdStream::write(const char* s, size_t len) {
if (_fd != -1) {
size_t count = ::write(_fd, s, (int)len);
}
update_position(s, len);
}
void gcLogFileStream::dump_loggc_header() {
if (is_open()) {
print_cr("%s", Abstract_VM_Version::internal_vm_info_string());
os::print_memory_info(this);
print("CommandLine flags: ");
CommandLineFlags::printSetFlags(this);
}
}
gcLogFileStream::~gcLogFileStream() {
if (_file != NULL) {
if (_need_close) fclose(_file);
_file = NULL;
}
if (_file_name != NULL) {
FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
_file_name = NULL;
}
delete _file_lock;
}
gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
_cur_file_num = 0;
_bytes_written = 0L;
_file_name = make_log_name(file_name, NULL);
if (_file_name == NULL) {
warning("Cannot open file %s: file name is too long.\n", file_name);
_need_close = false;
UseGCLogFileRotation = false;
return;
}
if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
char tempbuf[JVM_MAXPATHLEN];
jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
_file = fopen(tempbuf, "w");
} else {
_file = fopen(_file_name, "w");
}
if (_file != NULL) {
_need_close = true;
dump_loggc_header();
if (UseGCLogFileRotation) {
_file_lock = new Mutex(Mutex::leaf, "GCLogFile");
}
} else {
warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
_need_close = false;
}
}
void gcLogFileStream::write(const char* s, size_t len) {
if (_file != NULL) {
Thread* thread = ThreadLocalStorage::thread();
if (!thread || !_file_lock || (thread->is_VM_thread()
&& ((VMThread* )thread)->is_gclog_reentry())) {
size_t count = fwrite(s, 1, len, _file);
_bytes_written += count;
}
else {
MutexLockerEx ml(_file_lock, Mutex::_no_safepoint_check_flag);
size_t count = fwrite(s, 1, len, _file);
_bytes_written += count;
}
}
update_position(s, len);
}
void gcLogFileStream::rotate_log(bool force, outputStream* out) {
#ifdef ASSERT
Thread *thread = Thread::current();
assert(thread == NULL ||
(thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()),
"Must be VMThread at safepoint");
#endif
VMThread* vmthread = VMThread::vm_thread();
{
MutexLockerEx ml(_file_lock, Mutex::_no_safepoint_check_flag);
vmthread->set_gclog_reentry(true);
rotate_log_impl(force, out);
vmthread->set_gclog_reentry(false);
}
}
void gcLogFileStream::rotate_log_impl(bool force, outputStream* out) {
char time_msg[O_BUFLEN];
char time_str[EXTRACHARLEN];
char current_file_name[JVM_MAXPATHLEN];
char renamed_file_name[JVM_MAXPATHLEN];
if (!should_rotate(force)) {
return;
}
if (NumberOfGCLogFiles == 1) {
rewind();
_bytes_written = 0L;
jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n",
_file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
write(time_msg, strlen(time_msg));
if (out != NULL) {
out->print("%s", time_msg);
}
dump_loggc_header();
return;
}
#if defined(_WINDOWS)
#ifndef F_OK
#define F_OK 0
#endif
#endif // _WINDOWS
if (_file != NULL) {
jio_snprintf(renamed_file_name, JVM_MAXPATHLEN, "%s.%d",
_file_name, _cur_file_num);
int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN,
"%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
if (result >= JVM_MAXPATHLEN) {
warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
return;
}
const char* msg = force ? "GC log rotation request has been received."
: "GC log file has reached the maximum size.";
jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n",
os::local_time_string((char *)time_str, sizeof(time_str)),
msg, renamed_file_name);
write(time_msg, strlen(time_msg));
if (out != NULL) {
out->print("%s", time_msg);
}
fclose(_file);
_file = NULL;
bool can_rename = true;
if (access(current_file_name, F_OK) != 0) {
warning("No source file exists, cannot rename\n");
can_rename = false;
}
if (can_rename) {
if (access(renamed_file_name, F_OK) == 0) {
if (remove(renamed_file_name) != 0) {
warning("Could not delete existing file %s\n", renamed_file_name);
can_rename = false;
}
} else {
}
}
if (can_rename && rename(current_file_name, renamed_file_name) != 0) {
warning("Could not rename %s to %s\n", _file_name, renamed_file_name);
}
}
_cur_file_num++;
if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX,
_file_name, _cur_file_num);
if (result >= JVM_MAXPATHLEN) {
warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
return;
}
_file = fopen(current_file_name, "w");
if (_file != NULL) {
_bytes_written = 0L;
_need_close = true;
jio_snprintf(current_file_name, JVM_MAXPATHLEN,
"%s.%d", _file_name, _cur_file_num);
jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
os::local_time_string((char *)time_str, sizeof(time_str)), current_file_name);
write(time_msg, strlen(time_msg));
if (out != NULL) {
out->print("%s", time_msg);
}
dump_loggc_header();
if (access(current_file_name, F_OK) == 0) {
if (remove(current_file_name) != 0) {
warning("Could not delete existing file %s\n", current_file_name);
}
}
} else {
warning("failed to open rotation log file %s due to %s\n"
"Turned off GC log file rotation\n",
_file_name, strerror(errno));
_need_close = false;
FLAG_SET_DEFAULT(UseGCLogFileRotation, false);
}
}
defaultStream* defaultStream::instance = NULL;
int defaultStream::_output_fd = 1;
int defaultStream::_error_fd = 2;
FILE* defaultStream::_output_stream = stdout;
FILE* defaultStream::_error_stream = stderr;
#define LOG_MAJOR_VERSION 160
#define LOG_MINOR_VERSION 1
void defaultStream::init() {
_inited = true;
if (LogVMOutput || LogCompilation) {
init_log();
}
}
bool defaultStream::has_log_file() {
if (!_inited && !is_error_reported()) init();
return _log_file != NULL;
}
fileStream* defaultStream::open_file(const char* log_name) {
const char* try_name = make_log_name(log_name, NULL);
if (try_name == NULL) {
warning("Cannot open file %s: file name is too long.\n", log_name);
return NULL;
}
fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
if (file->is_open()) {
return file;
}
delete file;
char warnbuf[O_BUFLEN*2];
jio_snprintf(warnbuf, sizeof(warnbuf), "Warning: Cannot open log file: %s\n", log_name);
jio_print(warnbuf);
try_name = make_log_name(log_name, os::get_temp_directory());
if (try_name == NULL) {
warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory());
return NULL;
}
jio_snprintf(warnbuf, sizeof(warnbuf),
"Warning: Forcing option -XX:LogFile=%s\n", try_name);
jio_print(warnbuf);
file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
if (file->is_open()) {
return file;
}
delete file;
return NULL;
}
void defaultStream::init_log() {
const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log";
fileStream* file = open_file(log_name);
if (file != NULL) {
_log_file = file;
_outer_xmlStream = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
start_log();
} else {
LogVMOutput = false;
DisplayVMOutput = true;
LogCompilation = false;
}
}
void defaultStream::start_log() {
xmlStream*xs = _outer_xmlStream;
if (this == tty) xtty = xs;
xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>");
jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds();
xs->head("hotspot_log version='%d %d'"
" process='%d' time_ms='" INT64_FORMAT "'",
LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
os::current_process_id(), (int64_t)time_ms);
xs->head("vm_version");
xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr();
xs->tail("name");
xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr();
xs->tail("release");
xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr();
xs->tail("info");
xs->tail("vm_version");
xs->head("vm_arguments"); // Cf. Arguments::print_on()
if (Arguments::num_jvm_flags() > 0) {
xs->head("flags");
Arguments::print_jvm_flags_on(xs->text());
xs->tail("flags");
}
if (Arguments::num_jvm_args() > 0) {
xs->head("args");
Arguments::print_jvm_args_on(xs->text());
xs->tail("args");
}
if (Arguments::java_command() != NULL) {
xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command());
xs->tail("command");
}
if (Arguments::sun_java_launcher() != NULL) {
xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher());
xs->tail("launcher");
}
if (Arguments::system_properties() != NULL) {
xs->head("properties");
for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
xs->text()->print_cr("%s=%s", p->key(), p->value());
}
xs->tail("properties");
}
xs->tail("vm_arguments");
xs->head("tty");
xs->_text = this; // requires friend declaration!
}
void defaultStream::finish_log() {
xmlStream* xs = _outer_xmlStream;
xs->done("tty");
CompileLog::finish_log(xs->out()); // write compile logging, if any, now
xs->done("hotspot_log");
xs->flush();
fileStream* file = _log_file;
_log_file = NULL;
delete _outer_xmlStream;
_outer_xmlStream = NULL;
file->flush();
delete file;
}
void defaultStream::finish_log_on_error(char *buf, int buflen) {
xmlStream* xs = _outer_xmlStream;
if (xs && xs->out()) {
xs->done_raw("tty");
CompileLog::finish_log_on_error(xs->out(), buf, buflen); // write compile logging, if any, now
xs->done_raw("hotspot_log");
xs->flush();
fileStream* file = _log_file;
_log_file = NULL;
_outer_xmlStream = NULL;
if (file) {
file->flush();
}
}
}
intx defaultStream::hold(intx writer_id) {
bool has_log = has_log_file(); // check before locking
if (// impossible, but who knows?
writer_id == NO_WRITER ||
tty_lock == NULL ||
ThreadLocalStorage::thread() == NULL ||
!SerializeVMOutput ||
is_error_reported() ||
(SafepointSynchronize::is_synchronizing() &&
Thread::current()->is_VM_thread())
) {
return NO_WRITER;
}
if (_writer == writer_id) {
return NO_WRITER;
}
tty_lock->lock_without_safepoint_check();
if (writer_id != _last_writer) {
if (has_log) {
_log_file->bol();
_log_file->print_cr("<writer thread='" UINTX_FORMAT "'/>", writer_id);
}
_last_writer = writer_id;
}
_writer = writer_id;
return writer_id;
}
void defaultStream::release(intx holder) {
if (holder == NO_WRITER) {
return;
}
if (_writer != holder) {
return; // already unlocked, perhaps via break_tty_lock_for_safepoint
}
_writer = NO_WRITER;
tty_lock->unlock();
}
static void call_jio_print(const char* s, size_t len) {
char buffer[O_BUFLEN+100];
if (len > sizeof(buffer)-1) {
warning("increase O_BUFLEN in ostream.cpp -- output truncated");
len = sizeof(buffer)-1;
}
strncpy(buffer, s, len);
buffer[len] = '\0';
jio_print(buffer);
}
void defaultStream::write(const char* s, size_t len) {
intx thread_id = os::current_thread_id();
intx holder = hold(thread_id);
if (DisplayVMOutput &&
(_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) {
if (s[len] == '\0') {
jio_print(s);
} else {
call_jio_print(s, len);
}
}
if (has_log_file()) {
int nl0 = _newlines;
xmlTextStream::write(s, len);
if (nl0 != _newlines){
flush();
}
} else {
update_position(s, len);
}
release(holder);
}
intx ttyLocker::hold_tty() {
if (defaultStream::instance == NULL) return defaultStream::NO_WRITER;
intx thread_id = os::current_thread_id();
return defaultStream::instance->hold(thread_id);
}
void ttyLocker::release_tty(intx holder) {
if (holder == defaultStream::NO_WRITER) return;
defaultStream::instance->release(holder);
}
bool ttyLocker::release_tty_if_locked() {
intx thread_id = os::current_thread_id();
if (defaultStream::instance->writer() == thread_id) {
release_tty(thread_id);
return true;
}
return false;
}
void ttyLocker::break_tty_lock_for_safepoint(intx holder) {
if (defaultStream::instance != NULL &&
defaultStream::instance->writer() == holder) {
if (xtty != NULL) {
xtty->print_cr("<!-- safepoint while printing -->");
}
defaultStream::instance->release(holder);
}
}
void ostream_init() {
if (defaultStream::instance == NULL) {
defaultStream::instance = new(ResourceObj::C_HEAP, mtInternal) defaultStream();
tty = defaultStream::instance;
tty->time_stamp().update_to(1);
}
}
void ostream_init_log() {
gclog_or_tty = tty; // default to tty
if (Arguments::gc_log_filename() != NULL) {
fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal)
gcLogFileStream(Arguments::gc_log_filename());
if (gclog->is_open()) {
gclog->time_stamp().update_to(tty->time_stamp().ticks());
}
gclog_or_tty = gclog;
}
#if INCLUDE_CDS
if (DumpLoadedClassList != NULL) {
const char* list_name = make_log_name(DumpLoadedClassList, NULL);
classlist_file = new(ResourceObj::C_HEAP, mtInternal)
fileStream(list_name);
FREE_C_HEAP_ARRAY(char, list_name, mtInternal);
}
#endif
defaultStream::instance->has_log_file();
}
void ostream_exit() {
static bool ostream_exit_called = false;
if (ostream_exit_called) return;
ostream_exit_called = true;
#if INCLUDE_CDS
if (classlist_file != NULL) {
delete classlist_file;
}
#endif
if (gclog_or_tty != tty) {
delete gclog_or_tty;
}
{
DEBUG_ONLY(FlagSetting fs(PrintMallocFree, false);)
if (tty != defaultStream::instance) {
delete tty;
}
if (defaultStream::instance != NULL) {
delete defaultStream::instance;
}
}
tty = NULL;
xtty = NULL;
gclog_or_tty = NULL;
defaultStream::instance = NULL;
}
void ostream_abort() {
if (gclog_or_tty) gclog_or_tty->flush();
if (tty) tty->flush();
if (defaultStream::instance != NULL) {
static char buf[4096];
defaultStream::instance->finish_log_on_error(buf, sizeof(buf));
}
}
staticBufferStream::staticBufferStream(char* buffer, size_t buflen,
outputStream *outer_stream) {
_buffer = buffer;
_buflen = buflen;
_outer_stream = outer_stream;
_stamp.update_to(1);
}
void staticBufferStream::write(const char* c, size_t len) {
_outer_stream->print_raw(c, (int)len);
}
void staticBufferStream::flush() {
_outer_stream->flush();
}
void staticBufferStream::print(const char* format, ...) {
va_list ap;
va_start(ap, format);
size_t len;
const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len);
write(str, len);
va_end(ap);
}
void staticBufferStream::print_cr(const char* format, ...) {
va_list ap;
va_start(ap, format);
size_t len;
const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len);
write(str, len);
va_end(ap);
}
void staticBufferStream::vprint(const char *format, va_list argptr) {
size_t len;
const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len);
write(str, len);
}
void staticBufferStream::vprint_cr(const char* format, va_list argptr) {
size_t len;
const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len);
write(str, len);
}
bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
buffer_length = initial_size;
buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
buffer_pos = 0;
buffer_fixed = false;
buffer_max = bufmax;
}
bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
buffer_length = fixed_buffer_size;
buffer = fixed_buffer;
buffer_pos = 0;
buffer_fixed = true;
buffer_max = bufmax;
}
void bufferedStream::write(const char* s, size_t len) {
if(buffer_pos + len > buffer_max) {
flush();
}
size_t end = buffer_pos + len;
if (end >= buffer_length) {
if (buffer_fixed) {
len = buffer_length - buffer_pos - 1;
} else {
if (end < buffer_length * 2) {
end = buffer_length * 2;
}
buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
buffer_length = end;
}
}
memcpy(buffer + buffer_pos, s, len);
buffer_pos += len;
update_position(s, len);
}
char* bufferedStream::as_string() {
char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
strncpy(copy, buffer, buffer_pos);
copy[buffer_pos] = 0; // terminating null
return copy;
}
bufferedStream::~bufferedStream() {
if (!buffer_fixed) {
FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
}
}
#ifndef PRODUCT
#if defined(SOLARIS) || defined(LINUX) || defined(AIX) || defined(_ALLBSD_SOURCE)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
_socket = -1;
int result = os::socket(AF_INET, SOCK_STREAM, 0);
if (result <= 0) {
assert(false, "Socket could not be created!");
} else {
_socket = result;
}
}
int networkStream::read(char *buf, size_t len) {
return os::recv(_socket, buf, (int)len, 0);
}
void networkStream::flush() {
if (size() != 0) {
int result = os::raw_send(_socket, (char *)base(), size(), 0);
assert(result != -1, "connection error");
assert(result == (int)size(), "didn't send enough data");
}
reset();
}
networkStream::~networkStream() {
close();
}
void networkStream::close() {
if (_socket != -1) {
flush();
os::socket_close(_socket);
_socket = -1;
}
}
bool networkStream::connect(const char *ip, short port) {
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (server.sin_addr.s_addr == (uint32_t)-1) {
struct hostent* host = os::get_host_by_name((char*)ip);
if (host != NULL) {
memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length);
} else {
return false;
}
}
int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in));
return (result >= 0);
}
#endif
C:\hotspot-69087d08d473\src\share\vm/utilities/ostream.hpp
#ifndef SHARE_VM_UTILITIES_OSTREAM_HPP
#define SHARE_VM_UTILITIES_OSTREAM_HPP
#include "memory/allocation.hpp"
#include "runtime/timer.hpp"
class GCId;
DEBUG_ONLY(class ResourceMark;)
class outputStream : public ResourceObj {
protected:
int _indentation; // current indentation
int _width; // width of the page
int _position; // position on the current line
int _newlines; // number of '\n' output so far
julong _precount; // number of chars output, less _position
TimeStamp _stamp; // for time stamps
void update_position(const char* s, size_t len);
static const char* do_vsnprintf(char* buffer, size_t buflen,
const char* format, va_list ap,
bool add_cr,
size_t& result_len) ATTRIBUTE_PRINTF(3, 0);
public:
outputStream(int width = 80);
outputStream(int width, bool has_time_stamps);
outputStream& indent();
void inc() { _indentation++; };
void dec() { _indentation--; };
void inc(int n) { _indentation += n; };
void dec(int n) { _indentation -= n; };
int indentation() const { return _indentation; }
void set_indentation(int i) { _indentation = i; }
void fill_to(int col);
void move_to(int col, int slop = 6, int min_space = 2);
int width() const { return _width; }
int position() const { return _position; }
int newlines() const { return _newlines; }
julong count() const { return _precount + _position; }
void set_count(julong count) { _precount = count - _position; }
void set_position(int pos) { _position = pos; }
void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
void print_raw(const char* str) { write(str, strlen(str)); }
void print_raw(const char* str, int len) { write(str, len); }
void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); }
void print_raw_cr(const char* str, int len){ write(str, len); cr(); }
void print_data(void* data, size_t len, bool with_ascii);
void put(char ch);
void sp(int count = 1);
void cr();
void bol() { if (_position > 0) cr(); }
TimeStamp& time_stamp() { return _stamp; }
void stamp();
void stamp(bool guard, const char* prefix, const char* suffix);
void stamp(bool guard) {
stamp(guard, "", ": ");
}
void date_stamp(bool guard, const char* prefix, const char* suffix);
void date_stamp(bool guard) {
date_stamp(guard, "", ": ");
}
void gclog_stamp(const GCId& gc_id);
void print_jlong(jlong value);
void print_julong(julong value);
virtual void flush() {}
virtual void write(const char* str, size_t len) = 0;
virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
virtual ~outputStream() {} // close properly on deletion
void dec_cr() { dec(); cr(); }
void inc_cr() { inc(); cr(); }
};
extern outputStream* tty; // tty output
extern outputStream* gclog_or_tty; // stream for gc log if -Xloggc:<f>, or tty
class streamIndentor : public StackObj {
private:
outputStream* _str;
int _amount;
public:
streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) {
_str->inc(_amount);
}
~streamIndentor() { _str->dec(_amount); }
};
class ttyLocker: StackObj {
friend class ttyUnlocker;
private:
intx _holder;
public:
static intx hold_tty(); // returns a "holder" token
static void release_tty(intx holder); // must witness same token
static bool release_tty_if_locked(); // returns true if lock was released
static void break_tty_lock_for_safepoint(intx holder);
ttyLocker() { _holder = hold_tty(); }
~ttyLocker() { release_tty(_holder); }
};
class ttyUnlocker: StackObj {
private:
bool _was_locked;
public:
ttyUnlocker() {
_was_locked = ttyLocker::release_tty_if_locked();
}
~ttyUnlocker() {
if (_was_locked) {
ttyLocker::hold_tty();
}
}
};
class stringStream : public outputStream {
protected:
char* buffer;
size_t buffer_pos;
size_t buffer_length;
bool buffer_fixed;
DEBUG_ONLY(ResourceMark* rm;)
public:
stringStream(size_t initial_bufsize = 256);
stringStream(char* fixed_buffer, size_t fixed_buffer_size);
~stringStream();
virtual void write(const char* c, size_t len);
size_t size() { return buffer_pos; }
const char* base() { return buffer; }
void reset() { buffer_pos = 0; _precount = 0; _position = 0; }
char* as_string();
};
class fileStream : public outputStream {
protected:
FILE* _file;
bool _need_close;
public:
fileStream() { _file = NULL; _need_close = false; }
fileStream(const char* file_name);
fileStream(const char* file_name, const char* opentype);
fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
~fileStream();
bool is_open() const { return _file != NULL; }
void set_need_close(bool b) { _need_close = b;}
virtual void write(const char* c, size_t len);
size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); }
char* readln(char *data, int count);
int eof() { return feof(_file); }
long fileSize();
void rewind() { ::rewind(_file); }
void flush();
};
CDS_ONLY(extern fileStream* classlist_file;)
class fdStream : public outputStream {
protected:
int _fd;
bool _need_close;
public:
fdStream(const char* file_name);
fdStream(int fd = -1) { _fd = fd; _need_close = false; }
~fdStream();
bool is_open() const { return _fd != -1; }
void set_fd(int fd) { _fd = fd; _need_close = false; }
int fd() const { return _fd; }
virtual void write(const char* c, size_t len);
void flush() {};
};
class Mutex;
class gcLogFileStream : public fileStream {
protected:
const char* _file_name;
jlong _bytes_written;
uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
private:
Mutex* _file_lock;
void rotate_log_impl(bool force, outputStream* out);
public:
gcLogFileStream(const char* file_name);
~gcLogFileStream();
virtual void write(const char* c, size_t len);
virtual void rotate_log(bool force, outputStream* out = NULL);
void dump_loggc_header();
bool should_rotate(bool force) {
return force ||
((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize));
}
};
#ifndef PRODUCT
void test_loggc_filename();
void test_snprintf();
#endif
void ostream_init();
void ostream_init_log();
void ostream_exit();
void ostream_abort();
class staticBufferStream : public outputStream {
private:
char* _buffer;
size_t _buflen;
outputStream* _outer_stream;
public:
staticBufferStream(char* buffer, size_t buflen,
outputStream *outer_stream);
~staticBufferStream() {};
virtual void write(const char* c, size_t len);
void flush();
void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
};
class bufferedStream : public outputStream {
protected:
char* buffer;
size_t buffer_pos;
size_t buffer_max;
size_t buffer_length;
bool buffer_fixed;
public:
bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10);
~bufferedStream();
virtual void write(const char* c, size_t len);
size_t size() { return buffer_pos; }
const char* base() { return buffer; }
void reset() { buffer_pos = 0; _precount = 0; _position = 0; }
char* as_string();
};
#define O_BUFLEN 2000 // max size of output of individual print() methods
#ifndef PRODUCT
class networkStream : public bufferedStream {
private:
int _socket;
public:
networkStream();
~networkStream();
bool connect(const char *host, short port);
bool is_open() const { return _socket != -1; }
int read(char *buf, size_t len);
void close();
virtual void flush();
};
#endif
#endif // SHARE_VM_UTILITIES_OSTREAM_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/pair.hpp
#ifndef SHARE_VM_UTILITIES_PAIR_HPP
#define SHARE_VM_UTILITIES_PAIR_HPP
#include "memory/allocation.hpp"
#include "utilities/top.hpp"
template<typename T, typename V, typename ALLOC_BASE = ResourceObj>
class Pair : public ALLOC_BASE {
public:
T first;
V second;
Pair() {}
Pair(T t, V v) : first(t), second(v) {}
};
#endif // SHARE_VM_UTILITIES_PAIR_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/preserveException.cpp
#include "precompiled.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/preserveException.hpp"
PreserveExceptionMark::PreserveExceptionMark(Thread*& thread) {
thread = Thread::current();
_thread = thread;
_preserved_exception_oop = Handle(thread, _thread->pending_exception());
_preserved_exception_line = _thread->exception_line();
_preserved_exception_file = _thread->exception_file();
_thread->clear_pending_exception(); // Needed to avoid infinite recursion
}
PreserveExceptionMark::~PreserveExceptionMark() {
if (_thread->has_pending_exception()) {
oop exception = _thread->pending_exception();
_thread->clear_pending_exception(); // Needed to avoid infinite recursion
exception->print();
fatal("PreserveExceptionMark destructor expects no pending exceptions");
}
if (_preserved_exception_oop() != NULL) {
_thread->set_pending_exception(_preserved_exception_oop(), _preserved_exception_file, _preserved_exception_line);
}
}
CautiouslyPreserveExceptionMark::CautiouslyPreserveExceptionMark(Thread* thread) {
_thread = thread;
_preserved_exception_oop = Handle(thread, _thread->pending_exception());
_preserved_exception_line = _thread->exception_line();
_preserved_exception_file = _thread->exception_file();
_thread->clear_pending_exception(); // Pending exceptions are checked in the destructor
}
CautiouslyPreserveExceptionMark::~CautiouslyPreserveExceptionMark() {
assert(!_thread->has_pending_exception(), "unexpected exception generated");
if (_thread->has_pending_exception()) {
_thread->clear_pending_exception();
}
if (_preserved_exception_oop() != NULL) {
_thread->set_pending_exception(_preserved_exception_oop(), _preserved_exception_file, _preserved_exception_line);
}
}
void WeakPreserveExceptionMark::preserve() {
_preserved_exception_oop = Handle(_thread, _thread->pending_exception());
_preserved_exception_line = _thread->exception_line();
_preserved_exception_file = _thread->exception_file();
_thread->clear_pending_exception();
}
void WeakPreserveExceptionMark::restore() {
if (!_thread->has_pending_exception()) {
_thread->set_pending_exception(_preserved_exception_oop(), _preserved_exception_file, _preserved_exception_line);
}
}
C:\hotspot-69087d08d473\src\share\vm/utilities/preserveException.hpp
#ifndef SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
#define SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
#include "runtime/handles.hpp"
#include "runtime/thread.inline.hpp"
class PreserveExceptionMark {
private:
Thread* _thread;
Handle _preserved_exception_oop;
int _preserved_exception_line;
const char* _preserved_exception_file;
public:
PreserveExceptionMark(Thread*& thread);
~PreserveExceptionMark();
};
class CautiouslyPreserveExceptionMark {
private:
Thread* _thread;
Handle _preserved_exception_oop;
int _preserved_exception_line;
const char* _preserved_exception_file;
public:
CautiouslyPreserveExceptionMark(Thread* thread);
~CautiouslyPreserveExceptionMark();
};
class WeakPreserveExceptionMark {
private:
Thread* _thread;
Handle _preserved_exception_oop;
int _preserved_exception_line;
const char* _preserved_exception_file;
void preserve();
void restore();
public:
WeakPreserveExceptionMark(Thread* pThread) : _thread(pThread), _preserved_exception_oop() {
if (pThread->has_pending_exception()) {
preserve();
}
}
~WeakPreserveExceptionMark() {
if (_preserved_exception_oop.not_null()) {
restore();
}
}
};
#define PRESERVE_EXCEPTION_MARK Thread* THREAD; PreserveExceptionMark __em(THREAD);
#endif // SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
C:\hotspot-69087d08d473\src\share\vm/utilities/quickSort.cpp
#include "precompiled.hpp"
#ifndef PRODUCT
#include "runtime/os.hpp"
#include "utilities/quickSort.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include <stdlib.h>
#ifdef ASSERT
static int test_comparator(int a, int b) {
if (a == b) {
return 0;
}
if (a < b) {
return -1;
}
return 1;
}
#endif // ASSERT
static int test_even_odd_comparator(int a, int b) {
bool a_is_odd = (a % 2) == 1;
bool b_is_odd = (b % 2) == 1;
if (a_is_odd == b_is_odd) {
return 0;
}
if (a_is_odd) {
return -1;
}
return 1;
}
extern "C" {
static int test_stdlib_comparator(const void* a, const void* b) {
int ai = *(int*)a;
int bi = *(int*)b;
if (ai == bi) {
return 0;
}
if (ai < bi) {
return -1;
}
return 1;
}
}
void QuickSort::print_array(const char* prefix, int* array, int length) {
tty->print("%s:", prefix);
for (int i = 0; i < length; i++) {
tty->print(" %d", array[i]);
}
tty->cr();
}
bool QuickSort::compare_arrays(int* actual, int* expected, int length) {
for (int i = 0; i < length; i++) {
if (actual[i] != expected[i]) {
print_array("Sorted array ", actual, length);
print_array("Expected array", expected, length);
return false;
}
}
return true;
}
template <class C>
bool QuickSort::sort_and_compare(int* arrayToSort, int* expectedResult, int length, C comparator, bool idempotent) {
sort<int, C>(arrayToSort, length, comparator, idempotent);
return compare_arrays(arrayToSort, expectedResult, length);
}
void QuickSort::test_quick_sort() {
{
int* test_array = NULL;
int* expected_array = NULL;
assert(sort_and_compare(test_array, expected_array, 0, test_comparator), "Empty array not handled");
}
{
int test_array[] = {3};
int expected_array[] = {3};
assert(sort_and_compare(test_array, expected_array, 1, test_comparator), "Single value array not handled");
}
{
int test_array[] = {3,2};
int expected_array[] = {2,3};
assert(sort_and_compare(test_array, expected_array, 2, test_comparator), "Array with 2 values not correctly sorted");
}
{
int test_array[] = {3,2,1};
int expected_array[] = {1,2,3};
assert(sort_and_compare(test_array, expected_array, 3, test_comparator), "Array with 3 values not correctly sorted");
}
{
int test_array[] = {4,3,2,1};
int expected_array[] = {1,2,3,4};
assert(sort_and_compare(test_array, expected_array, 4, test_comparator), "Array with 4 values not correctly sorted");
}
{
int test_array[] = {7,1,5,3,6,9,8,2,4,0};
int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
assert(sort_and_compare(test_array, expected_array, 10, test_comparator), "Array with 10 values not correctly sorted");
}
{
int test_array[] = {4,4,1,4};
int expected_array[] = {1,4,4,4};
assert(sort_and_compare(test_array, expected_array, 4, test_comparator), "3 duplicates not sorted correctly");
}
{
int test_array[] = {0,1,2,3,4,5,6,7,8,9};
int expected_array[] = {0,1,2,3,4,5,6,7,8,9};
assert(sort_and_compare(test_array, expected_array, 10, test_comparator), "Already sorted array not correctly sorted");
}
ssssssss87
最新推荐文章于 2024-08-01 15:05:06 发布