mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
7017124: Fix some VM stats to avoid 32-bit overflow
Added new method inc_stat_counter() to increment long statistic values and use atomic long load and store. Reviewed-by: dholmes, jrose, phh, never
This commit is contained in:
parent
e7c3086ed3
commit
b9633d42b4
10 changed files with 100 additions and 80 deletions
|
@ -67,7 +67,6 @@ extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst);
|
||||||
inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
|
inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
|
||||||
#ifdef COMPILER2
|
#ifdef COMPILER2
|
||||||
// Compiler2 does not support v8, it is used only for v9.
|
// Compiler2 does not support v8, it is used only for v9.
|
||||||
assert (VM_Version::v9_instructions_work(), "only supported on v9");
|
|
||||||
_Atomic_move_long_v9(src, dst);
|
_Atomic_move_long_v9(src, dst);
|
||||||
#else
|
#else
|
||||||
// The branch is cheaper then emulated LDD.
|
// The branch is cheaper then emulated LDD.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -157,7 +157,7 @@ ResourceObj::~ResourceObj() {
|
||||||
|
|
||||||
void trace_heap_malloc(size_t size, const char* name, void* p) {
|
void trace_heap_malloc(size_t size, const char* name, void* p) {
|
||||||
// A lock is not needed here - tty uses a lock internally
|
// A lock is not needed here - tty uses a lock internally
|
||||||
tty->print_cr("Heap malloc " INTPTR_FORMAT " %7d %s", p, size, name == NULL ? "" : name);
|
tty->print_cr("Heap malloc " INTPTR_FORMAT " " SIZE_FORMAT " %s", p, size, name == NULL ? "" : name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -573,22 +573,27 @@ void AllocatedObj::print_value_on(outputStream* st) const {
|
||||||
st->print("AllocatedObj(" INTPTR_FORMAT ")", this);
|
st->print("AllocatedObj(" INTPTR_FORMAT ")", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Arena::_bytes_allocated = 0;
|
julong Arena::_bytes_allocated = 0;
|
||||||
|
|
||||||
|
void Arena::inc_bytes_allocated(size_t x) { inc_stat_counter(&_bytes_allocated, x); }
|
||||||
|
|
||||||
AllocStats::AllocStats() {
|
AllocStats::AllocStats() {
|
||||||
start_mallocs = os::num_mallocs;
|
start_mallocs = os::num_mallocs;
|
||||||
start_frees = os::num_frees;
|
start_frees = os::num_frees;
|
||||||
start_malloc_bytes = os::alloc_bytes;
|
start_malloc_bytes = os::alloc_bytes;
|
||||||
start_res_bytes = Arena::_bytes_allocated;
|
start_mfree_bytes = os::free_bytes;
|
||||||
|
start_res_bytes = Arena::_bytes_allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AllocStats::num_mallocs() { return os::num_mallocs - start_mallocs; }
|
julong AllocStats::num_mallocs() { return os::num_mallocs - start_mallocs; }
|
||||||
size_t AllocStats::alloc_bytes() { return os::alloc_bytes - start_malloc_bytes; }
|
julong AllocStats::alloc_bytes() { return os::alloc_bytes - start_malloc_bytes; }
|
||||||
size_t AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; }
|
julong AllocStats::num_frees() { return os::num_frees - start_frees; }
|
||||||
int AllocStats::num_frees() { return os::num_frees - start_frees; }
|
julong AllocStats::free_bytes() { return os::free_bytes - start_mfree_bytes; }
|
||||||
|
julong AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; }
|
||||||
void AllocStats::print() {
|
void AllocStats::print() {
|
||||||
tty->print("%d mallocs (%ldK), %d frees, %ldK resrc",
|
tty->print_cr(UINT64_FORMAT " mallocs (" UINT64_FORMAT "MB), "
|
||||||
num_mallocs(), alloc_bytes()/K, num_frees(), resource_bytes()/K);
|
UINT64_FORMAT" frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
|
||||||
|
num_mallocs(), alloc_bytes()/M, num_frees(), free_bytes()/M, resource_bytes()/M);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -202,10 +202,11 @@ protected:
|
||||||
char *_hwm, *_max; // High water mark and max in current chunk
|
char *_hwm, *_max; // High water mark and max in current chunk
|
||||||
void* grow(size_t x); // Get a new Chunk of at least size x
|
void* grow(size_t x); // Get a new Chunk of at least size x
|
||||||
NOT_PRODUCT(size_t _size_in_bytes;) // Size of arena (used for memory usage tracing)
|
NOT_PRODUCT(size_t _size_in_bytes;) // Size of arena (used for memory usage tracing)
|
||||||
NOT_PRODUCT(static size_t _bytes_allocated;) // total #bytes allocated since start
|
NOT_PRODUCT(static julong _bytes_allocated;) // total #bytes allocated since start
|
||||||
friend class AllocStats;
|
friend class AllocStats;
|
||||||
debug_only(void* malloc(size_t size);)
|
debug_only(void* malloc(size_t size);)
|
||||||
debug_only(void* internal_malloc_4(size_t x);)
|
debug_only(void* internal_malloc_4(size_t x);)
|
||||||
|
NOT_PRODUCT(void inc_bytes_allocated(size_t x);)
|
||||||
public:
|
public:
|
||||||
Arena();
|
Arena();
|
||||||
Arena(size_t init_size);
|
Arena(size_t init_size);
|
||||||
|
@ -219,7 +220,7 @@ protected:
|
||||||
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
|
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
|
||||||
x = ARENA_ALIGN(x);
|
x = ARENA_ALIGN(x);
|
||||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||||
NOT_PRODUCT(_bytes_allocated += x);
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x);
|
return grow(x);
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,7 +233,7 @@ protected:
|
||||||
void *Amalloc_4(size_t x) {
|
void *Amalloc_4(size_t x) {
|
||||||
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
||||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||||
NOT_PRODUCT(_bytes_allocated += x);
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x);
|
return grow(x);
|
||||||
} else {
|
} else {
|
||||||
|
@ -252,7 +253,7 @@ protected:
|
||||||
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
|
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
|
||||||
x += delta;
|
x += delta;
|
||||||
#endif
|
#endif
|
||||||
NOT_PRODUCT(_bytes_allocated += x);
|
NOT_PRODUCT(inc_bytes_allocated(x);)
|
||||||
if (_hwm + x > _max) {
|
if (_hwm + x > _max) {
|
||||||
return grow(x); // grow() returns a result aligned >= 8 bytes.
|
return grow(x); // grow() returns a result aligned >= 8 bytes.
|
||||||
} else {
|
} else {
|
||||||
|
@ -406,15 +407,16 @@ extern bool warn_new_operator;
|
||||||
// for statistics
|
// for statistics
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
class AllocStats : StackObj {
|
class AllocStats : StackObj {
|
||||||
int start_mallocs, start_frees;
|
julong start_mallocs, start_frees;
|
||||||
size_t start_malloc_bytes, start_res_bytes;
|
julong start_malloc_bytes, start_mfree_bytes, start_res_bytes;
|
||||||
public:
|
public:
|
||||||
AllocStats();
|
AllocStats();
|
||||||
|
|
||||||
int num_mallocs(); // since creation of receiver
|
julong num_mallocs(); // since creation of receiver
|
||||||
size_t alloc_bytes();
|
julong alloc_bytes();
|
||||||
size_t resource_bytes();
|
julong num_frees();
|
||||||
int num_frees();
|
julong free_bytes();
|
||||||
|
julong resource_bytes();
|
||||||
void print();
|
void print();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -32,6 +32,12 @@
|
||||||
void trace_heap_malloc(size_t size, const char* name, void *p);
|
void trace_heap_malloc(size_t size, const char* name, void *p);
|
||||||
void trace_heap_free(void *p);
|
void trace_heap_free(void *p);
|
||||||
|
|
||||||
|
// Increments unsigned long value for statistics (not atomic on MP).
|
||||||
|
inline void inc_stat_counter(volatile julong* dest, julong add_value) {
|
||||||
|
julong value = Atomic::load((volatile jlong*)dest);
|
||||||
|
value += add_value;
|
||||||
|
Atomic::store((jlong)value, (volatile jlong*)dest);
|
||||||
|
}
|
||||||
|
|
||||||
// allocate using malloc; will fail if no memory available
|
// allocate using malloc; will fail if no memory available
|
||||||
inline char* AllocateHeap(size_t size, const char* name = NULL) {
|
inline char* AllocateHeap(size_t size, const char* name = NULL) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -39,12 +39,12 @@ IndexSet::BitBlock IndexSet::_empty_block = IndexSet::BitBlock();
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// Initialize statistics counters
|
// Initialize statistics counters
|
||||||
uint IndexSet::_alloc_new = 0;
|
julong IndexSet::_alloc_new = 0;
|
||||||
uint IndexSet::_alloc_total = 0;
|
julong IndexSet::_alloc_total = 0;
|
||||||
|
|
||||||
long IndexSet::_total_bits = 0;
|
julong IndexSet::_total_bits = 0;
|
||||||
long IndexSet::_total_used_blocks = 0;
|
julong IndexSet::_total_used_blocks = 0;
|
||||||
long IndexSet::_total_unused_blocks = 0;
|
julong IndexSet::_total_unused_blocks = 0;
|
||||||
|
|
||||||
// Per set, or all sets operation tracing
|
// Per set, or all sets operation tracing
|
||||||
int IndexSet::_serial_count = 1;
|
int IndexSet::_serial_count = 1;
|
||||||
|
@ -141,7 +141,7 @@ void IndexSet::populate_free_list() {
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (CollectIndexSetStatistics) {
|
if (CollectIndexSetStatistics) {
|
||||||
_alloc_new += bitblock_alloc_chunk_size;
|
inc_stat_counter(&_alloc_new, bitblock_alloc_chunk_size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ void IndexSet::populate_free_list() {
|
||||||
IndexSet::BitBlock *IndexSet::alloc_block() {
|
IndexSet::BitBlock *IndexSet::alloc_block() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (CollectIndexSetStatistics) {
|
if (CollectIndexSetStatistics) {
|
||||||
_alloc_total++;
|
inc_stat_counter(&_alloc_total, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Compile *compile = Compile::current();
|
Compile *compile = Compile::current();
|
||||||
|
@ -391,13 +391,13 @@ void IndexSet::dump() const {
|
||||||
// Update block/bit counts to reflect that this set has been iterated over.
|
// Update block/bit counts to reflect that this set has been iterated over.
|
||||||
|
|
||||||
void IndexSet::tally_iteration_statistics() const {
|
void IndexSet::tally_iteration_statistics() const {
|
||||||
_total_bits += count();
|
inc_stat_counter(&_total_bits, count());
|
||||||
|
|
||||||
for (uint i = 0; i < _max_blocks; i++) {
|
for (uint i = 0; i < _max_blocks; i++) {
|
||||||
if (_blocks[i] != &_empty_block) {
|
if (_blocks[i] != &_empty_block) {
|
||||||
_total_used_blocks++;
|
inc_stat_counter(&_total_used_blocks, 1);
|
||||||
} else {
|
} else {
|
||||||
_total_unused_blocks++;
|
inc_stat_counter(&_total_unused_blocks, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,17 +406,17 @@ void IndexSet::tally_iteration_statistics() const {
|
||||||
// Print statistics about IndexSet usage.
|
// Print statistics about IndexSet usage.
|
||||||
|
|
||||||
void IndexSet::print_statistics() {
|
void IndexSet::print_statistics() {
|
||||||
long total_blocks = _total_used_blocks + _total_unused_blocks;
|
julong total_blocks = _total_used_blocks + _total_unused_blocks;
|
||||||
tty->print_cr ("Accumulated IndexSet usage statistics:");
|
tty->print_cr ("Accumulated IndexSet usage statistics:");
|
||||||
tty->print_cr ("--------------------------------------");
|
tty->print_cr ("--------------------------------------");
|
||||||
tty->print_cr (" Iteration:");
|
tty->print_cr (" Iteration:");
|
||||||
tty->print_cr (" blocks visited: %d", total_blocks);
|
tty->print_cr (" blocks visited: " UINT64_FORMAT, total_blocks);
|
||||||
tty->print_cr (" blocks empty: %4.2f%%", 100.0*_total_unused_blocks/total_blocks);
|
tty->print_cr (" blocks empty: %4.2f%%", 100.0*(double)_total_unused_blocks/total_blocks);
|
||||||
tty->print_cr (" bit density (bits/used blocks): %4.2f%%", (double)_total_bits/_total_used_blocks);
|
tty->print_cr (" bit density (bits/used blocks): %4.2f", (double)_total_bits/_total_used_blocks);
|
||||||
tty->print_cr (" bit density (bits/all blocks): %4.2f%%", (double)_total_bits/total_blocks);
|
tty->print_cr (" bit density (bits/all blocks): %4.2f", (double)_total_bits/total_blocks);
|
||||||
tty->print_cr (" Allocation:");
|
tty->print_cr (" Allocation:");
|
||||||
tty->print_cr (" blocks allocated: %d", _alloc_new);
|
tty->print_cr (" blocks allocated: " UINT64_FORMAT, _alloc_new);
|
||||||
tty->print_cr (" blocks used/reused: %d", _alloc_total);
|
tty->print_cr (" blocks used/reused: " UINT64_FORMAT, _alloc_total);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------- IndexSet::verify() -----------------------------
|
//---------------------------- IndexSet::verify() -----------------------------
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -352,13 +352,13 @@ class IndexSet : public ResourceObj {
|
||||||
void tally_iteration_statistics() const;
|
void tally_iteration_statistics() const;
|
||||||
|
|
||||||
// BitBlock allocation statistics
|
// BitBlock allocation statistics
|
||||||
static uint _alloc_new;
|
static julong _alloc_new;
|
||||||
static uint _alloc_total;
|
static julong _alloc_total;
|
||||||
|
|
||||||
// Block density statistics
|
// Block density statistics
|
||||||
static long _total_bits;
|
static julong _total_bits;
|
||||||
static long _total_used_blocks;
|
static julong _total_used_blocks;
|
||||||
static long _total_unused_blocks;
|
static julong _total_unused_blocks;
|
||||||
|
|
||||||
// Sanity tests
|
// Sanity tests
|
||||||
void verify() const;
|
void verify() const;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -712,6 +712,9 @@ class CommandLineFlags {
|
||||||
develop(bool, PrintMalloc, false, \
|
develop(bool, PrintMalloc, false, \
|
||||||
"print all malloc/free calls") \
|
"print all malloc/free calls") \
|
||||||
\
|
\
|
||||||
|
develop(bool, PrintMallocStatistics, false, \
|
||||||
|
"print malloc/free statistics") \
|
||||||
|
\
|
||||||
develop(bool, ZapResourceArea, trueInDebug, \
|
develop(bool, ZapResourceArea, trueInDebug, \
|
||||||
"Zap freed resource/arena space with 0xABABABAB") \
|
"Zap freed resource/arena space with 0xABABABAB") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -320,7 +320,7 @@ void print_statistics() {
|
||||||
}
|
}
|
||||||
|
|
||||||
print_bytecode_count();
|
print_bytecode_count();
|
||||||
if (WizardMode) {
|
if (PrintMallocStatistics) {
|
||||||
tty->print("allocation stats: ");
|
tty->print("allocation stats: ");
|
||||||
alloc_stats.print();
|
alloc_stats.print();
|
||||||
tty->cr();
|
tty->cr();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -72,9 +72,10 @@ int os::_processor_count = 0;
|
||||||
size_t os::_page_sizes[os::page_sizes_max];
|
size_t os::_page_sizes[os::page_sizes_max];
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
int os::num_mallocs = 0; // # of calls to malloc/realloc
|
julong os::num_mallocs = 0; // # of calls to malloc/realloc
|
||||||
size_t os::alloc_bytes = 0; // # of bytes allocated
|
julong os::alloc_bytes = 0; // # of bytes allocated
|
||||||
int os::num_frees = 0; // # of calls to free
|
julong os::num_frees = 0; // # of calls to free
|
||||||
|
julong os::free_bytes = 0; // # of bytes freed
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fill in buffer with current local time as an ISO-8601 string.
|
// Fill in buffer with current local time as an ISO-8601 string.
|
||||||
|
@ -490,9 +491,9 @@ void print_neighbor_blocks(void* ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
|
if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
|
||||||
tty->print_cr("### previous object: %p (%ld bytes)", obj, size);
|
tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
|
||||||
} else {
|
} else {
|
||||||
tty->print_cr("### previous object (not sure if correct): %p (%ld bytes)", obj, size);
|
tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now find successor block
|
// now find successor block
|
||||||
|
@ -504,16 +505,16 @@ void print_neighbor_blocks(void* ptr) {
|
||||||
start_of_next_block[1] == badResourceValue &&
|
start_of_next_block[1] == badResourceValue &&
|
||||||
start_of_next_block[2] == badResourceValue &&
|
start_of_next_block[2] == badResourceValue &&
|
||||||
start_of_next_block[3] == badResourceValue) {
|
start_of_next_block[3] == badResourceValue) {
|
||||||
tty->print_cr("### next object: %p (%ld bytes)", next_obj, next_size);
|
tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
|
||||||
} else {
|
} else {
|
||||||
tty->print_cr("### next object (not sure if correct): %p (%ld bytes)", next_obj, next_size);
|
tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void report_heap_error(void* memblock, void* bad, const char* where) {
|
void report_heap_error(void* memblock, void* bad, const char* where) {
|
||||||
tty->print_cr("## nof_mallocs = %d, nof_frees = %d", os::num_mallocs, os::num_frees);
|
tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
|
||||||
tty->print_cr("## memory stomp: byte at %p %s object %p", bad, where, memblock);
|
tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
|
||||||
print_neighbor_blocks(memblock);
|
print_neighbor_blocks(memblock);
|
||||||
fatal("memory stomping error");
|
fatal("memory stomping error");
|
||||||
}
|
}
|
||||||
|
@ -538,8 +539,8 @@ void verify_block(void* memblock) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* os::malloc(size_t size) {
|
void* os::malloc(size_t size) {
|
||||||
NOT_PRODUCT(num_mallocs++);
|
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
|
||||||
NOT_PRODUCT(alloc_bytes += size);
|
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
// return a valid pointer if size is zero
|
// return a valid pointer if size is zero
|
||||||
|
@ -562,26 +563,26 @@ void* os::malloc(size_t size) {
|
||||||
#endif
|
#endif
|
||||||
u_char* memblock = ptr + space_before;
|
u_char* memblock = ptr + space_before;
|
||||||
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
||||||
tty->print_cr("os::malloc caught, %lu bytes --> %p", size, memblock);
|
tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
|
||||||
breakpoint();
|
breakpoint();
|
||||||
}
|
}
|
||||||
debug_only(if (paranoid) verify_block(memblock));
|
debug_only(if (paranoid) verify_block(memblock));
|
||||||
if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc %lu bytes --> %p", size, memblock);
|
if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
|
||||||
return memblock;
|
return memblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* os::realloc(void *memblock, size_t size) {
|
void* os::realloc(void *memblock, size_t size) {
|
||||||
NOT_PRODUCT(num_mallocs++);
|
|
||||||
NOT_PRODUCT(alloc_bytes += size);
|
|
||||||
#ifndef ASSERT
|
#ifndef ASSERT
|
||||||
|
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
|
||||||
|
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
|
||||||
return ::realloc(memblock, size);
|
return ::realloc(memblock, size);
|
||||||
#else
|
#else
|
||||||
if (memblock == NULL) {
|
if (memblock == NULL) {
|
||||||
return os::malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
||||||
tty->print_cr("os::realloc caught %p", memblock);
|
tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
|
||||||
breakpoint();
|
breakpoint();
|
||||||
}
|
}
|
||||||
verify_block(memblock);
|
verify_block(memblock);
|
||||||
|
@ -589,13 +590,13 @@ void* os::realloc(void *memblock, size_t size) {
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
// always move the block
|
// always move the block
|
||||||
void* ptr = malloc(size);
|
void* ptr = malloc(size);
|
||||||
if (PrintMalloc) tty->print_cr("os::remalloc %lu bytes, %p --> %p", size, memblock, ptr);
|
if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
|
||||||
// Copy to new memory if malloc didn't fail
|
// Copy to new memory if malloc didn't fail
|
||||||
if ( ptr != NULL ) {
|
if ( ptr != NULL ) {
|
||||||
memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
|
memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
|
||||||
if (paranoid) verify_block(ptr);
|
if (paranoid) verify_block(ptr);
|
||||||
if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
|
if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
|
||||||
tty->print_cr("os::realloc caught, %lu bytes --> %p", size, ptr);
|
tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
|
||||||
breakpoint();
|
breakpoint();
|
||||||
}
|
}
|
||||||
free(memblock);
|
free(memblock);
|
||||||
|
@ -606,17 +607,14 @@ void* os::realloc(void *memblock, size_t size) {
|
||||||
|
|
||||||
|
|
||||||
void os::free(void *memblock) {
|
void os::free(void *memblock) {
|
||||||
NOT_PRODUCT(num_frees++);
|
NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (memblock == NULL) return;
|
if (memblock == NULL) return;
|
||||||
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
||||||
if (tty != NULL) tty->print_cr("os::free caught %p", memblock);
|
if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
|
||||||
breakpoint();
|
breakpoint();
|
||||||
}
|
}
|
||||||
verify_block(memblock);
|
verify_block(memblock);
|
||||||
if (PrintMalloc && tty != NULL)
|
|
||||||
// tty->print_cr("os::free %p", memblock);
|
|
||||||
fprintf(stderr, "os::free %p\n", memblock);
|
|
||||||
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
|
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
|
||||||
// Added by detlefs.
|
// Added by detlefs.
|
||||||
if (MallocCushion) {
|
if (MallocCushion) {
|
||||||
|
@ -627,12 +625,18 @@ void os::free(void *memblock) {
|
||||||
*p = (u_char)freeBlockPad;
|
*p = (u_char)freeBlockPad;
|
||||||
}
|
}
|
||||||
size_t size = get_size(memblock);
|
size_t size = get_size(memblock);
|
||||||
|
inc_stat_counter(&free_bytes, size);
|
||||||
u_char* end = ptr + space_before + size;
|
u_char* end = ptr + space_before + size;
|
||||||
for (u_char* q = end; q < end + MallocCushion; q++) {
|
for (u_char* q = end; q < end + MallocCushion; q++) {
|
||||||
guarantee(*q == badResourceValue,
|
guarantee(*q == badResourceValue,
|
||||||
"Thing freed should be malloc result.");
|
"Thing freed should be malloc result.");
|
||||||
*q = (u_char)freeBlockPad;
|
*q = (u_char)freeBlockPad;
|
||||||
}
|
}
|
||||||
|
if (PrintMalloc && tty != NULL)
|
||||||
|
fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, memblock);
|
||||||
|
} else if (PrintMalloc && tty != NULL) {
|
||||||
|
// tty->print_cr("os::free %p", memblock);
|
||||||
|
fprintf(stderr, "os::free " PTR_FORMAT "\n", memblock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
::free((char*)memblock - space_before);
|
::free((char*)memblock - space_before);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -559,9 +559,10 @@ class os: AllStatic {
|
||||||
static char* strdup(const char *); // Like strdup
|
static char* strdup(const char *); // Like strdup
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
static int num_mallocs; // # of calls to malloc/realloc
|
static julong num_mallocs; // # of calls to malloc/realloc
|
||||||
static size_t alloc_bytes; // # of bytes allocated
|
static julong alloc_bytes; // # of bytes allocated
|
||||||
static int num_frees; // # of calls to free
|
static julong num_frees; // # of calls to free
|
||||||
|
static julong free_bytes; // # of bytes freed
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SocketInterface (ex HPI SocketInterface )
|
// SocketInterface (ex HPI SocketInterface )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue