1.1 --- a/src/share/vm/memory/metachunk.hpp Tue Oct 15 07:10:09 2013 -0700 1.2 +++ b/src/share/vm/memory/metachunk.hpp Tue Oct 15 14:28:51 2013 +0200 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -24,89 +24,44 @@ 1.11 #ifndef SHARE_VM_MEMORY_METACHUNK_HPP 1.12 #define SHARE_VM_MEMORY_METACHUNK_HPP 1.13 1.14 -// Metachunk - Quantum of allocation from a Virtualspace 1.15 -// Metachunks are reused (when freed are put on a global freelist) and 1.16 -// have no permanent association to a SpaceManager. 1.17 - 1.18 -// +--------------+ <- end 1.19 -// | | --+ ---+ 1.20 -// | | | free | 1.21 -// | | | | 1.22 -// | | | | capacity 1.23 -// | | | | 1.24 -// | | <- top --+ | 1.25 -// | | ---+ | 1.26 -// | | | used | 1.27 -// | | | | 1.28 -// | | | | 1.29 -// +--------------+ <- bottom ---+ ---+ 1.30 +#include "memory/allocation.hpp" 1.31 +#include "utilities/debug.hpp" 1.32 +#include "utilities/globalDefinitions.hpp" 1.33 1.34 class VirtualSpaceNode; 1.35 1.36 -class Metachunk VALUE_OBJ_CLASS_SPEC { 1.37 - // link to support lists of chunks 1.38 - Metachunk* _next; 1.39 - Metachunk* _prev; 1.40 - VirtualSpaceNode* _container; 1.41 +// Super class of Metablock and Metachunk to allow them to 1.42 +// be put on the FreeList and in the BinaryTreeDictionary. 1.43 +template <class T> 1.44 +class Metabase VALUE_OBJ_CLASS_SPEC { 1.45 + size_t _word_size; 1.46 + T* _next; 1.47 + T* _prev; 1.48 1.49 - MetaWord* _bottom; 1.50 - MetaWord* _end; 1.51 - MetaWord* _top; 1.52 - size_t _word_size; 1.53 - // Used in a guarantee() so included in the Product builds 1.54 - // even through it is only for debugging. 1.55 - bool _is_free; 1.56 - 1.57 - // Metachunks are allocated out of a MetadataVirtualSpace and 1.58 - // and use some of its space to describe itself (plus alignment 1.59 - // considerations). Metadata is allocated in the rest of the chunk. 1.60 - // This size is the overhead of maintaining the Metachunk within 1.61 - // the space. 1.62 - static size_t _overhead; 1.63 + protected: 1.64 + Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {} 1.65 1.66 public: 1.67 - Metachunk(size_t word_size , VirtualSpaceNode* container); 1.68 + T* next() const { return _next; } 1.69 + T* prev() const { return _prev; } 1.70 + void set_next(T* v) { _next = v; assert(v != this, "Boom");} 1.71 + void set_prev(T* v) { _prev = v; assert(v != this, "Boom");} 1.72 + void clear_next() { set_next(NULL); } 1.73 + void clear_prev() { set_prev(NULL); } 1.74 1.75 - // Used to add a Metachunk to a list of Metachunks 1.76 - void set_next(Metachunk* v) { _next = v; assert(v != this, "Boom");} 1.77 - void set_prev(Metachunk* v) { _prev = v; assert(v != this, "Boom");} 1.78 - void set_container(VirtualSpaceNode* v) { _container = v; } 1.79 - 1.80 - MetaWord* allocate(size_t word_size); 1.81 - 1.82 - // Accessors 1.83 - Metachunk* next() const { return _next; } 1.84 - Metachunk* prev() const { return _prev; } 1.85 - VirtualSpaceNode* container() const { return _container; } 1.86 - MetaWord* bottom() const { return _bottom; } 1.87 - MetaWord* end() const { return _end; } 1.88 - MetaWord* top() const { return _top; } 1.89 - size_t word_size() const { return _word_size; } 1.90 size_t size() const volatile { return _word_size; } 1.91 void set_size(size_t v) { _word_size = v; } 1.92 - bool is_free() { return _is_free; } 1.93 - void set_is_free(bool v) { _is_free = v; } 1.94 - static size_t overhead() { return _overhead; } 1.95 - void clear_next() { set_next(NULL); } 1.96 - void link_prev(Metachunk* ptr) { set_prev(ptr); } 1.97 - uintptr_t* end() { return ((uintptr_t*) this) + size(); } 1.98 - bool cantCoalesce() const { return false; } 1.99 - void link_next(Metachunk* ptr) { set_next(ptr); } 1.100 - void link_after(Metachunk* ptr){ 1.101 + 1.102 + void link_next(T* ptr) { set_next(ptr); } 1.103 + void link_prev(T* ptr) { set_prev(ptr); } 1.104 + void link_after(T* ptr) { 1.105 link_next(ptr); 1.106 - if (ptr != NULL) ptr->link_prev(this); 1.107 + if (ptr != NULL) ptr->link_prev((T*)this); 1.108 } 1.109 1.110 - // Reset top to bottom so chunk can be reused. 1.111 - void reset_empty() { _top = (_bottom + _overhead); _next = NULL; _prev = NULL; } 1.112 - bool is_empty() { return _top == (_bottom + _overhead); } 1.113 + uintptr_t* end() const { return ((uintptr_t*) this) + size(); } 1.114 1.115 - // used (has been allocated) 1.116 - // free (available for future allocations) 1.117 - // capacity (total size of chunk) 1.118 - size_t used_word_size() const; 1.119 - size_t free_word_size() const; 1.120 - size_t capacity_word_size()const; 1.121 + bool cantCoalesce() const { return false; } 1.122 1.123 // Debug support 1.124 #ifdef ASSERT 1.125 @@ -114,14 +69,98 @@ 1.126 void* next_addr() const { return (void*)&_next; } 1.127 void* size_addr() const { return (void*)&_word_size; } 1.128 #endif 1.129 - bool verify_chunk_in_free_list(Metachunk* tc) const { return true; } 1.130 + bool verify_chunk_in_free_list(T* tc) const { return true; } 1.131 bool verify_par_locked() { return true; } 1.132 1.133 void assert_is_mangled() const {/* Don't check "\*/} 1.134 1.135 - NOT_PRODUCT(void mangle();) 1.136 + bool is_free() { return true; } 1.137 +}; 1.138 + 1.139 +// Metachunk - Quantum of allocation from a Virtualspace 1.140 +// Metachunks are reused (when freed are put on a global freelist) and 1.141 +// have no permanent association to a SpaceManager. 1.142 + 1.143 +// +--------------+ <- end --+ --+ 1.144 +// | | | | 1.145 +// | | | free | 1.146 +// | | | | 1.147 +// | | | | size | capacity 1.148 +// | | | | 1.149 +// | | <- top -- + | 1.150 +// | | | | 1.151 +// | | | used | 1.152 +// | | | | 1.153 +// | | | | 1.154 +// +--------------+ <- bottom --+ --+ 1.155 + 1.156 +class Metachunk : public Metabase<Metachunk> { 1.157 + friend class TestMetachunk; 1.158 + // The VirtualSpaceNode containing this chunk. 1.159 + VirtualSpaceNode* _container; 1.160 + 1.161 + // Current allocation top. 1.162 + MetaWord* _top; 1.163 + 1.164 + DEBUG_ONLY(bool _is_tagged_free;) 1.165 + 1.166 + MetaWord* initial_top() const { return (MetaWord*)this + overhead(); } 1.167 + MetaWord* top() const { return _top; } 1.168 + 1.169 + public: 1.170 + // Metachunks are allocated out of a MetadataVirtualSpace and 1.171 + // and use some of its space to describe itself (plus alignment 1.172 + // considerations). Metadata is allocated in the rest of the chunk. 1.173 + // This size is the overhead of maintaining the Metachunk within 1.174 + // the space. 1.175 + 1.176 + // Alignment of each allocation in the chunks. 1.177 + static size_t object_alignment(); 1.178 + 1.179 + // Size of the Metachunk header, including alignment. 1.180 + static size_t overhead(); 1.181 + 1.182 + Metachunk(size_t word_size , VirtualSpaceNode* container); 1.183 + 1.184 + MetaWord* allocate(size_t word_size); 1.185 + 1.186 + VirtualSpaceNode* container() const { return _container; } 1.187 + 1.188 + MetaWord* bottom() const { return (MetaWord*) this; } 1.189 + 1.190 + // Reset top to bottom so chunk can be reused. 1.191 + void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); } 1.192 + bool is_empty() { return _top == initial_top(); } 1.193 + 1.194 + // used (has been allocated) 1.195 + // free (available for future allocations) 1.196 + size_t word_size() const { return size(); } 1.197 + size_t used_word_size() const; 1.198 + size_t free_word_size() const; 1.199 + 1.200 +#ifdef ASSERT 1.201 + void mangle(); 1.202 + bool is_tagged_free() { return _is_tagged_free; } 1.203 + void set_is_tagged_free(bool v) { _is_tagged_free = v; } 1.204 +#endif 1.205 1.206 void print_on(outputStream* st) const; 1.207 void verify(); 1.208 }; 1.209 + 1.210 +// Metablock is the unit of allocation from a Chunk. 1.211 +// 1.212 +// A Metablock may be reused by its SpaceManager but are never moved between 1.213 +// SpaceManagers. There is no explicit link to the Metachunk 1.214 +// from which it was allocated. Metablock may be deallocated and 1.215 +// put on a freelist but the space is never freed, rather 1.216 +// the Metachunk it is a part of will be deallocated when it's 1.217 +// associated class loader is collected. 1.218 + 1.219 +class Metablock : public Metabase<Metablock> { 1.220 + friend class VMStructs; 1.221 + public: 1.222 + Metablock(size_t word_size) : Metabase<Metablock>(word_size) {} 1.223 +}; 1.224 + 1.225 #endif // SHARE_VM_MEMORY_METACHUNK_HPP