8253779: Amalloc may be wasting space by overaligning
Reviewed-by: kbarrett, stuefe
This commit is contained in:
parent
68b6e11e48
commit
ac75a53fc5
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2021, 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
|
||||
@ -72,7 +72,7 @@ public:
|
||||
|
||||
RegMask* live = (RegMask*)_live[node->_idx];
|
||||
if (live == NULL) {
|
||||
live = new (Compile::current()->comp_arena()->Amalloc_D(sizeof(RegMask))) RegMask();
|
||||
live = new (Compile::current()->comp_arena()->Amalloc_4(sizeof(RegMask))) RegMask();
|
||||
_live.map(node->_idx, (Node*)live);
|
||||
}
|
||||
|
||||
|
@ -27,19 +27,15 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
#include <new>
|
||||
|
||||
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
|
||||
// Note: this value must be a power of 2
|
||||
|
||||
#define ARENA_AMALLOC_ALIGNMENT (2*BytesPerWord)
|
||||
|
||||
#define ARENA_ALIGN_M1 (((size_t)(ARENA_AMALLOC_ALIGNMENT)) - 1)
|
||||
#define ARENA_ALIGN_MASK (~((size_t)ARENA_ALIGN_M1))
|
||||
#define ARENA_ALIGN(x) ((((size_t)(x)) + ARENA_ALIGN_M1) & ARENA_ALIGN_MASK)
|
||||
// The byte alignment to be used by Arena::Amalloc.
|
||||
#define ARENA_AMALLOC_ALIGNMENT BytesPerLong
|
||||
#define ARENA_ALIGN(x) (align_up((x), ARENA_AMALLOC_ALIGNMENT))
|
||||
|
||||
//------------------------------Chunk------------------------------------------
|
||||
// Linked list of raw memory chunks
|
||||
@ -136,28 +132,14 @@ protected:
|
||||
void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw();
|
||||
void operator delete(void* p);
|
||||
|
||||
// Fast allocate in the arena. Common case is: pointer test + increment.
|
||||
// Fast allocate in the arena. Common case aligns to the size of jlong which is 64 bits
|
||||
// on both 32 and 64 bit platforms. Required for atomic jlong operations on 32 bits.
|
||||
void* Amalloc(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
|
||||
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
|
||||
x = ARENA_ALIGN(x);
|
||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||
if (!check_for_overflow(x, "Arena::Amalloc", alloc_failmode))
|
||||
if (!check_for_overflow(x, "Arena::Amalloc", alloc_failmode)) {
|
||||
return NULL;
|
||||
if (_hwm + x > _max) {
|
||||
return grow(x, alloc_failmode);
|
||||
} else {
|
||||
char *old = _hwm;
|
||||
_hwm += x;
|
||||
return old;
|
||||
}
|
||||
}
|
||||
// Further assume size is padded out to words
|
||||
void *Amalloc_4(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
|
||||
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||
if (!check_for_overflow(x, "Arena::Amalloc_4", alloc_failmode))
|
||||
return NULL;
|
||||
if (_hwm + x > _max) {
|
||||
} else if (_hwm + x > _max) {
|
||||
return grow(x, alloc_failmode);
|
||||
} else {
|
||||
char *old = _hwm;
|
||||
@ -166,15 +148,15 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate with 'double' alignment. It is 8 bytes on sparc.
|
||||
// In other cases Amalloc_D() should be the same as Amalloc_4().
|
||||
void* Amalloc_D(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
|
||||
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
|
||||
// Allocate in the arena, assuming the size has been aligned to size of pointer, which
|
||||
// is 4 bytes on 32 bits, hence the name.
|
||||
void* Amalloc_4(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
|
||||
assert(is_aligned(x, BytesPerWord), "misaligned size");
|
||||
debug_only(if (UseMallocOnly) return malloc(x);)
|
||||
if (!check_for_overflow(x, "Arena::Amalloc_D", alloc_failmode))
|
||||
if (!check_for_overflow(x, "Arena::Amalloc_4", alloc_failmode)) {
|
||||
return NULL;
|
||||
if (_hwm + x > _max) {
|
||||
return grow(x, alloc_failmode); // grow() returns a result aligned >= 8 bytes.
|
||||
} else if (_hwm + x > _max) {
|
||||
return grow(x, alloc_failmode);
|
||||
} else {
|
||||
char *old = _hwm;
|
||||
_hwm += x;
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
// Allocate right next to the MachNodes in the same arena
|
||||
void *operator new(size_t x) throw() {
|
||||
Compile* C = Compile::current();
|
||||
return C->node_arena()->Amalloc_D(x);
|
||||
return C->node_arena()->Amalloc_4(x);
|
||||
}
|
||||
|
||||
// Opcode
|
||||
|
@ -442,7 +442,7 @@ static RegMask *init_input_masks( uint size, RegMask &ret_adr, RegMask &fp ) {
|
||||
void Matcher::init_first_stack_mask() {
|
||||
|
||||
// Allocate storage for spill masks as masks for the appropriate load type.
|
||||
RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * NOF_STACK_MASKS);
|
||||
RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_4(sizeof(RegMask) * NOF_STACK_MASKS);
|
||||
|
||||
// Initialize empty placeholder masks into the newly allocated arena
|
||||
for (int i = 0; i < NOF_STACK_MASKS; i++) {
|
||||
|
@ -308,7 +308,7 @@ inline int Node::Init(int req) {
|
||||
// Allocate memory for the necessary number of edges.
|
||||
if (req > 0) {
|
||||
// Allocate space for _in array to have double alignment.
|
||||
_in = (Node **) ((char *) (C->node_arena()->Amalloc_D(req * sizeof(void*))));
|
||||
_in = (Node **) ((char *) (C->node_arena()->Amalloc_4(req * sizeof(void*))));
|
||||
}
|
||||
// If there are default notes floating around, capture them:
|
||||
Node_Notes* nn = C->default_node_notes();
|
||||
@ -499,7 +499,7 @@ Node::Node(Node *n0, Node *n1, Node *n2, Node *n3,
|
||||
Node *Node::clone() const {
|
||||
Compile* C = Compile::current();
|
||||
uint s = size_of(); // Size of inherited Node
|
||||
Node *n = (Node*)C->node_arena()->Amalloc_D(size_of() + _max*sizeof(Node*));
|
||||
Node *n = (Node*)C->node_arena()->Amalloc_4(size_of() + _max*sizeof(Node*));
|
||||
Copy::conjoint_words_to_lower((HeapWord*)this, (HeapWord*)n, s);
|
||||
// Set the new input pointer array
|
||||
n->_in = (Node**)(((char*)n)+s);
|
||||
|
@ -239,7 +239,7 @@ public:
|
||||
|
||||
inline void* operator new(size_t x) throw() {
|
||||
Compile* C = Compile::current();
|
||||
Node* n = (Node*)C->node_arena()->Amalloc_D(x);
|
||||
Node* n = (Node*)C->node_arena()->Amalloc_4(x);
|
||||
return (void*)n;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ public:
|
||||
inline void* operator new( size_t x ) throw() {
|
||||
Compile* compile = Compile::current();
|
||||
compile->set_type_last_size(x);
|
||||
return compile->type_arena()->Amalloc_D(x);
|
||||
return compile->type_arena()->Amalloc_4(x);
|
||||
}
|
||||
inline void operator delete( void* ptr ) {
|
||||
Compile* compile = Compile::current();
|
||||
|
Loading…
Reference in New Issue
Block a user