219 // Return nest-host class, resolving, validating and saving it if needed. 220 // In cases where this is called from a thread that cannot do classloading 221 // (such as a native JIT thread) then we simply return NULL, which in turn 222 // causes the access check to return false. Such code will retry the access 223 // from a more suitable environment later. Otherwise the _nest_host is always 224 // set once this method returns. 225 // Any errors from nest-host resolution must be preserved so they can be queried 226 // from higher-level access checking code, and reported as part of access checking 227 // exceptions. 228 // VirtualMachineErrors are propagated with a NULL return. 229 // Under any conditions where the _nest_host can be set to non-NULL the resulting value 230 // of it and, if applicable, _nest_host_res_error, are idempotent. But as we can be 231 // executing this code concurrently we need to ensure ordering is maintained so that 232 // errors messages can safely be read. 233 InstanceKlass* InstanceKlass::nest_host(TRAPS) { 234 InstanceKlass* nest_host_k = _nest_host; 235 if (nest_host_k != NULL) { 236 return nest_host_k; 237 } 238 239 const bool doLog = log_is_enabled(Trace, class, nestmates); 240 241 // need to resolve and save our nest-host class. 242 if (_nest_host_index != 0) { // we have a real nest_host 243 // Before trying to resolve check if we're in a suitable context 244 if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { 245 if (doLog) { 246 ResourceMark rm(THREAD); 247 log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", 248 this->external_name()); 249 } 250 return NULL; // sentinel to say "try again from a different context" 251 } 252 253 if (doLog) { 254 ResourceMark rm(THREAD); 255 log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", 256 this->external_name(), 257 _constants->klass_name_at(_nest_host_index)->as_C_string()); 258 } 259 260 Klass* k = _constants->klass_at(_nest_host_index, THREAD); 261 if (HAS_PENDING_EXCEPTION) { 262 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 263 return NULL; // propagate VMEs 264 } 265 ResourceMark rm(THREAD); 266 stringStream ss; 267 char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string(); 268 ss.print("Nest host resolution of %s with host %s failed: ", 269 this->external_name(), target_host_class); 270 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 271 _nest_host_res_error = ss.as_string(true /* on C-heap */); 272 // ensure we see _nest_host_res_error is set if _nest_host is non-NULL 273 OrderAccess::storestore(); 274 CLEAR_PENDING_EXCEPTION; 275 if (doLog) { 276 log_trace(class, nestmates)("%s", _nest_host_res_error); 277 } 278 } else { 279 // A valid nest-host is an instance class in the current package that lists this 280 // class as a nest member. If any of these conditions are not met the class is 281 // its own nest-host. 282 const char* error = NULL; 283 284 // JVMS 5.4.4 indicates package check comes first 285 if (is_same_class_package(k)) { 286 // Now check actual membership. We can't be a member if our "host" is 287 // not an instance class. 288 if (k->is_instance_klass()) { 289 nest_host_k = InstanceKlass::cast(k); 290 bool is_member = nest_host_k->has_nest_member(this, THREAD); 291 // exception is rare, perhaps impossible 292 if (!HAS_PENDING_EXCEPTION) { 293 if (is_member) { 294 _nest_host = nest_host_k; // save resolved nest-host value 295 if (doLog) { 296 ResourceMark rm(THREAD); 297 log_trace(class, nestmates)("Resolved nest-host of %s to %s", 298 this->external_name(), k->external_name()); 299 } 300 return nest_host_k; 301 } else { 302 error = "current type is not listed as a nest member"; 303 } 304 } else { 305 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 306 return NULL; // propagate VMEs 307 } 308 stringStream ss; 309 ss.print("exception on member check: "); 310 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 311 error = ss.as_string(); 312 } 313 } else { 314 error = "host is not an instance class"; 315 } 316 } else { 317 error = "types are in different packages"; 318 } 319 320 // something went wrong, so record what and log it 321 { 322 ResourceMark rm(THREAD); 323 stringStream ss; 324 ss.print("Type %s (loader: %s) is not a nest member of type %s (loader: %s): %s", 325 this->external_name(), 326 this->class_loader_data()->loader_name_and_id(), 327 k->external_name(), 328 k->class_loader_data()->loader_name_and_id(), 329 error); 330 _nest_host_res_error = ss.as_string(true /* on C-heap */); 331 // ensure we see _nest_host_res_error is set if _nest_host is non-NULL 332 OrderAccess::storestore(); 333 334 if (doLog) { 335 log_trace(class, nestmates)("%s", _nest_host_res_error); 336 } 337 } 338 } 339 } else { 340 if (doLog) { 341 ResourceMark rm(THREAD); 342 log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", 343 this->external_name()); 344 } 345 } 346 347 // Either not in an explicit nest, or else an error occurred, so 348 // the nest-host is set to `this`. Any thread that sees this assignment 349 // will also see any setting of _nest_host_res_error, if applicable. 350 return (_nest_host = this); 351 } 352 353 // Dynamic nest member support: set this class's nest host to the given class. 354 // This occurs as part of the class definition, as soon as the instanceKlass 355 // has been created and doesn't require further resolution. The code: 356 // lookup().defineHiddenClass(bytes_for_X, NESTMATE); 357 // results in: 358 // class_of_X.set_nest_host(lookup().lookupClass().getNestHost()) 359 // If it has an explicit _nest_host_index or _nest_members, these will be ignored. 360 // We also know the "host" is a valid nest-host in the same package so we can 361 // assert some of those facts. 362 void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) { 363 assert(is_hidden(), "must be a hidden class"); 364 assert(host != NULL, "NULL nest host specified"); 365 assert(_nest_host == NULL, "current class has resolved nest-host"); 394 // Any exceptions (i.e. VMEs) are propagated. 395 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { 396 397 assert(this != k, "this should be handled by higher-level code"); 398 399 // Per JVMS 5.4.4 we first resolve and validate the current class, then 400 // the target class k. 401 402 InstanceKlass* cur_host = nest_host(CHECK_false); 403 if (cur_host == NULL) { 404 return false; 405 } 406 407 Klass* k_nest_host = k->nest_host(CHECK_false); 408 if (k_nest_host == NULL) { 409 return false; 410 } 411 412 bool access = (cur_host == k_nest_host); 413 414 if (log_is_enabled(Trace, class, nestmates)) { 415 ResourceMark rm(THREAD); 416 log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", 417 this->external_name(), 418 access ? "" : "NOT ", 419 k->external_name()); 420 } 421 422 return access; 423 } 424 425 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { 426 bool is_hidden_or_anonymous = parser.is_hidden() || parser.is_unsafe_anonymous(); 427 const int size = InstanceKlass::size(parser.vtable_size(), 428 parser.itable_size(), 429 nonstatic_oop_map_size(parser.total_oop_map_count()), 430 parser.is_interface(), 431 is_hidden_or_anonymous, 432 should_store_fingerprint(is_hidden_or_anonymous)); 433 434 const Symbol* const class_name = parser.class_name(); 435 assert(class_name != NULL, "invariant"); 436 ClassLoaderData* loader_data = parser.loader_data(); 437 assert(loader_data != NULL, "invariant"); 438 439 InstanceKlass* ik; 440 441 // Allocation | 219 // Return nest-host class, resolving, validating and saving it if needed. 220 // In cases where this is called from a thread that cannot do classloading 221 // (such as a native JIT thread) then we simply return NULL, which in turn 222 // causes the access check to return false. Such code will retry the access 223 // from a more suitable environment later. Otherwise the _nest_host is always 224 // set once this method returns. 225 // Any errors from nest-host resolution must be preserved so they can be queried 226 // from higher-level access checking code, and reported as part of access checking 227 // exceptions. 228 // VirtualMachineErrors are propagated with a NULL return. 229 // Under any conditions where the _nest_host can be set to non-NULL the resulting value 230 // of it and, if applicable, _nest_host_res_error, are idempotent. But as we can be 231 // executing this code concurrently we need to ensure ordering is maintained so that 232 // errors messages can safely be read. 233 InstanceKlass* InstanceKlass::nest_host(TRAPS) { 234 InstanceKlass* nest_host_k = _nest_host; 235 if (nest_host_k != NULL) { 236 return nest_host_k; 237 } 238 239 ResourceMark rm(THREAD); 240 241 // need to resolve and save our nest-host class. 242 if (_nest_host_index != 0) { // we have a real nest_host 243 // Before trying to resolve check if we're in a suitable context 244 if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { 245 log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", 246 this->external_name()); 247 return NULL; // sentinel to say "try again from a different context" 248 } 249 250 log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", 251 this->external_name(), 252 _constants->klass_name_at(_nest_host_index)->as_C_string()); 253 254 Klass* k = _constants->klass_at(_nest_host_index, THREAD); 255 if (HAS_PENDING_EXCEPTION) { 256 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 257 return NULL; // propagate VMEs 258 } 259 stringStream ss; 260 char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string(); 261 ss.print("Nest host resolution of %s with host %s failed: ", 262 this->external_name(), target_host_class); 263 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 264 _nest_host_res_error = ss.as_string(true /* on C-heap */); 265 // ensure we see _nest_host_res_error is set if _nest_host is non-NULL 266 OrderAccess::storestore(); 267 CLEAR_PENDING_EXCEPTION; 268 269 log_trace(class, nestmates)("%s", _nest_host_res_error); 270 } else { 271 // A valid nest-host is an instance class in the current package that lists this 272 // class as a nest member. If any of these conditions are not met the class is 273 // its own nest-host. 274 const char* error = NULL; 275 276 // JVMS 5.4.4 indicates package check comes first 277 if (is_same_class_package(k)) { 278 // Now check actual membership. We can't be a member if our "host" is 279 // not an instance class. 280 if (k->is_instance_klass()) { 281 nest_host_k = InstanceKlass::cast(k); 282 bool is_member = nest_host_k->has_nest_member(this, THREAD); 283 // exception is rare, perhaps impossible 284 if (!HAS_PENDING_EXCEPTION) { 285 if (is_member) { 286 _nest_host = nest_host_k; // save resolved nest-host value 287 288 log_trace(class, nestmates)("Resolved nest-host of %s to %s", 289 this->external_name(), k->external_name()); 290 return nest_host_k; 291 } else { 292 error = "current type is not listed as a nest member"; 293 } 294 } else { 295 if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { 296 return NULL; // propagate VMEs 297 } 298 stringStream ss; 299 ss.print("exception on member check: "); 300 java_lang_Throwable::print(PENDING_EXCEPTION, &ss); 301 error = ss.as_string(); 302 } 303 } else { 304 error = "host is not an instance class"; 305 } 306 } else { 307 error = "types are in different packages"; 308 } 309 310 // something went wrong, so record what and log it 311 { 312 stringStream ss; 313 ss.print("Type %s (loader: %s) is not a nest member of type %s (loader: %s): %s", 314 this->external_name(), 315 this->class_loader_data()->loader_name_and_id(), 316 k->external_name(), 317 k->class_loader_data()->loader_name_and_id(), 318 error); 319 _nest_host_res_error = ss.as_string(true /* on C-heap */); 320 // ensure we see _nest_host_res_error is set if _nest_host is non-NULL 321 OrderAccess::storestore(); 322 323 log_trace(class, nestmates)("%s", _nest_host_res_error); 324 } 325 } 326 } else { 327 log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", 328 this->external_name()); 329 } 330 331 // Either not in an explicit nest, or else an error occurred, so 332 // the nest-host is set to `this`. Any thread that sees this assignment 333 // will also see any setting of _nest_host_res_error, if applicable. 334 return (_nest_host = this); 335 } 336 337 // Dynamic nest member support: set this class's nest host to the given class. 338 // This occurs as part of the class definition, as soon as the instanceKlass 339 // has been created and doesn't require further resolution. The code: 340 // lookup().defineHiddenClass(bytes_for_X, NESTMATE); 341 // results in: 342 // class_of_X.set_nest_host(lookup().lookupClass().getNestHost()) 343 // If it has an explicit _nest_host_index or _nest_members, these will be ignored. 344 // We also know the "host" is a valid nest-host in the same package so we can 345 // assert some of those facts. 346 void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) { 347 assert(is_hidden(), "must be a hidden class"); 348 assert(host != NULL, "NULL nest host specified"); 349 assert(_nest_host == NULL, "current class has resolved nest-host"); 378 // Any exceptions (i.e. VMEs) are propagated. 379 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { 380 381 assert(this != k, "this should be handled by higher-level code"); 382 383 // Per JVMS 5.4.4 we first resolve and validate the current class, then 384 // the target class k. 385 386 InstanceKlass* cur_host = nest_host(CHECK_false); 387 if (cur_host == NULL) { 388 return false; 389 } 390 391 Klass* k_nest_host = k->nest_host(CHECK_false); 392 if (k_nest_host == NULL) { 393 return false; 394 } 395 396 bool access = (cur_host == k_nest_host); 397 398 ResourceMark rm(THREAD); 399 log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", 400 this->external_name(), 401 access ? "" : "NOT ", 402 k->external_name()); 403 return access; 404 } 405 406 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { 407 bool is_hidden_or_anonymous = parser.is_hidden() || parser.is_unsafe_anonymous(); 408 const int size = InstanceKlass::size(parser.vtable_size(), 409 parser.itable_size(), 410 nonstatic_oop_map_size(parser.total_oop_map_count()), 411 parser.is_interface(), 412 is_hidden_or_anonymous, 413 should_store_fingerprint(is_hidden_or_anonymous)); 414 415 const Symbol* const class_name = parser.class_name(); 416 assert(class_name != NULL, "invariant"); 417 ClassLoaderData* loader_data = parser.loader_data(); 418 assert(loader_data != NULL, "invariant"); 419 420 InstanceKlass* ik; 421 422 // Allocation |