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