1/*
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24#ifndef SHARE_VM_MEMORY_METACHUNK_HPP
25#define SHARE_VM_MEMORY_METACHUNK_HPP
26
27#include "memory/allocation.hpp"
28#include "utilities/debug.hpp"
29#include "utilities/globalDefinitions.hpp"
30
31class VirtualSpaceNode;
32
33// Super class of Metablock and Metachunk to allow them to
34// be put on the FreeList and in the BinaryTreeDictionary.
35template <class T>
36class Metabase VALUE_OBJ_CLASS_SPEC {
37  size_t _word_size;
38  T*     _next;
39  T*     _prev;
40
41 protected:
42  Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {}
43
44 public:
45  T* next() const         { return _next; }
46  T* prev() const         { return _prev; }
47  void set_next(T* v)     { _next = v; assert(v != this, "Boom");}
48  void set_prev(T* v)     { _prev = v; assert(v != this, "Boom");}
49  void clear_next()       { set_next(NULL); }
50  void clear_prev()       { set_prev(NULL); }
51
52  size_t size() const volatile { return _word_size; }
53  void set_size(size_t v) { _word_size = v; }
54
55  void link_next(T* ptr)  { set_next(ptr); }
56  void link_prev(T* ptr)  { set_prev(ptr); }
57  void link_after(T* ptr) {
58    link_next(ptr);
59    if (ptr != NULL) ptr->link_prev((T*)this);
60  }
61
62  uintptr_t* end() const        { return ((uintptr_t*) this) + size(); }
63
64  bool cantCoalesce() const     { return false; }
65
66  // Debug support
67#ifdef ASSERT
68  void* prev_addr() const { return (void*)&_prev; }
69  void* next_addr() const { return (void*)&_next; }
70  void* size_addr() const { return (void*)&_word_size; }
71#endif
72  bool verify_chunk_in_free_list(T* tc) const { return true; }
73  bool verify_par_locked() { return true; }
74
75  void assert_is_mangled() const {/* Don't check "\*/}
76
77  bool is_free()                 { return true; }
78};
79
80//  Metachunk - Quantum of allocation from a Virtualspace
81//    Metachunks are reused (when freed are put on a global freelist) and
82//    have no permanent association to a SpaceManager.
83
84//            +--------------+ <- end    --+       --+
85//            |              |             |         |
86//            |              |             | free    |
87//            |              |             |         |
88//            |              |             |         | size | capacity
89//            |              |             |         |
90//            |              | <- top   -- +         |
91//            |              |             |         |
92//            |              |             | used    |
93//            |              |             |         |
94//            |              |             |         |
95//            +--------------+ <- bottom --+       --+
96
97class Metachunk : public Metabase<Metachunk> {
98  friend class MetachunkTest;
99  // The VirtualSpaceNode containing this chunk.
100  VirtualSpaceNode* _container;
101
102  // Current allocation top.
103  MetaWord* _top;
104
105  DEBUG_ONLY(bool _is_tagged_free;)
106
107  MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
108  MetaWord* top() const         { return _top; }
109
110 public:
111  // Metachunks are allocated out of a MetadataVirtualSpace and
112  // and use some of its space to describe itself (plus alignment
113  // considerations).  Metadata is allocated in the rest of the chunk.
114  // This size is the overhead of maintaining the Metachunk within
115  // the space.
116
117  // Alignment of each allocation in the chunks.
118  static size_t object_alignment();
119
120  // Size of the Metachunk header, including alignment.
121  static size_t overhead();
122
123  Metachunk(size_t word_size , VirtualSpaceNode* container);
124
125  MetaWord* allocate(size_t word_size);
126
127  VirtualSpaceNode* container() const { return _container; }
128
129  MetaWord* bottom() const { return (MetaWord*) this; }
130
131  // Reset top to bottom so chunk can be reused.
132  void reset_empty() { _top = initial_top(); clear_next(); clear_prev(); }
133  bool is_empty() { return _top == initial_top(); }
134
135  // used (has been allocated)
136  // free (available for future allocations)
137  size_t word_size() const { return size(); }
138  size_t used_word_size() const;
139  size_t free_word_size() const;
140
141#ifdef ASSERT
142  bool is_tagged_free() { return _is_tagged_free; }
143  void set_is_tagged_free(bool v) { _is_tagged_free = v; }
144#endif
145
146  bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
147
148#ifndef PRODUCT
149  void mangle(juint word_value);
150#endif
151
152  void print_on(outputStream* st) const;
153  void verify();
154};
155
156// Metablock is the unit of allocation from a Chunk.
157//
158// A Metablock may be reused by its SpaceManager but are never moved between
159// SpaceManagers.  There is no explicit link to the Metachunk
160// from which it was allocated.  Metablock may be deallocated and
161// put on a freelist but the space is never freed, rather
162// the Metachunk it is a part of will be deallocated when it's
163// associated class loader is collected.
164
165class Metablock : public Metabase<Metablock> {
166  friend class VMStructs;
167 public:
168  Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
169};
170
171#endif  // SHARE_VM_MEMORY_METACHUNK_HPP
172