87 set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5) |
87 set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5) |
88 } |
88 } |
89 |
89 |
90 |
90 |
91 // Initialization of vtables and mirror object is done separatly from base_create_array_klass, |
91 // Initialization of vtables and mirror object is done separatly from base_create_array_klass, |
92 // since a GC can happen. At this point all instance variables of the arrayKlass must be setup. |
92 // since a GC can happen. At this point all instance variables of the ArrayKlass must be setup. |
93 void arrayKlass::complete_create_array_klass(arrayKlass* k, KlassHandle super_klass, TRAPS) { |
93 void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_klass, TRAPS) { |
94 ResourceMark rm(THREAD); |
94 ResourceMark rm(THREAD); |
95 k->initialize_supers(super_klass(), CHECK); |
95 k->initialize_supers(super_klass(), CHECK); |
96 k->vtable()->initialize_vtable(false, CHECK); |
96 k->vtable()->initialize_vtable(false, CHECK); |
97 java_lang_Class::create_mirror(k, CHECK); |
97 java_lang_Class::create_mirror(k, CHECK); |
98 } |
98 } |
99 |
99 |
100 GrowableArray<Klass*>* arrayKlass::compute_secondary_supers(int num_extra_slots) { |
100 GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) { |
101 // interfaces = { cloneable_klass, serializable_klass }; |
101 // interfaces = { cloneable_klass, serializable_klass }; |
102 assert(num_extra_slots == 0, "sanity of primitive array type"); |
102 assert(num_extra_slots == 0, "sanity of primitive array type"); |
103 // Must share this for correct bootstrapping! |
103 // Must share this for correct bootstrapping! |
104 set_secondary_supers(Universe::the_array_interfaces_array()); |
104 set_secondary_supers(Universe::the_array_interfaces_array()); |
105 return NULL; |
105 return NULL; |
106 } |
106 } |
107 |
107 |
108 bool arrayKlass::compute_is_subtype_of(Klass* k) { |
108 bool ArrayKlass::compute_is_subtype_of(Klass* k) { |
109 // An array is a subtype of Serializable, Clonable, and Object |
109 // An array is a subtype of Serializable, Clonable, and Object |
110 return k == SystemDictionary::Object_klass() |
110 return k == SystemDictionary::Object_klass() |
111 || k == SystemDictionary::Cloneable_klass() |
111 || k == SystemDictionary::Cloneable_klass() |
112 || k == SystemDictionary::Serializable_klass(); |
112 || k == SystemDictionary::Serializable_klass(); |
113 } |
113 } |
114 |
114 |
115 |
115 |
116 inline intptr_t* arrayKlass::start_of_vtable() const { |
116 inline intptr_t* ArrayKlass::start_of_vtable() const { |
117 // all vtables start at the same place, that's why we use InstanceKlass::header_size here |
117 // all vtables start at the same place, that's why we use InstanceKlass::header_size here |
118 return ((intptr_t*)this) + InstanceKlass::header_size(); |
118 return ((intptr_t*)this) + InstanceKlass::header_size(); |
119 } |
119 } |
120 |
120 |
121 |
121 |
122 klassVtable* arrayKlass::vtable() const { |
122 klassVtable* ArrayKlass::vtable() const { |
123 KlassHandle kh(Thread::current(), this); |
123 KlassHandle kh(Thread::current(), this); |
124 return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size()); |
124 return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size()); |
125 } |
125 } |
126 |
126 |
127 |
127 |
128 objArrayOop arrayKlass::allocate_arrayArray(int n, int length, TRAPS) { |
128 objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) { |
129 if (length < 0) { |
129 if (length < 0) { |
130 THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); |
130 THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); |
131 } |
131 } |
132 if (length > arrayOopDesc::max_array_length(T_ARRAY)) { |
132 if (length > arrayOopDesc::max_array_length(T_ARRAY)) { |
133 report_java_out_of_memory("Requested array size exceeds VM limit"); |
133 report_java_out_of_memory("Requested array size exceeds VM limit"); |
134 JvmtiExport::post_array_size_exhausted(); |
134 JvmtiExport::post_array_size_exhausted(); |
135 THROW_OOP_0(Universe::out_of_memory_error_array_size()); |
135 THROW_OOP_0(Universe::out_of_memory_error_array_size()); |
136 } |
136 } |
137 int size = objArrayOopDesc::object_size(length); |
137 int size = objArrayOopDesc::object_size(length); |
138 Klass* k = array_klass(n+dimension(), CHECK_0); |
138 Klass* k = array_klass(n+dimension(), CHECK_0); |
139 arrayKlass* ak = arrayKlass::cast(k); |
139 ArrayKlass* ak = ArrayKlass::cast(k); |
140 objArrayOop o = |
140 objArrayOop o = |
141 (objArrayOop)CollectedHeap::array_allocate(ak, size, length, CHECK_0); |
141 (objArrayOop)CollectedHeap::array_allocate(ak, size, length, CHECK_0); |
142 // initialization to NULL not necessary, area already cleared |
142 // initialization to NULL not necessary, area already cleared |
143 return o; |
143 return o; |
144 } |
144 } |
145 |
145 |
146 void arrayKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) { |
146 void ArrayKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) { |
147 Klass* k = this; |
147 Klass* k = this; |
148 // Iterate over this array klass and all higher dimensions |
148 // Iterate over this array klass and all higher dimensions |
149 while (k != NULL) { |
149 while (k != NULL) { |
150 f(k, CHECK); |
150 f(k, CHECK); |
151 k = arrayKlass::cast(k)->higher_dimension(); |
151 k = ArrayKlass::cast(k)->higher_dimension(); |
152 } |
152 } |
153 } |
153 } |
154 |
154 |
155 void arrayKlass::array_klasses_do(void f(Klass* k)) { |
155 void ArrayKlass::array_klasses_do(void f(Klass* k)) { |
156 Klass* k = this; |
156 Klass* k = this; |
157 // Iterate over this array klass and all higher dimensions |
157 // Iterate over this array klass and all higher dimensions |
158 while (k != NULL) { |
158 while (k != NULL) { |
159 f(k); |
159 f(k); |
160 k = arrayKlass::cast(k)->higher_dimension(); |
160 k = ArrayKlass::cast(k)->higher_dimension(); |
161 } |
161 } |
162 } |
162 } |
163 |
163 |
164 |
164 |
165 void arrayKlass::with_array_klasses_do(void f(Klass* k)) { |
165 void ArrayKlass::with_array_klasses_do(void f(Klass* k)) { |
166 array_klasses_do(f); |
166 array_klasses_do(f); |
167 } |
167 } |
168 |
168 |
169 |
169 |
170 // GC support |
170 // GC support |
171 |
171 |
172 void arrayKlass::oops_do(OopClosure* cl) { |
172 void ArrayKlass::oops_do(OopClosure* cl) { |
173 Klass::oops_do(cl); |
173 Klass::oops_do(cl); |
174 |
174 |
175 cl->do_oop(adr_component_mirror()); |
175 cl->do_oop(adr_component_mirror()); |
176 } |
176 } |
177 |
177 |
178 // JVM support |
178 // JVM support |
179 |
179 |
180 jint arrayKlass::compute_modifier_flags(TRAPS) const { |
180 jint ArrayKlass::compute_modifier_flags(TRAPS) const { |
181 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; |
181 return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; |
182 } |
182 } |
183 |
183 |
184 // JVMTI support |
184 // JVMTI support |
185 |
185 |
186 jint arrayKlass::jvmti_class_status() const { |
186 jint ArrayKlass::jvmti_class_status() const { |
187 return JVMTI_CLASS_STATUS_ARRAY; |
187 return JVMTI_CLASS_STATUS_ARRAY; |
188 } |
188 } |
189 |
189 |
190 void arrayKlass::remove_unshareable_info() { |
190 void ArrayKlass::remove_unshareable_info() { |
191 Klass::remove_unshareable_info(); |
191 Klass::remove_unshareable_info(); |
192 // Clear the java mirror |
192 // Clear the java mirror |
193 set_component_mirror(NULL); |
193 set_component_mirror(NULL); |
194 } |
194 } |
195 |
195 |
196 void arrayKlass::restore_unshareable_info(TRAPS) { |
196 void ArrayKlass::restore_unshareable_info(TRAPS) { |
197 Klass::restore_unshareable_info(CHECK); |
197 Klass::restore_unshareable_info(CHECK); |
198 // Klass recreates the component mirror also |
198 // Klass recreates the component mirror also |
199 } |
199 } |
200 |
200 |
201 // Printing |
201 // Printing |
202 |
202 |
203 void arrayKlass::print_on(outputStream* st) const { |
203 void ArrayKlass::print_on(outputStream* st) const { |
204 assert(is_klass(), "must be klass"); |
204 assert(is_klass(), "must be klass"); |
205 Klass::print_on(st); |
205 Klass::print_on(st); |
206 } |
206 } |
207 |
207 |
208 void arrayKlass::print_value_on(outputStream* st) const { |
208 void ArrayKlass::print_value_on(outputStream* st) const { |
209 assert(is_klass(), "must be klass"); |
209 assert(is_klass(), "must be klass"); |
210 for(int index = 0; index < dimension(); index++) { |
210 for(int index = 0; index < dimension(); index++) { |
211 st->print("[]"); |
211 st->print("[]"); |
212 } |
212 } |
213 } |
213 } |
214 |
214 |
215 void arrayKlass::oop_print_on(oop obj, outputStream* st) { |
215 void ArrayKlass::oop_print_on(oop obj, outputStream* st) { |
216 assert(obj->is_array(), "must be array"); |
216 assert(obj->is_array(), "must be array"); |
217 Klass::oop_print_on(obj, st); |
217 Klass::oop_print_on(obj, st); |
218 st->print_cr(" - length: %d", arrayOop(obj)->length()); |
218 st->print_cr(" - length: %d", arrayOop(obj)->length()); |
219 } |
219 } |
220 |
220 |
221 |
221 |
222 // Verification |
222 // Verification |
223 |
223 |
224 void arrayKlass::verify_on(outputStream* st) { |
224 void ArrayKlass::verify_on(outputStream* st) { |
225 Klass::verify_on(st); |
225 Klass::verify_on(st); |
226 |
226 |
227 if (component_mirror() != NULL) { |
227 if (component_mirror() != NULL) { |
228 guarantee(component_mirror()->klass() != NULL, "should have a class"); |
228 guarantee(component_mirror()->klass() != NULL, "should have a class"); |
229 } |
229 } |
230 } |
230 } |
231 |
231 |
232 void arrayKlass::oop_verify_on(oop obj, outputStream* st) { |
232 void ArrayKlass::oop_verify_on(oop obj, outputStream* st) { |
233 guarantee(obj->is_array(), "must be array"); |
233 guarantee(obj->is_array(), "must be array"); |
234 arrayOop a = arrayOop(obj); |
234 arrayOop a = arrayOop(obj); |
235 guarantee(a->length() >= 0, "array with negative length?"); |
235 guarantee(a->length() >= 0, "array with negative length?"); |
236 } |
236 } |