4331 4332 4333 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) { 4334 if (directBufferSupportInitializeFailed) { 4335 return false; 4336 } 4337 4338 if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) { 4339 if (!lookupDirectBufferClasses(env)) { 4340 directBufferSupportInitializeFailed = 1; 4341 return false; 4342 } 4343 4344 // Make global references for these 4345 bufferClass = (jclass) env->NewGlobalRef(bufferClass); 4346 directBufferClass = (jclass) env->NewGlobalRef(directBufferClass); 4347 directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass); 4348 4349 // Get needed field and method IDs 4350 directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V"); 4351 directBufferAddressField = env->GetFieldID(bufferClass, "address", "J"); 4352 bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I"); 4353 4354 if ((directByteBufferConstructor == NULL) || 4355 (directBufferAddressField == NULL) || 4356 (bufferCapacityField == NULL)) { 4357 directBufferSupportInitializeFailed = 1; 4358 return false; 4359 } 4360 4361 directBufferSupportInitializeEnded = 1; 4362 } else { 4363 while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) { 4364 // Set state as yield_all can call os:sleep. On Solaris, yield_all calls 4365 // os::sleep which requires the VM state transition. On other platforms, it 4366 // is not necessary. The following call to change the VM state is purposely 4367 // put inside the loop to avoid potential deadlock when multiple threads 4368 // try to call this method. See 6791815 for more details. 4369 ThreadInVMfromNative tivn(thread); 4370 os::yield_all(); 4371 } 4372 } | 4331 4332 4333 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) { 4334 if (directBufferSupportInitializeFailed) { 4335 return false; 4336 } 4337 4338 if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) { 4339 if (!lookupDirectBufferClasses(env)) { 4340 directBufferSupportInitializeFailed = 1; 4341 return false; 4342 } 4343 4344 // Make global references for these 4345 bufferClass = (jclass) env->NewGlobalRef(bufferClass); 4346 directBufferClass = (jclass) env->NewGlobalRef(directBufferClass); 4347 directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass); 4348 4349 // Get needed field and method IDs 4350 directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V"); 4351 if (env->ExceptionCheck()) { 4352 env->ExceptionClear(); 4353 directBufferSupportInitializeFailed = 1; 4354 return false; 4355 } 4356 directBufferAddressField = env->GetFieldID(bufferClass, "address", "J"); 4357 if (env->ExceptionCheck()) { 4358 env->ExceptionClear(); 4359 directBufferSupportInitializeFailed = 1; 4360 return false; 4361 } 4362 bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I"); 4363 if (env->ExceptionCheck()) { 4364 env->ExceptionClear(); 4365 directBufferSupportInitializeFailed = 1; 4366 return false; 4367 } 4368 4369 if ((directByteBufferConstructor == NULL) || 4370 (directBufferAddressField == NULL) || 4371 (bufferCapacityField == NULL)) { 4372 directBufferSupportInitializeFailed = 1; 4373 return false; 4374 } 4375 4376 directBufferSupportInitializeEnded = 1; 4377 } else { 4378 while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) { 4379 // Set state as yield_all can call os:sleep. On Solaris, yield_all calls 4380 // os::sleep which requires the VM state transition. On other platforms, it 4381 // is not necessary. The following call to change the VM state is purposely 4382 // put inside the loop to avoid potential deadlock when multiple threads 4383 // try to call this method. See 6791815 for more details. 4384 ThreadInVMfromNative tivn(thread); 4385 os::yield_all(); 4386 } 4387 } |