Mercurial > hg > truffle
comparison src/share/vm/ci/ciObjectFactory.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | f6b0eb4e44cf d8ce2825b193 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "ci/ciCPCache.hpp" | |
27 #include "ci/ciCallSite.hpp" | 26 #include "ci/ciCallSite.hpp" |
28 #include "ci/ciInstance.hpp" | 27 #include "ci/ciInstance.hpp" |
29 #include "ci/ciInstanceKlass.hpp" | 28 #include "ci/ciInstanceKlass.hpp" |
30 #include "ci/ciInstanceKlassKlass.hpp" | |
31 #include "ci/ciMemberName.hpp" | 29 #include "ci/ciMemberName.hpp" |
32 #include "ci/ciMethod.hpp" | 30 #include "ci/ciMethod.hpp" |
33 #include "ci/ciMethodData.hpp" | 31 #include "ci/ciMethodData.hpp" |
34 #include "ci/ciMethodHandle.hpp" | 32 #include "ci/ciMethodHandle.hpp" |
35 #include "ci/ciMethodKlass.hpp" | |
36 #include "ci/ciNullObject.hpp" | 33 #include "ci/ciNullObject.hpp" |
37 #include "ci/ciObjArray.hpp" | 34 #include "ci/ciObjArray.hpp" |
38 #include "ci/ciObjArrayKlass.hpp" | 35 #include "ci/ciObjArrayKlass.hpp" |
39 #include "ci/ciObjArrayKlassKlass.hpp" | 36 #include "ci/ciObject.hpp" |
40 #include "ci/ciObjectFactory.hpp" | 37 #include "ci/ciObjectFactory.hpp" |
41 #include "ci/ciSymbol.hpp" | 38 #include "ci/ciSymbol.hpp" |
42 #include "ci/ciTypeArray.hpp" | 39 #include "ci/ciTypeArray.hpp" |
43 #include "ci/ciTypeArrayKlass.hpp" | 40 #include "ci/ciTypeArrayKlass.hpp" |
44 #include "ci/ciTypeArrayKlassKlass.hpp" | |
45 #include "ci/ciUtilities.hpp" | 41 #include "ci/ciUtilities.hpp" |
46 #include "classfile/systemDictionary.hpp" | 42 #include "classfile/systemDictionary.hpp" |
47 #include "gc_interface/collectedHeap.inline.hpp" | 43 #include "gc_interface/collectedHeap.inline.hpp" |
48 #include "memory/allocation.inline.hpp" | 44 #include "memory/allocation.inline.hpp" |
49 #include "oops/oop.inline.hpp" | 45 #include "oops/oop.inline.hpp" |
65 // search to find the oop in the table, and inserting a new oop | 61 // search to find the oop in the table, and inserting a new oop |
66 // into the table may be costly. If this cost ends up being | 62 // into the table may be costly. If this cost ends up being |
67 // problematic the underlying data structure can be switched to some | 63 // problematic the underlying data structure can be switched to some |
68 // sort of balanced binary tree. | 64 // sort of balanced binary tree. |
69 | 65 |
70 GrowableArray<ciObject*>* ciObjectFactory::_shared_ci_objects = NULL; | 66 GrowableArray<ciMetadata*>* ciObjectFactory::_shared_ci_metadata = NULL; |
71 ciSymbol* ciObjectFactory::_shared_ci_symbols[vmSymbols::SID_LIMIT]; | 67 ciSymbol* ciObjectFactory::_shared_ci_symbols[vmSymbols::SID_LIMIT]; |
72 int ciObjectFactory::_shared_ident_limit = 0; | 68 int ciObjectFactory::_shared_ident_limit = 0; |
73 volatile bool ciObjectFactory::_initialized = false; | 69 volatile bool ciObjectFactory::_initialized = false; |
74 | 70 |
75 | 71 |
83 } | 79 } |
84 _non_perm_count = 0; | 80 _non_perm_count = 0; |
85 | 81 |
86 _next_ident = _shared_ident_limit; | 82 _next_ident = _shared_ident_limit; |
87 _arena = arena; | 83 _arena = arena; |
88 _ci_objects = new (arena) GrowableArray<ciObject*>(arena, expected_size, 0, NULL); | 84 _ci_metadata = new (arena) GrowableArray<ciMetadata*>(arena, expected_size, 0, NULL); |
89 | 85 |
90 // If the shared ci objects exist append them to this factory's objects | 86 // If the shared ci objects exist append them to this factory's objects |
91 | 87 |
92 if (_shared_ci_objects != NULL) { | 88 if (_shared_ci_metadata != NULL) { |
93 _ci_objects->appendAll(_shared_ci_objects); | 89 _ci_metadata->appendAll(_shared_ci_metadata); |
94 } | 90 } |
95 | 91 |
96 _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); | 92 _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); |
97 _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); | 93 _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); |
98 _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); | 94 _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); |
124 void ciObjectFactory::init_shared_objects() { | 120 void ciObjectFactory::init_shared_objects() { |
125 | 121 |
126 _next_ident = 1; // start numbering CI objects at 1 | 122 _next_ident = 1; // start numbering CI objects at 1 |
127 | 123 |
128 { | 124 { |
129 // Create the shared symbols, but not in _shared_ci_objects. | 125 // Create the shared symbols, but not in _shared_ci_metadata. |
130 int i; | 126 int i; |
131 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { | 127 for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { |
132 Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); | 128 Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); |
133 assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping"); | 129 assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping"); |
134 ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i); | 130 ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i); |
143 } | 139 } |
144 assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check"); | 140 assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check"); |
145 #endif | 141 #endif |
146 } | 142 } |
147 | 143 |
148 _ci_objects = new (_arena) GrowableArray<ciObject*>(_arena, 64, 0, NULL); | 144 _ci_metadata = new (_arena) GrowableArray<ciMetadata*>(_arena, 64, 0, NULL); |
149 | 145 |
150 for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) { | 146 for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) { |
151 BasicType t = (BasicType)i; | 147 BasicType t = (BasicType)i; |
152 if (type2name(t) != NULL && t != T_OBJECT && t != T_ARRAY && t != T_NARROWOOP) { | 148 if (type2name(t) != NULL && t != T_OBJECT && t != T_ARRAY && t != T_NARROWOOP) { |
153 ciType::_basic_types[t] = new (_arena) ciType(t); | 149 ciType::_basic_types[t] = new (_arena) ciType(t); |
155 } | 151 } |
156 } | 152 } |
157 | 153 |
158 ciEnv::_null_object_instance = new (_arena) ciNullObject(); | 154 ciEnv::_null_object_instance = new (_arena) ciNullObject(); |
159 init_ident_of(ciEnv::_null_object_instance); | 155 init_ident_of(ciEnv::_null_object_instance); |
160 ciEnv::_method_klass_instance = | |
161 get(Universe::methodKlassObj())->as_method_klass(); | |
162 ciEnv::_klass_klass_instance = | |
163 get(Universe::klassKlassObj())->as_klass_klass(); | |
164 ciEnv::_instance_klass_klass_instance = | |
165 get(Universe::instanceKlassKlassObj()) | |
166 ->as_instance_klass_klass(); | |
167 ciEnv::_type_array_klass_klass_instance = | |
168 get(Universe::typeArrayKlassKlassObj()) | |
169 ->as_type_array_klass_klass(); | |
170 ciEnv::_obj_array_klass_klass_instance = | |
171 get(Universe::objArrayKlassKlassObj()) | |
172 ->as_obj_array_klass_klass(); | |
173 | 156 |
174 #define WK_KLASS_DEFN(name, ignore_s, opt) \ | 157 #define WK_KLASS_DEFN(name, ignore_s, opt) \ |
175 if (SystemDictionary::name() != NULL) \ | 158 if (SystemDictionary::name() != NULL) \ |
176 ciEnv::_##name = get(SystemDictionary::name())->as_instance_klass(); | 159 ciEnv::_##name = get_metadata(SystemDictionary::name())->as_instance_klass(); |
177 | 160 |
178 WK_KLASSES_DO(WK_KLASS_DEFN) | 161 WK_KLASSES_DO(WK_KLASS_DEFN) |
179 #undef WK_KLASS_DEFN | 162 #undef WK_KLASS_DEFN |
180 | 163 |
181 for (int len = -1; len != _ci_objects->length(); ) { | 164 for (int len = -1; len != _ci_metadata->length(); ) { |
182 len = _ci_objects->length(); | 165 len = _ci_metadata->length(); |
183 for (int i2 = 0; i2 < len; i2++) { | 166 for (int i2 = 0; i2 < len; i2++) { |
184 ciObject* obj = _ci_objects->at(i2); | 167 ciMetadata* obj = _ci_metadata->at(i2); |
168 assert (obj->is_metadata(), "what else would it be?"); | |
185 if (obj->is_loaded() && obj->is_instance_klass()) { | 169 if (obj->is_loaded() && obj->is_instance_klass()) { |
186 obj->as_instance_klass()->compute_nonstatic_fields(); | 170 obj->as_instance_klass()->compute_nonstatic_fields(); |
187 } | 171 } |
188 } | 172 } |
189 } | 173 } |
190 | 174 |
191 ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); | 175 ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); |
192 // Create dummy instanceKlass and objArrayKlass object and assign them idents | 176 // Create dummy InstanceKlass and objArrayKlass object and assign them idents |
193 ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); | 177 ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); |
194 init_ident_of(ciEnv::_unloaded_ciinstance_klass); | 178 init_ident_of(ciEnv::_unloaded_ciinstance_klass); |
195 ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); | 179 ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); |
196 init_ident_of(ciEnv::_unloaded_ciobjarrayklass); | 180 init_ident_of(ciEnv::_unloaded_ciobjarrayklass); |
197 assert(ciEnv::_unloaded_ciobjarrayklass->is_obj_array_klass(), "just checking"); | 181 assert(ciEnv::_unloaded_ciobjarrayklass->is_obj_array_klass(), "just checking"); |
198 | 182 |
199 get(Universe::boolArrayKlassObj()); | 183 get_metadata(Universe::boolArrayKlassObj()); |
200 get(Universe::charArrayKlassObj()); | 184 get_metadata(Universe::charArrayKlassObj()); |
201 get(Universe::singleArrayKlassObj()); | 185 get_metadata(Universe::singleArrayKlassObj()); |
202 get(Universe::doubleArrayKlassObj()); | 186 get_metadata(Universe::doubleArrayKlassObj()); |
203 get(Universe::byteArrayKlassObj()); | 187 get_metadata(Universe::byteArrayKlassObj()); |
204 get(Universe::shortArrayKlassObj()); | 188 get_metadata(Universe::shortArrayKlassObj()); |
205 get(Universe::intArrayKlassObj()); | 189 get_metadata(Universe::intArrayKlassObj()); |
206 get(Universe::longArrayKlassObj()); | 190 get_metadata(Universe::longArrayKlassObj()); |
207 | 191 |
208 | 192 |
209 | 193 |
210 assert(_non_perm_count == 0, "no shared non-perm objects"); | 194 assert(_non_perm_count == 0, "no shared non-perm objects"); |
211 | 195 |
213 // be used for non-shared objects. That is, numbers less than | 197 // be used for non-shared objects. That is, numbers less than |
214 // this limit are permanently assigned to shared CI objects, | 198 // this limit are permanently assigned to shared CI objects, |
215 // while the higher numbers are recycled afresh by each new ciEnv. | 199 // while the higher numbers are recycled afresh by each new ciEnv. |
216 | 200 |
217 _shared_ident_limit = _next_ident; | 201 _shared_ident_limit = _next_ident; |
218 _shared_ci_objects = _ci_objects; | 202 _shared_ci_metadata = _ci_metadata; |
219 } | 203 } |
220 | 204 |
221 | 205 |
222 ciSymbol* ciObjectFactory::get_symbol(Symbol* key) { | 206 ciSymbol* ciObjectFactory::get_symbol(Symbol* key) { |
223 vmSymbols::SID sid = vmSymbols::find_sid(key); | 207 vmSymbols::SID sid = vmSymbols::find_sid(key); |
249 // already been created, it is returned. Otherwise, a new ciObject | 233 // already been created, it is returned. Otherwise, a new ciObject |
250 // is created. | 234 // is created. |
251 ciObject* ciObjectFactory::get(oop key) { | 235 ciObject* ciObjectFactory::get(oop key) { |
252 ASSERT_IN_VM; | 236 ASSERT_IN_VM; |
253 | 237 |
254 #ifdef ASSERT | 238 assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); |
255 if (CIObjectFactoryVerify) { | 239 |
256 oop last = NULL; | |
257 for (int j = 0; j< _ci_objects->length(); j++) { | |
258 oop o = _ci_objects->at(j)->get_oop(); | |
259 assert(last < o, "out of order"); | |
260 last = o; | |
261 } | |
262 } | |
263 #endif // ASSERT | |
264 int len = _ci_objects->length(); | |
265 int index = find(key, _ci_objects); | |
266 #ifdef ASSERT | |
267 if (CIObjectFactoryVerify) { | |
268 for (int i=0; i<_ci_objects->length(); i++) { | |
269 if (_ci_objects->at(i)->get_oop() == key) { | |
270 assert(index == i, " bad lookup"); | |
271 } | |
272 } | |
273 } | |
274 #endif | |
275 if (!is_found_at(index, key, _ci_objects)) { | |
276 // Check in the non-perm area before putting it in the list. | |
277 NonPermObject* &bucket = find_non_perm(key); | 240 NonPermObject* &bucket = find_non_perm(key); |
278 if (bucket != NULL) { | 241 if (bucket != NULL) { |
279 return bucket->object(); | 242 return bucket->object(); |
280 } | 243 } |
281 | 244 |
283 // into the cache. | 246 // into the cache. |
284 Handle keyHandle(key); | 247 Handle keyHandle(key); |
285 ciObject* new_object = create_new_object(keyHandle()); | 248 ciObject* new_object = create_new_object(keyHandle()); |
286 assert(keyHandle() == new_object->get_oop(), "must be properly recorded"); | 249 assert(keyHandle() == new_object->get_oop(), "must be properly recorded"); |
287 init_ident_of(new_object); | 250 init_ident_of(new_object); |
288 if (!new_object->is_perm()) { | 251 assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be"); |
252 | |
289 // Not a perm-space object. | 253 // Not a perm-space object. |
290 insert_non_perm(bucket, keyHandle(), new_object); | 254 insert_non_perm(bucket, keyHandle(), new_object); |
291 return new_object; | 255 return new_object; |
292 } | 256 } |
293 if (len != _ci_objects->length()) { | 257 |
258 // ------------------------------------------------------------------ | |
259 // ciObjectFactory::get | |
260 // | |
261 // Get the ciObject corresponding to some oop. If the ciObject has | |
262 // already been created, it is returned. Otherwise, a new ciObject | |
263 // is created. | |
264 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { | |
265 ASSERT_IN_VM; | |
266 | |
267 assert(key == NULL || key->is_metadata(), "must be"); | |
268 | |
269 #ifdef ASSERT | |
270 if (CIObjectFactoryVerify) { | |
271 Metadata* last = NULL; | |
272 for (int j = 0; j< _ci_metadata->length(); j++) { | |
273 Metadata* o = _ci_metadata->at(j)->constant_encoding(); | |
274 assert(last < o, "out of order"); | |
275 last = o; | |
276 } | |
277 } | |
278 #endif // ASSERT | |
279 int len = _ci_metadata->length(); | |
280 int index = find(key, _ci_metadata); | |
281 #ifdef ASSERT | |
282 if (CIObjectFactoryVerify) { | |
283 for (int i=0; i<_ci_metadata->length(); i++) { | |
284 if (_ci_metadata->at(i)->constant_encoding() == key) { | |
285 assert(index == i, " bad lookup"); | |
286 } | |
287 } | |
288 } | |
289 #endif | |
290 if (!is_found_at(index, key, _ci_metadata)) { | |
291 // The ciObject does not yet exist. Create it and insert it | |
292 // into the cache. | |
293 ciMetadata* new_object = create_new_object(key); | |
294 init_ident_of(new_object); | |
295 assert(new_object->is_metadata(), "must be"); | |
296 | |
297 if (len != _ci_metadata->length()) { | |
294 // creating the new object has recursively entered new objects | 298 // creating the new object has recursively entered new objects |
295 // into the table. We need to recompute our index. | 299 // into the table. We need to recompute our index. |
296 index = find(keyHandle(), _ci_objects); | 300 index = find(key, _ci_metadata); |
297 } | 301 } |
298 assert(!is_found_at(index, keyHandle(), _ci_objects), "no double insert"); | 302 assert(!is_found_at(index, key, _ci_metadata), "no double insert"); |
299 insert(index, new_object, _ci_objects); | 303 insert(index, new_object, _ci_metadata); |
300 return new_object; | 304 return new_object; |
301 } | 305 } |
302 return _ci_objects->at(index); | 306 return _ci_metadata->at(index)->as_metadata(); |
303 } | 307 } |
304 | 308 |
305 // ------------------------------------------------------------------ | 309 // ------------------------------------------------------------------ |
306 // ciObjectFactory::create_new_object | 310 // ciObjectFactory::create_new_object |
307 // | 311 // |
310 // Implementation note: this functionality could be virtual behavior | 314 // Implementation note: this functionality could be virtual behavior |
311 // of the oop itself. For now, we explicitly marshal the object. | 315 // of the oop itself. For now, we explicitly marshal the object. |
312 ciObject* ciObjectFactory::create_new_object(oop o) { | 316 ciObject* ciObjectFactory::create_new_object(oop o) { |
313 EXCEPTION_CONTEXT; | 317 EXCEPTION_CONTEXT; |
314 | 318 |
315 if (o->is_klass()) { | 319 if (o->is_instance()) { |
316 KlassHandle h_k(THREAD, (klassOop)o); | |
317 Klass* k = ((klassOop)o)->klass_part(); | |
318 if (k->oop_is_instance()) { | |
319 return new (arena()) ciInstanceKlass(h_k); | |
320 } else if (k->oop_is_objArray()) { | |
321 return new (arena()) ciObjArrayKlass(h_k); | |
322 } else if (k->oop_is_typeArray()) { | |
323 return new (arena()) ciTypeArrayKlass(h_k); | |
324 } else if (k->oop_is_method()) { | |
325 return new (arena()) ciMethodKlass(h_k); | |
326 } else if (k->oop_is_klass()) { | |
327 if (k->oop_is_objArrayKlass()) { | |
328 return new (arena()) ciObjArrayKlassKlass(h_k); | |
329 } else if (k->oop_is_typeArrayKlass()) { | |
330 return new (arena()) ciTypeArrayKlassKlass(h_k); | |
331 } else if (k->oop_is_instanceKlass()) { | |
332 return new (arena()) ciInstanceKlassKlass(h_k); | |
333 } else { | |
334 assert(o == Universe::klassKlassObj(), "bad klassKlass"); | |
335 return new (arena()) ciKlassKlass(h_k); | |
336 } | |
337 } | |
338 } else if (o->is_method()) { | |
339 methodHandle h_m(THREAD, (methodOop)o); | |
340 return new (arena()) ciMethod(h_m); | |
341 } else if (o->is_methodData()) { | |
342 methodDataHandle h_md(THREAD, (methodDataOop)o); | |
343 return new (arena()) ciMethodData(h_md); | |
344 } else if (o->is_instance()) { | |
345 instanceHandle h_i(THREAD, (instanceOop)o); | 320 instanceHandle h_i(THREAD, (instanceOop)o); |
346 if (java_lang_invoke_CallSite::is_instance(o)) | 321 if (java_lang_invoke_CallSite::is_instance(o)) |
347 return new (arena()) ciCallSite(h_i); | 322 return new (arena()) ciCallSite(h_i); |
348 else if (java_lang_invoke_MemberName::is_instance(o)) | 323 else if (java_lang_invoke_MemberName::is_instance(o)) |
349 return new (arena()) ciMemberName(h_i); | 324 return new (arena()) ciMemberName(h_i); |
355 objArrayHandle h_oa(THREAD, (objArrayOop)o); | 330 objArrayHandle h_oa(THREAD, (objArrayOop)o); |
356 return new (arena()) ciObjArray(h_oa); | 331 return new (arena()) ciObjArray(h_oa); |
357 } else if (o->is_typeArray()) { | 332 } else if (o->is_typeArray()) { |
358 typeArrayHandle h_ta(THREAD, (typeArrayOop)o); | 333 typeArrayHandle h_ta(THREAD, (typeArrayOop)o); |
359 return new (arena()) ciTypeArray(h_ta); | 334 return new (arena()) ciTypeArray(h_ta); |
360 } else if (o->is_constantPoolCache()) { | 335 } |
361 constantPoolCacheHandle h_cpc(THREAD, (constantPoolCacheOop) o); | 336 |
362 return new (arena()) ciCPCache(h_cpc); | 337 // The oop is of some type not supported by the compiler interface. |
338 ShouldNotReachHere(); | |
339 return NULL; | |
340 } | |
341 | |
342 // ------------------------------------------------------------------ | |
343 // ciObjectFactory::create_new_object | |
344 // | |
345 // Create a new ciObject from a Metadata*. | |
346 // | |
347 // Implementation note: this functionality could be virtual behavior | |
348 // of the oop itself. For now, we explicitly marshal the object. | |
349 ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { | |
350 EXCEPTION_CONTEXT; | |
351 | |
352 if (o->is_klass()) { | |
353 KlassHandle h_k(THREAD, (Klass*)o); | |
354 Klass* k = (Klass*)o; | |
355 if (k->oop_is_instance()) { | |
356 return new (arena()) ciInstanceKlass(h_k); | |
357 } else if (k->oop_is_objArray()) { | |
358 return new (arena()) ciObjArrayKlass(h_k); | |
359 } else if (k->oop_is_typeArray()) { | |
360 return new (arena()) ciTypeArrayKlass(h_k); | |
361 } | |
362 } else if (o->is_method()) { | |
363 methodHandle h_m(THREAD, (Method*)o); | |
364 return new (arena()) ciMethod(h_m); | |
365 } else if (o->is_methodData()) { | |
366 // Hold methodHandle alive - might not be necessary ??? | |
367 methodHandle h_m(THREAD, ((MethodData*)o)->method()); | |
368 return new (arena()) ciMethodData((MethodData*)o); | |
363 } | 369 } |
364 | 370 |
365 // The oop is of some type not supported by the compiler interface. | 371 // The oop is of some type not supported by the compiler interface. |
366 ShouldNotReachHere(); | 372 ShouldNotReachHere(); |
367 return NULL; | 373 return NULL; |
444 // This is a new unloaded klass. Create it and stick it in | 450 // This is a new unloaded klass. Create it and stick it in |
445 // the cache. | 451 // the cache. |
446 ciKlass* new_klass = NULL; | 452 ciKlass* new_klass = NULL; |
447 | 453 |
448 // Two cases: this is an unloaded objArrayKlass or an | 454 // Two cases: this is an unloaded objArrayKlass or an |
449 // unloaded instanceKlass. Deal with both. | 455 // unloaded InstanceKlass. Deal with both. |
450 if (name->byte_at(0) == '[') { | 456 if (name->byte_at(0) == '[') { |
451 // Decompose the name.' | 457 // Decompose the name.' |
452 FieldArrayInfo fd; | 458 FieldArrayInfo fd; |
453 BasicType element_type = FieldType::get_array_info(name->get_symbol(), | 459 BasicType element_type = FieldType::get_array_info(name->get_symbol(), |
454 fd, THREAD); | 460 fd, THREAD); |
588 return new_ret_addr; | 594 return new_ret_addr; |
589 } | 595 } |
590 | 596 |
591 // ------------------------------------------------------------------ | 597 // ------------------------------------------------------------------ |
592 // ciObjectFactory::init_ident_of | 598 // ciObjectFactory::init_ident_of |
593 void ciObjectFactory::init_ident_of(ciObject* obj) { | 599 void ciObjectFactory::init_ident_of(ciBaseObject* obj) { |
594 obj->set_ident(_next_ident++); | 600 obj->set_ident(_next_ident++); |
595 } | 601 } |
596 | |
597 void ciObjectFactory::init_ident_of(ciSymbol* obj) { | |
598 obj->set_ident(_next_ident++); | |
599 } | |
600 | |
601 | 602 |
602 // ------------------------------------------------------------------ | 603 // ------------------------------------------------------------------ |
603 // ciObjectFactory::find | 604 // ciObjectFactory::find |
604 // | 605 // |
605 // Use binary search to find the position of this oop in the cache. | 606 // Use binary search to find the position of this oop in the cache. |
606 // If there is no entry in the cache corresponding to this oop, return | 607 // If there is no entry in the cache corresponding to this oop, return |
607 // the position at which the oop should be inserted. | 608 // the position at which the oop should be inserted. |
608 int ciObjectFactory::find(oop key, GrowableArray<ciObject*>* objects) { | 609 int ciObjectFactory::find(Metadata* key, GrowableArray<ciMetadata*>* objects) { |
609 int min = 0; | 610 int min = 0; |
610 int max = objects->length()-1; | 611 int max = objects->length()-1; |
611 | 612 |
612 // print_contents(); | 613 // print_contents(); |
613 | 614 |
614 while (max >= min) { | 615 while (max >= min) { |
615 int mid = (max + min) / 2; | 616 int mid = (max + min) / 2; |
616 oop value = objects->at(mid)->get_oop(); | 617 Metadata* value = objects->at(mid)->constant_encoding(); |
617 if (value < key) { | 618 if (value < key) { |
618 min = mid + 1; | 619 min = mid + 1; |
619 } else if (value > key) { | 620 } else if (value > key) { |
620 max = mid - 1; | 621 max = mid - 1; |
621 } else { | 622 } else { |
627 | 628 |
628 // ------------------------------------------------------------------ | 629 // ------------------------------------------------------------------ |
629 // ciObjectFactory::is_found_at | 630 // ciObjectFactory::is_found_at |
630 // | 631 // |
631 // Verify that the binary seach found the given key. | 632 // Verify that the binary seach found the given key. |
632 bool ciObjectFactory::is_found_at(int index, oop key, GrowableArray<ciObject*>* objects) { | 633 bool ciObjectFactory::is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects) { |
633 return (index < objects->length() && | 634 return (index < objects->length() && |
634 objects->at(index)->get_oop() == key); | 635 objects->at(index)->constant_encoding() == key); |
635 } | 636 } |
636 | 637 |
637 | 638 |
638 // ------------------------------------------------------------------ | 639 // ------------------------------------------------------------------ |
639 // ciObjectFactory::insert | 640 // ciObjectFactory::insert |
640 // | 641 // |
641 // Insert a ciObject into the table at some index. | 642 // Insert a ciObject into the table at some index. |
642 void ciObjectFactory::insert(int index, ciObject* obj, GrowableArray<ciObject*>* objects) { | 643 void ciObjectFactory::insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects) { |
643 int len = objects->length(); | 644 int len = objects->length(); |
644 if (len == index) { | 645 if (len == index) { |
645 objects->append(obj); | 646 objects->append(obj); |
646 } else { | 647 } else { |
647 objects->append(objects->at(len-1)); | 648 objects->append(objects->at(len-1)); |
649 for (pos = len-2; pos >= index; pos--) { | 650 for (pos = len-2; pos >= index; pos--) { |
650 objects->at_put(pos+1,objects->at(pos)); | 651 objects->at_put(pos+1,objects->at(pos)); |
651 } | 652 } |
652 objects->at_put(index, obj); | 653 objects->at_put(index, obj); |
653 } | 654 } |
654 #ifdef ASSERT | |
655 if (CIObjectFactoryVerify) { | |
656 oop last = NULL; | |
657 for (int j = 0; j< objects->length(); j++) { | |
658 oop o = objects->at(j)->get_oop(); | |
659 assert(last < o, "out of order"); | |
660 last = o; | |
661 } | |
662 } | |
663 #endif // ASSERT | |
664 } | 655 } |
665 | 656 |
666 static ciObjectFactory::NonPermObject* emptyBucket = NULL; | 657 static ciObjectFactory::NonPermObject* emptyBucket = NULL; |
667 | 658 |
668 // ------------------------------------------------------------------ | 659 // ------------------------------------------------------------------ |
670 // | 661 // |
671 // Use a small hash table, hashed on the klass of the key. | 662 // Use a small hash table, hashed on the klass of the key. |
672 // If there is no entry in the cache corresponding to this oop, return | 663 // If there is no entry in the cache corresponding to this oop, return |
673 // the null tail of the bucket into which the oop should be inserted. | 664 // the null tail of the bucket into which the oop should be inserted. |
674 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { | 665 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { |
675 // Be careful: is_perm might change from false to true. | 666 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); |
676 // Thus, there might be a matching perm object in the table. | 667 ciMetadata* klass = get_metadata(key->klass()); |
677 // If there is, this probe must find it. | |
678 if (key->is_perm() && _non_perm_count == 0) { | |
679 return emptyBucket; | |
680 } else if (key->is_instance()) { | |
681 if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) { | |
682 // class mirror instances are always perm | |
683 return emptyBucket; | |
684 } | |
685 // fall through to probe | |
686 } else if (key->is_array()) { | |
687 // fall through to probe | |
688 } else { | |
689 // not an array or instance | |
690 return emptyBucket; | |
691 } | |
692 | |
693 ciObject* klass = get(key->klass()); | |
694 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; | 668 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; |
695 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { | 669 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { |
696 if (is_equal(p, key)) break; | 670 if (is_equal(p, key)) break; |
697 } | 671 } |
698 return (*bp); | 672 return (*bp); |
715 // ------------------------------------------------------------------ | 689 // ------------------------------------------------------------------ |
716 // ciObjectFactory::insert_non_perm | 690 // ciObjectFactory::insert_non_perm |
717 // | 691 // |
718 // Insert a ciObject into the non-perm table. | 692 // Insert a ciObject into the non-perm table. |
719 void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) { | 693 void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) { |
694 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); | |
720 assert(&where != &emptyBucket, "must not try to fill empty bucket"); | 695 assert(&where != &emptyBucket, "must not try to fill empty bucket"); |
721 NonPermObject* p = new (arena()) NonPermObject(where, key, obj); | 696 NonPermObject* p = new (arena()) NonPermObject(where, key, obj); |
722 assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match"); | 697 assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match"); |
723 assert(find_non_perm(key) == p, "must find the same spot"); | 698 assert(find_non_perm(key) == p, "must find the same spot"); |
724 ++_non_perm_count; | 699 ++_non_perm_count; |
731 assert(index >= vmSymbols::FIRST_SID && index < vmSymbols::SID_LIMIT, "oob"); | 706 assert(index >= vmSymbols::FIRST_SID && index < vmSymbols::SID_LIMIT, "oob"); |
732 return _shared_ci_symbols[index]; | 707 return _shared_ci_symbols[index]; |
733 } | 708 } |
734 | 709 |
735 // ------------------------------------------------------------------ | 710 // ------------------------------------------------------------------ |
711 // ciObjectFactory::metadata_do | |
712 void ciObjectFactory::metadata_do(void f(Metadata*)) { | |
713 if (_ci_metadata == NULL) return; | |
714 for (int j = 0; j< _ci_metadata->length(); j++) { | |
715 Metadata* o = _ci_metadata->at(j)->constant_encoding(); | |
716 f(o); | |
717 } | |
718 } | |
719 | |
720 // ------------------------------------------------------------------ | |
736 // ciObjectFactory::print_contents_impl | 721 // ciObjectFactory::print_contents_impl |
737 void ciObjectFactory::print_contents_impl() { | 722 void ciObjectFactory::print_contents_impl() { |
738 int len = _ci_objects->length(); | 723 int len = _ci_metadata->length(); |
739 tty->print_cr("ciObjectFactory (%d) oop contents:", len); | 724 tty->print_cr("ciObjectFactory (%d) meta data contents:", len); |
740 for (int i=0; i<len; i++) { | 725 for (int i=0; i<len; i++) { |
741 _ci_objects->at(i)->print(); | 726 _ci_metadata->at(i)->print(); |
742 tty->cr(); | 727 tty->cr(); |
743 } | 728 } |
744 } | 729 } |
745 | 730 |
746 // ------------------------------------------------------------------ | 731 // ------------------------------------------------------------------ |
754 // ------------------------------------------------------------------ | 739 // ------------------------------------------------------------------ |
755 // ciObjectFactory::print | 740 // ciObjectFactory::print |
756 // | 741 // |
757 // Print debugging information about the object factory | 742 // Print debugging information about the object factory |
758 void ciObjectFactory::print() { | 743 void ciObjectFactory::print() { |
759 tty->print("<ciObjectFactory oops=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>", | 744 tty->print("<ciObjectFactory oops=%d metadata=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>", |
760 _ci_objects->length(), _unloaded_methods->length(), | 745 _non_perm_count, _ci_metadata->length(), _unloaded_methods->length(), |
761 _unloaded_instances->length(), | 746 _unloaded_instances->length(), |
762 _unloaded_klasses->length()); | 747 _unloaded_klasses->length()); |
763 } | 748 } |