< prev index next >

src/hotspot/share/ci/ciEnv.cpp

Print this page


 377     return true;
 378   }
 379 
 380   if (resolved_klass->is_objArray_klass()) {
 381     // Find the element klass, if this is an array.
 382     resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
 383   }
 384   if (resolved_klass->is_instance_klass()) {
 385     return (Reflection::verify_class_access(accessing_klass->get_Klass(),
 386                                             InstanceKlass::cast(resolved_klass),
 387                                             true) == Reflection::ACCESS_OK);
 388   }
 389   return true;
 390 }
 391 
 392 // ------------------------------------------------------------------
 393 // ciEnv::get_klass_by_name_impl
 394 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
 395                                        const constantPoolHandle& cpool,
 396                                        ciSymbol* name,
 397                                        bool require_local) {

 398   ASSERT_IN_VM;
 399   EXCEPTION_CONTEXT;
 400 
 401   // Now we need to check the SystemDictionary
 402   Symbol* sym = name->get_symbol();
 403   if ((sym->byte_at(0) == 'L' || sym->byte_at(0) == 'Q') &&
 404     sym->byte_at(sym->utf8_length()-1) == ';') {
 405     // This is a name from a signature.  Strip off the trimmings.
 406     // Call recursive to keep scope of strippedsym.
 407     TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
 408                     sym->utf8_length()-2,
 409                     KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
 410     ciSymbol* strippedname = get_symbol(strippedsym);
 411     return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);

 412   }
 413 
 414   // Check for prior unloaded klass.  The SystemDictionary's answers
 415   // can vary over time but the compiler needs consistency.
 416   ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name);
 417   if (unloaded_klass != NULL) {
 418     if (require_local)  return NULL;
 419     return unloaded_klass;
 420   }
 421 
 422   Handle loader(THREAD, (oop)NULL);
 423   Handle domain(THREAD, (oop)NULL);
 424   if (accessing_klass != NULL) {
 425     loader = Handle(THREAD, accessing_klass->loader());
 426     domain = Handle(THREAD, accessing_klass->protection_domain());
 427   }
 428 
 429   // setup up the proper type to return on OOM
 430   ciKlass* fail_type;
 431   if (sym->byte_at(0) == '[') {


 446                                                            KILL_COMPILE_ON_FATAL_(fail_type));
 447     }
 448     found_klass = kls;
 449   }
 450 
 451   // If we fail to find an array klass, look again for its element type.
 452   // The element type may be available either locally or via constraints.
 453   // In either case, if we can find the element type in the system dictionary,
 454   // we must build an array type around it.  The CI requires array klasses
 455   // to be loaded if their element klasses are loaded, except when memory
 456   // is exhausted.
 457   if (sym->byte_at(0) == '[' &&
 458       (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L' || sym->byte_at(1) == 'Q')) {
 459     // We have an unloaded array.
 460     // Build it on the fly if the element class exists.
 461     TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
 462                                                  sym->utf8_length()-1,
 463                                                  KILL_COMPILE_ON_FATAL_(fail_type));
 464 
 465     // Get element ciKlass recursively.

 466     ciKlass* elem_klass =
 467       get_klass_by_name_impl(accessing_klass,
 468                              cpool,
 469                              get_symbol(elem_sym),
 470                              require_local);
 471     if (elem_klass != NULL && elem_klass->is_loaded()) {
 472       // Now make an array for it
 473       if (elem_klass->is_valuetype() && elem_klass->as_value_klass()->flatten_array()) {
 474         return ciValueArrayKlass::make_impl(elem_klass);
 475       } else {
 476         return ciObjArrayKlass::make_impl(elem_klass);
 477       }
 478     }
 479   }
 480 
 481   if (found_klass == NULL && !cpool.is_null() && cpool->has_preresolution()) {
 482     // Look inside the constant pool for pre-resolved class entries.
 483     for (int i = cpool->length() - 1; i >= 1; i--) {
 484       if (cpool->tag_at(i).is_klass()) {
 485         Klass* kls = cpool->resolved_klass_at(i);
 486         if (kls->name() == sym) {
 487           found_klass = kls;
 488           break;
 489         }
 490       }
 491     }
 492   }
 493 
 494   if (found_klass != NULL) {
 495     // Found it.  Build a CI handle.
 496     return get_klass(found_klass);
 497   }
 498 
 499   if (require_local)  return NULL;
 500 
 501   // Not yet loaded into the VM, or not governed by loader constraints.
 502   // Make a CI representative for it.
 503   int i = 0;
 504   while (sym->byte_at(i) == '[') {
 505     i++;
 506   }
 507   if (i > 0 && sym->byte_at(i) == 'Q') {





 508     // An unloaded array class of value types is an ObjArrayKlass, an
 509     // unloaded value type class is an InstanceKlass. For consistency,
 510     // make the signature of the unloaded array of value type use L
 511     // rather than Q.
 512     char *new_name = CURRENT_THREAD_ENV->name_buffer(sym->utf8_length()+1);
 513     strncpy(new_name, (char*)sym->base(), sym->utf8_length());
 514     new_name[i] = 'L';
 515     new_name[sym->utf8_length()] = '\0';
 516     return get_unloaded_klass(accessing_klass, ciSymbol::make(new_name));

 517   }
 518   return get_unloaded_klass(accessing_klass, name);
 519 }
 520 
 521 // ------------------------------------------------------------------
 522 // ciEnv::get_klass_by_name
 523 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass,
 524                                   ciSymbol* klass_name,
 525                                   bool require_local) {
 526   GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass,
 527                                                  constantPoolHandle(),
 528                                                  klass_name,
 529                                                  require_local);)
 530 }
 531 
 532 // ------------------------------------------------------------------
 533 // ciEnv::get_klass_by_index_impl
 534 //
 535 // Implementation of get_klass_by_index.
 536 ciKlass* ciEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
 537                                         int index,
 538                                         bool& is_accessible,




 377     return true;
 378   }
 379 
 380   if (resolved_klass->is_objArray_klass()) {
 381     // Find the element klass, if this is an array.
 382     resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
 383   }
 384   if (resolved_klass->is_instance_klass()) {
 385     return (Reflection::verify_class_access(accessing_klass->get_Klass(),
 386                                             InstanceKlass::cast(resolved_klass),
 387                                             true) == Reflection::ACCESS_OK);
 388   }
 389   return true;
 390 }
 391 
 392 // ------------------------------------------------------------------
 393 // ciEnv::get_klass_by_name_impl
 394 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
 395                                        const constantPoolHandle& cpool,
 396                                        ciSymbol* name,
 397                                        bool require_local,
 398                                        bool is_value_type) {
 399   ASSERT_IN_VM;
 400   EXCEPTION_CONTEXT;
 401 
 402   // Now we need to check the SystemDictionary
 403   Symbol* sym = name->get_symbol();
 404   if ((sym->byte_at(0) == 'L' || sym->byte_at(0) == 'Q') &&
 405     sym->byte_at(sym->utf8_length()-1) == ';') {
 406     // This is a name from a signature.  Strip off the trimmings.
 407     // Call recursive to keep scope of strippedsym.
 408     TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
 409                     sym->utf8_length()-2,
 410                     KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
 411     ciSymbol* strippedname = get_symbol(strippedsym);
 412     is_value_type = (sym->byte_at(0) == 'Q');
 413     return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local, is_value_type);
 414   }
 415 
 416   // Check for prior unloaded klass.  The SystemDictionary's answers
 417   // can vary over time but the compiler needs consistency.
 418   ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name);
 419   if (unloaded_klass != NULL) {
 420     if (require_local)  return NULL;
 421     return unloaded_klass;
 422   }
 423 
 424   Handle loader(THREAD, (oop)NULL);
 425   Handle domain(THREAD, (oop)NULL);
 426   if (accessing_klass != NULL) {
 427     loader = Handle(THREAD, accessing_klass->loader());
 428     domain = Handle(THREAD, accessing_klass->protection_domain());
 429   }
 430 
 431   // setup up the proper type to return on OOM
 432   ciKlass* fail_type;
 433   if (sym->byte_at(0) == '[') {


 448                                                            KILL_COMPILE_ON_FATAL_(fail_type));
 449     }
 450     found_klass = kls;
 451   }
 452 
 453   // If we fail to find an array klass, look again for its element type.
 454   // The element type may be available either locally or via constraints.
 455   // In either case, if we can find the element type in the system dictionary,
 456   // we must build an array type around it.  The CI requires array klasses
 457   // to be loaded if their element klasses are loaded, except when memory
 458   // is exhausted.
 459   if (sym->byte_at(0) == '[' &&
 460       (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L' || sym->byte_at(1) == 'Q')) {
 461     // We have an unloaded array.
 462     // Build it on the fly if the element class exists.
 463     TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
 464                                                  sym->utf8_length()-1,
 465                                                  KILL_COMPILE_ON_FATAL_(fail_type));
 466 
 467     // Get element ciKlass recursively.
 468     is_value_type = (sym->byte_at(1) == 'Q');
 469     ciKlass* elem_klass =
 470       get_klass_by_name_impl(accessing_klass,
 471                              cpool,
 472                              get_symbol(elem_sym),
 473                              require_local, is_value_type);
 474     if (elem_klass != NULL && elem_klass->is_loaded()) {
 475       // Now make an array for it
 476       if (elem_klass->is_valuetype() && elem_klass->as_value_klass()->flatten_array()) {
 477         return ciValueArrayKlass::make_impl(elem_klass);
 478       } else {
 479         return ciObjArrayKlass::make_impl(elem_klass);
 480       }
 481     }
 482   }
 483 
 484   if (found_klass == NULL && !cpool.is_null() && cpool->has_preresolution()) {
 485     // Look inside the constant pool for pre-resolved class entries.
 486     for (int i = cpool->length() - 1; i >= 1; i--) {
 487       if (cpool->tag_at(i).is_klass()) {
 488         Klass* kls = cpool->resolved_klass_at(i);
 489         if (kls->name() == sym) {
 490           found_klass = kls;
 491           break;
 492         }
 493       }
 494     }
 495   }
 496 
 497   if (found_klass != NULL) {
 498     // Found it.  Build a CI handle.
 499     return get_klass(found_klass);
 500   }
 501 
 502   if (require_local)  return NULL;
 503 
 504   // Not yet loaded into the VM, or not governed by loader constraints.
 505   // Make a CI representative for it.
 506   int i = 0;
 507   while (sym->byte_at(i) == '[') {
 508     i++;
 509   }
 510   if (i > 0 && sym->byte_at(i) == 'Q') {
 511     if (EnableValhallaC1) {
 512       return get_unloaded_klass(accessing_klass, name, true);
 513     } else {
 514       // FIXME - C2 can't handle unloaded ciValueKlass
 515       
 516       // An unloaded array class of value types is an ObjArrayKlass, an
 517       // unloaded value type class is an InstanceKlass. For consistency,
 518       // make the signature of the unloaded array of value type use L
 519       // rather than Q.
 520       char *new_name = CURRENT_THREAD_ENV->name_buffer(sym->utf8_length()+1);
 521       strncpy(new_name, (char*)sym->base(), sym->utf8_length());
 522       new_name[i] = 'L';
 523       new_name[sym->utf8_length()] = '\0';
 524       return get_unloaded_klass(accessing_klass, ciSymbol::make(new_name), false);
 525     }
 526   }
 527   return get_unloaded_klass(accessing_klass, name, is_value_type);
 528 }
 529 
 530 // ------------------------------------------------------------------
 531 // ciEnv::get_klass_by_name
 532 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass,
 533                                   ciSymbol* klass_name,
 534                                   bool require_local) {
 535   GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass,
 536                                                  constantPoolHandle(),
 537                                                  klass_name,
 538                                                  require_local);)
 539 }
 540 
 541 // ------------------------------------------------------------------
 542 // ciEnv::get_klass_by_index_impl
 543 //
 544 // Implementation of get_klass_by_index.
 545 ciKlass* ciEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
 546                                         int index,
 547                                         bool& is_accessible,


< prev index next >