31
32 class VirtualSpaceNode;
33
34 size_t Metachunk::object_alignment() {
35 // Must align pointers and sizes to 8,
36 // so that 64 bit types get correctly aligned.
37 const size_t alignment = 8;
38
39 // Make sure that the Klass alignment also agree.
40 STATIC_ASSERT(alignment == (size_t)KlassAlignmentInBytes);
41
42 return alignment;
43 }
44
45 size_t Metachunk::overhead() {
46 return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
47 }
48
49 // Metachunk methods
50
51 Metachunk::Metachunk(size_t word_size,
52 VirtualSpaceNode* container)
53 : Metabase<Metachunk>(word_size),
54 _top(NULL),
55 _container(container)
56 {
57 _top = initial_top();
58 set_is_tagged_free(false);
59 #ifdef ASSERT
60 mangle(uninitMetaWordVal);
61 #endif
62 }
63
64 MetaWord* Metachunk::allocate(size_t word_size) {
65 MetaWord* result = NULL;
66 // If available, bump the pointer to allocate.
67 if (free_word_size() >= word_size) {
68 result = _top;
69 _top = _top + word_size;
70 }
71 return result;
72 }
73
74 // _bottom points to the start of the chunk including the overhead.
75 size_t Metachunk::used_word_size() const {
76 return pointer_delta(_top, bottom(), sizeof(MetaWord));
77 }
78
79 size_t Metachunk::free_word_size() const {
80 return pointer_delta(end(), _top, sizeof(MetaWord));
81 }
82
83 void Metachunk::print_on(outputStream* st) const {
84 st->print_cr("Metachunk:"
85 " bottom " PTR_FORMAT " top " PTR_FORMAT
86 " end " PTR_FORMAT " size " SIZE_FORMAT,
87 p2i(bottom()), p2i(_top), p2i(end()), word_size());
88 if (Verbose) {
89 st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT,
90 used_word_size(), free_word_size());
91 }
92 }
93
94 #ifndef PRODUCT
95 void Metachunk::mangle(juint word_value) {
96 // Overwrite the payload of the chunk and not the links that
97 // maintain list of chunks.
98 HeapWord* start = (HeapWord*)initial_top();
99 size_t size = word_size() - overhead();
100 Copy::fill_to_words(start, size, word_value);
101 }
102 #endif // PRODUCT
103
104 void Metachunk::verify() {
105 #ifdef ASSERT
106 // Cannot walk through the blocks unless the blocks have
107 // headers with sizes.
108 assert(bottom() <= _top &&
109 _top <= (MetaWord*)end(),
110 "Chunk has been smashed");
111 #endif
112 return;
113 }
114
|
31
32 class VirtualSpaceNode;
33
34 size_t Metachunk::object_alignment() {
35 // Must align pointers and sizes to 8,
36 // so that 64 bit types get correctly aligned.
37 const size_t alignment = 8;
38
39 // Make sure that the Klass alignment also agree.
40 STATIC_ASSERT(alignment == (size_t)KlassAlignmentInBytes);
41
42 return alignment;
43 }
44
45 size_t Metachunk::overhead() {
46 return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord;
47 }
48
49 // Metachunk methods
50
51 Metachunk::Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size,
52 VirtualSpaceNode* container)
53 : Metabase<Metachunk>(word_size),
54 _chunk_type(chunktype),
55 _is_class(is_class),
56 _sentinel(CHUNK_SENTINEL),
57 _origin(origin_normal),
58 _use_count(0),
59 _top(NULL),
60 _container(container)
61 {
62 _top = initial_top();
63 set_is_tagged_free(false);
64 #ifdef ASSERT
65 mangle(uninitMetaWordVal);
66 verify();
67 #endif
68 }
69
70 MetaWord* Metachunk::allocate(size_t word_size) {
71 MetaWord* result = NULL;
72 // If available, bump the pointer to allocate.
73 if (free_word_size() >= word_size) {
74 result = _top;
75 _top = _top + word_size;
76 }
77 return result;
78 }
79
80 // _bottom points to the start of the chunk including the overhead.
81 size_t Metachunk::used_word_size() const {
82 return pointer_delta(_top, bottom(), sizeof(MetaWord));
83 }
84
85 size_t Metachunk::free_word_size() const {
86 return pointer_delta(end(), _top, sizeof(MetaWord));
87 }
88
89 void Metachunk::print_on(outputStream* st) const {
90 st->print_cr("Metachunk:"
91 " bottom " PTR_FORMAT " top " PTR_FORMAT
92 " end " PTR_FORMAT " size " SIZE_FORMAT " (%s)",
93 p2i(bottom()), p2i(_top), p2i(end()), word_size(),
94 chunk_size_name(get_chunk_type()));
95 if (Verbose) {
96 st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT,
97 used_word_size(), free_word_size());
98 }
99 }
100
101 #ifdef ASSERT
102 void Metachunk::mangle(juint word_value) {
103 // Overwrite the payload of the chunk and not the links that
104 // maintain list of chunks.
105 HeapWord* start = (HeapWord*)initial_top();
106 size_t size = word_size() - overhead();
107 Copy::fill_to_words(start, size, word_value);
108 }
109
110 void Metachunk::verify() {
111 assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this));
112 const ChunkIndex chunk_type = get_chunk_type();
113 assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this));
114 if (chunk_type != HumongousIndex) {
115 assert(word_size() == get_size_for_nonhumongous_chunktype(chunk_type, is_class()),
116 "Chunk " PTR_FORMAT ": wordsize " SIZE_FORMAT " does not fit chunk type %s.",
117 p2i(this), word_size(), chunk_size_name(chunk_type));
118 }
119 assert(is_valid_chunkorigin(get_origin()), "Chunk " PTR_FORMAT ": Invalid chunk origin.", p2i(this));
120 assert(bottom() <= _top && _top <= (MetaWord*)end(),
121 "Chunk " PTR_FORMAT ": Chunk top out of chunk bounds.", p2i(this));
122
123 // For non-humongous chunks, starting address shall be aligned
124 // to its chunk size. Humongous chunks start address is
125 // aligned to specialized chunk size.
126 const size_t required_alignment =
127 (chunk_type != HumongousIndex ? word_size() : get_size_for_nonhumongous_chunktype(SpecializedIndex, is_class())) * sizeof(MetaWord);
128 assert(is_aligned((address)this, required_alignment),
129 "Chunk " PTR_FORMAT ": (size " SIZE_FORMAT ") not aligned to " SIZE_FORMAT ".",
130 p2i(this), word_size() * sizeof(MetaWord), required_alignment);
131 }
132
133 #endif // ASSERT
134
135 // Helper, returns a descriptive name for the given index.
136 const char* chunk_size_name(ChunkIndex index) {
137 switch (index) {
138 case SpecializedIndex:
139 return "specialized";
140 case SmallIndex:
141 return "small";
142 case MediumIndex:
143 return "medium";
144 case HumongousIndex:
145 return "humongous";
146 default:
147 return "Invalid index";
148 }
149 }
|