46 return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord; |
46 return align_up(sizeof(Metachunk), object_alignment()) / BytesPerWord; |
47 } |
47 } |
48 |
48 |
49 // Metachunk methods |
49 // Metachunk methods |
50 |
50 |
51 Metachunk::Metachunk(size_t word_size, |
51 Metachunk::Metachunk(ChunkIndex chunktype, bool is_class, size_t word_size, |
52 VirtualSpaceNode* container) |
52 VirtualSpaceNode* container) |
53 : Metabase<Metachunk>(word_size), |
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), |
54 _top(NULL), |
59 _top(NULL), |
55 _container(container) |
60 _container(container) |
56 { |
61 { |
57 _top = initial_top(); |
62 _top = initial_top(); |
58 set_is_tagged_free(false); |
63 set_is_tagged_free(false); |
59 #ifdef ASSERT |
64 #ifdef ASSERT |
60 mangle(uninitMetaWordVal); |
65 mangle(uninitMetaWordVal); |
|
66 verify(); |
61 #endif |
67 #endif |
62 } |
68 } |
63 |
69 |
64 MetaWord* Metachunk::allocate(size_t word_size) { |
70 MetaWord* Metachunk::allocate(size_t word_size) { |
65 MetaWord* result = NULL; |
71 MetaWord* result = NULL; |
81 } |
87 } |
82 |
88 |
83 void Metachunk::print_on(outputStream* st) const { |
89 void Metachunk::print_on(outputStream* st) const { |
84 st->print_cr("Metachunk:" |
90 st->print_cr("Metachunk:" |
85 " bottom " PTR_FORMAT " top " PTR_FORMAT |
91 " bottom " PTR_FORMAT " top " PTR_FORMAT |
86 " end " PTR_FORMAT " size " SIZE_FORMAT, |
92 " end " PTR_FORMAT " size " SIZE_FORMAT " (%s)", |
87 p2i(bottom()), p2i(_top), p2i(end()), word_size()); |
93 p2i(bottom()), p2i(_top), p2i(end()), word_size(), |
|
94 chunk_size_name(get_chunk_type())); |
88 if (Verbose) { |
95 if (Verbose) { |
89 st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, |
96 st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, |
90 used_word_size(), free_word_size()); |
97 used_word_size(), free_word_size()); |
91 } |
98 } |
92 } |
99 } |
93 |
100 |
94 #ifndef PRODUCT |
101 #ifdef ASSERT |
95 void Metachunk::mangle(juint word_value) { |
102 void Metachunk::mangle(juint word_value) { |
96 // Overwrite the payload of the chunk and not the links that |
103 // Overwrite the payload of the chunk and not the links that |
97 // maintain list of chunks. |
104 // maintain list of chunks. |
98 HeapWord* start = (HeapWord*)initial_top(); |
105 HeapWord* start = (HeapWord*)initial_top(); |
99 size_t size = word_size() - overhead(); |
106 size_t size = word_size() - overhead(); |
100 Copy::fill_to_words(start, size, word_value); |
107 Copy::fill_to_words(start, size, word_value); |
101 } |
108 } |
102 #endif // PRODUCT |
|
103 |
109 |
104 void Metachunk::verify() { |
110 void Metachunk::verify() { |
105 #ifdef ASSERT |
111 assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this)); |
106 // Cannot walk through the blocks unless the blocks have |
112 const ChunkIndex chunk_type = get_chunk_type(); |
107 // headers with sizes. |
113 assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this)); |
108 assert(bottom() <= _top && |
114 if (chunk_type != HumongousIndex) { |
109 _top <= (MetaWord*)end(), |
115 assert(word_size() == get_size_for_nonhumongous_chunktype(chunk_type, is_class()), |
110 "Chunk has been smashed"); |
116 "Chunk " PTR_FORMAT ": wordsize " SIZE_FORMAT " does not fit chunk type %s.", |
111 #endif |
117 p2i(this), word_size(), chunk_size_name(chunk_type)); |
112 return; |
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); |
113 } |
131 } |
114 |
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 } |