243 assert(Universe::heap()->is_in_reserved(key), "must be");
244
245 NonPermObject* &bucket = find_non_perm(key);
246 if (bucket != NULL) {
247 return bucket->object();
248 }
249
250 // The ciObject does not yet exist. Create it and insert it
251 // into the cache.
252 Handle keyHandle(key);
253 ciObject* new_object = create_new_object(keyHandle());
254 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
255 init_ident_of(new_object);
256 assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be");
257
258 // Not a perm-space object.
259 insert_non_perm(bucket, keyHandle(), new_object);
260 return new_object;
261 }
262
263 // ------------------------------------------------------------------
264 // ciObjectFactory::get_metadata
265 //
266 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
267 // already been created, it is returned. Otherwise, a new ciMetadata
268 // is created.
269 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
270 ASSERT_IN_VM;
271
272 #ifdef ASSERT
273 if (CIObjectFactoryVerify) {
274 Metadata* last = NULL;
275 for (int j = 0; j< _ci_metadata->length(); j++) {
276 Metadata* o = _ci_metadata->at(j)->constant_encoding();
277 assert(last < o, "out of order");
278 last = o;
279 }
280 }
281 #endif // ASSERT
282 int len = _ci_metadata->length();
283 int index = find(key, _ci_metadata);
284 #ifdef ASSERT
285 if (CIObjectFactoryVerify) {
286 for (int i=0; i<_ci_metadata->length(); i++) {
287 if (_ci_metadata->at(i)->constant_encoding() == key) {
288 assert(index == i, " bad lookup");
289 }
290 }
291 }
292 #endif
293 if (!is_found_at(index, key, _ci_metadata)) {
294 // The ciMetadata does not yet exist. Create it and insert it
295 // into the cache.
296 ciMetadata* new_object = create_new_metadata(key);
297 init_ident_of(new_object);
298 assert(new_object->is_metadata(), "must be");
299
300 if (len != _ci_metadata->length()) {
301 // creating the new object has recursively entered new objects
302 // into the table. We need to recompute our index.
303 index = find(key, _ci_metadata);
304 }
305 assert(!is_found_at(index, key, _ci_metadata), "no double insert");
306 insert(index, new_object, _ci_metadata);
307 return new_object;
308 }
309 return _ci_metadata->at(index)->as_metadata();
310 }
311
312 // ------------------------------------------------------------------
313 // ciObjectFactory::create_new_object
314 //
315 // Create a new ciObject from an oop.
316 //
317 // Implementation note: this functionality could be virtual behavior
318 // of the oop itself. For now, we explicitly marshal the object.
319 ciObject* ciObjectFactory::create_new_object(oop o) {
320 EXCEPTION_CONTEXT;
321
322 if (o->is_instance()) {
323 instanceHandle h_i(THREAD, (instanceOop)o);
324 if (java_lang_invoke_CallSite::is_instance(o))
325 return new (arena()) ciCallSite(h_i);
326 else if (java_lang_invoke_MemberName::is_instance(o))
636 // Get a ciReturnAddress for a specified bci.
637 ciReturnAddress* ciObjectFactory::get_return_address(int bci) {
638 for (int i=0; i<_return_addresses->length(); i++) {
639 ciReturnAddress* entry = _return_addresses->at(i);
640 if (entry->bci() == bci) {
641 // We've found a match.
642 return entry;
643 }
644 }
645
646 ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
647 init_ident_of(new_ret_addr);
648 _return_addresses->append(new_ret_addr);
649 return new_ret_addr;
650 }
651
652 // ------------------------------------------------------------------
653 // ciObjectFactory::init_ident_of
654 void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
655 obj->set_ident(_next_ident++);
656 }
657
658 // ------------------------------------------------------------------
659 // ciObjectFactory::find
660 //
661 // Use binary search to find the position of this oop in the cache.
662 // If there is no entry in the cache corresponding to this oop, return
663 // the position at which the oop should be inserted.
664 int ciObjectFactory::find(Metadata* key, GrowableArray<ciMetadata*>* objects) {
665 int min = 0;
666 int max = objects->length()-1;
667
668 // print_contents();
669
670 while (max >= min) {
671 int mid = (max + min) / 2;
672 Metadata* value = objects->at(mid)->constant_encoding();
673 if (value < key) {
674 min = mid + 1;
675 } else if (value > key) {
676 max = mid - 1;
677 } else {
678 return mid;
679 }
680 }
681 return min;
682 }
683
684 // ------------------------------------------------------------------
685 // ciObjectFactory::is_found_at
686 //
687 // Verify that the binary seach found the given key.
688 bool ciObjectFactory::is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects) {
689 return (index < objects->length() &&
690 objects->at(index)->constant_encoding() == key);
691 }
692
693
694 // ------------------------------------------------------------------
695 // ciObjectFactory::insert
696 //
697 // Insert a ciObject into the table at some index.
698 void ciObjectFactory::insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects) {
699 int len = objects->length();
700 if (len == index) {
701 objects->append(obj);
702 } else {
703 objects->append(objects->at(len-1));
704 int pos;
705 for (pos = len-2; pos >= index; pos--) {
706 objects->at_put(pos+1,objects->at(pos));
707 }
708 objects->at_put(index, obj);
709 }
710 }
711
712 static ciObjectFactory::NonPermObject* emptyBucket = NULL;
713
714 // ------------------------------------------------------------------
715 // ciObjectFactory::find_non_perm
716 //
717 // Use a small hash table, hashed on the klass of the key.
718 // If there is no entry in the cache corresponding to this oop, return
719 // the null tail of the bucket into which the oop should be inserted.
720 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
721 assert(Universe::heap()->is_in_reserved(key), "must be");
722 ciMetadata* klass = get_metadata(key->klass());
723 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
724 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
725 if (is_equal(p, key)) break;
726 }
727 return (*bp);
728 }
729
|
243 assert(Universe::heap()->is_in_reserved(key), "must be");
244
245 NonPermObject* &bucket = find_non_perm(key);
246 if (bucket != NULL) {
247 return bucket->object();
248 }
249
250 // The ciObject does not yet exist. Create it and insert it
251 // into the cache.
252 Handle keyHandle(key);
253 ciObject* new_object = create_new_object(keyHandle());
254 assert(keyHandle() == new_object->get_oop(), "must be properly recorded");
255 init_ident_of(new_object);
256 assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be");
257
258 // Not a perm-space object.
259 insert_non_perm(bucket, keyHandle(), new_object);
260 return new_object;
261 }
262
263 int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
264 Metadata* value = elt->constant_encoding();
265 if (key < value) return -1;
266 else if (key > value) return 1;
267 else return 0;
268 }
269
270 // ------------------------------------------------------------------
271 // ciObjectFactory::get_metadata
272 //
273 // Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
274 // already been created, it is returned. Otherwise, a new ciMetadata
275 // is created.
276 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
277 ASSERT_IN_VM;
278
279 #ifdef ASSERT
280 if (CIObjectFactoryVerify) {
281 Metadata* last = NULL;
282 for (int j = 0; j< _ci_metadata->length(); j++) {
283 Metadata* o = _ci_metadata->at(j)->constant_encoding();
284 assert(last < o, "out of order");
285 last = o;
286 }
287 }
288 #endif // ASSERT
289 int len = _ci_metadata->length();
290 bool found = false;
291 int index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
292 #ifdef ASSERT
293 if (CIObjectFactoryVerify) {
294 for (int i=0; i<_ci_metadata->length(); i++) {
295 if (_ci_metadata->at(i)->constant_encoding() == key) {
296 assert(index == i, " bad lookup");
297 }
298 }
299 }
300 #endif
301
302 if (!found) {
303 // The ciMetadata does not yet exist. Create it and insert it
304 // into the cache.
305 ciMetadata* new_object = create_new_metadata(key);
306 init_ident_of(new_object);
307 assert(new_object->is_metadata(), "must be");
308
309 if (len != _ci_metadata->length()) {
310 // creating the new object has recursively entered new objects
311 // into the table. We need to recompute our index.
312 index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
313 }
314 assert(!found, "no double insert");
315 _ci_metadata->insert_before(index, new_object);
316 return new_object;
317 }
318 return _ci_metadata->at(index)->as_metadata();
319 }
320
321 // ------------------------------------------------------------------
322 // ciObjectFactory::create_new_object
323 //
324 // Create a new ciObject from an oop.
325 //
326 // Implementation note: this functionality could be virtual behavior
327 // of the oop itself. For now, we explicitly marshal the object.
328 ciObject* ciObjectFactory::create_new_object(oop o) {
329 EXCEPTION_CONTEXT;
330
331 if (o->is_instance()) {
332 instanceHandle h_i(THREAD, (instanceOop)o);
333 if (java_lang_invoke_CallSite::is_instance(o))
334 return new (arena()) ciCallSite(h_i);
335 else if (java_lang_invoke_MemberName::is_instance(o))
645 // Get a ciReturnAddress for a specified bci.
646 ciReturnAddress* ciObjectFactory::get_return_address(int bci) {
647 for (int i=0; i<_return_addresses->length(); i++) {
648 ciReturnAddress* entry = _return_addresses->at(i);
649 if (entry->bci() == bci) {
650 // We've found a match.
651 return entry;
652 }
653 }
654
655 ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci);
656 init_ident_of(new_ret_addr);
657 _return_addresses->append(new_ret_addr);
658 return new_ret_addr;
659 }
660
661 // ------------------------------------------------------------------
662 // ciObjectFactory::init_ident_of
663 void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
664 obj->set_ident(_next_ident++);
665 }
666
667 static ciObjectFactory::NonPermObject* emptyBucket = NULL;
668
669 // ------------------------------------------------------------------
670 // ciObjectFactory::find_non_perm
671 //
672 // Use a small hash table, hashed on the klass of the key.
673 // If there is no entry in the cache corresponding to this oop, return
674 // the null tail of the bucket into which the oop should be inserted.
675 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
676 assert(Universe::heap()->is_in_reserved(key), "must be");
677 ciMetadata* klass = get_metadata(key->klass());
678 NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
679 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
680 if (is_equal(p, key)) break;
681 }
682 return (*bp);
683 }
684
|