7158805: Better rewriting of nested subroutine calls

Reviewed-by: mschoene, coleenp
This commit is contained in:
Harold Seigel 2013-03-07 11:49:38 -05:00
parent 1b5f599819
commit 455fd39d49
3 changed files with 46 additions and 27 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -248,7 +248,7 @@ class ChunkPool: public CHeapObj<mtInternal> {
ChunkPool(size_t size) : _size(size) { _first = NULL; _num_chunks = _num_used = 0; }
// Allocate a new chunk from the pool (might expand the pool)
_NOINLINE_ void* allocate(size_t bytes) {
_NOINLINE_ void* allocate(size_t bytes, AllocFailType alloc_failmode) {
assert(bytes == _size, "bad size");
void* p = NULL;
// No VM lock can be taken inside ThreadCritical lock, so os::malloc
@ -258,9 +258,9 @@ class ChunkPool: public CHeapObj<mtInternal> {
p = get_first();
}
if (p == NULL) p = os::malloc(bytes, mtChunk, CURRENT_PC);
if (p == NULL)
if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "ChunkPool::allocate");
}
return p;
}
@ -357,7 +357,7 @@ class ChunkPoolCleaner : public PeriodicTask {
//--------------------------------------------------------------------------------------
// Chunk implementation
void* Chunk::operator new(size_t requested_size, size_t length) {
void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) {
// requested_size is equal to sizeof(Chunk) but in order for the arena
// allocations to come out aligned as expected the size must be aligned
// to expected arean alignment.
@ -365,13 +365,14 @@ void* Chunk::operator new(size_t requested_size, size_t length) {
assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment");
size_t bytes = ARENA_ALIGN(requested_size) + length;
switch (length) {
case Chunk::size: return ChunkPool::large_pool()->allocate(bytes);
case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes);
case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes);
case Chunk::size: return ChunkPool::large_pool()->allocate(bytes, alloc_failmode);
case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes, alloc_failmode);
case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes, alloc_failmode);
default: {
void *p = os::malloc(bytes, mtChunk, CALLER_PC);
if (p == NULL)
void* p = os::malloc(bytes, mtChunk, CALLER_PC);
if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "Chunk::new");
}
return p;
}
}
@ -425,7 +426,7 @@ NOT_PRODUCT(volatile jint Arena::_instance_count = 0;)
Arena::Arena(size_t init_size) {
size_t round_size = (sizeof (char *)) - 1;
init_size = (init_size+round_size) & ~round_size;
_first = _chunk = new (init_size) Chunk(init_size);
_first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(init_size);
@ -433,7 +434,7 @@ Arena::Arena(size_t init_size) {
}
Arena::Arena() {
_first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size);
_first = _chunk = new (AllocFailStrategy::EXIT_OOM, Chunk::init_size) Chunk(Chunk::init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(Chunk::init_size);
@ -540,12 +541,9 @@ void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
size_t len = MAX2(x, (size_t) Chunk::size);
Chunk *k = _chunk; // Get filled-up chunk address
_chunk = new (len) Chunk(len);
_chunk = new (alloc_failmode, len) Chunk(len);
if (_chunk == NULL) {
if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
}
return NULL;
}
if (k) k->set_next(_chunk); // Append new chunk to end of linked list