128 #define ERROR_MP_OS_TOO_OLD 100 |
128 #define ERROR_MP_OS_TOO_OLD 100 |
129 #define ERROR_MP_EXTSHM_ACTIVE 101 |
129 #define ERROR_MP_EXTSHM_ACTIVE 101 |
130 #define ERROR_MP_VMGETINFO_FAILED 102 |
130 #define ERROR_MP_VMGETINFO_FAILED 102 |
131 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 |
131 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 |
132 |
132 |
133 // Query dimensions of the stack of the calling thread. |
|
134 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); |
|
135 static address resolve_function_descriptor_to_code_pointer(address p); |
133 static address resolve_function_descriptor_to_code_pointer(address p); |
136 |
134 |
137 static void vmembk_print_on(outputStream* os); |
135 static void vmembk_print_on(outputStream* os); |
138 |
136 |
139 //////////////////////////////////////////////////////////////////////////////// |
137 //////////////////////////////////////////////////////////////////////////////// |
762 static void *thread_native_entry(Thread *thread) { |
760 static void *thread_native_entry(Thread *thread) { |
763 |
761 |
764 // find out my own stack dimensions |
762 // find out my own stack dimensions |
765 { |
763 { |
766 // actually, this should do exactly the same as thread->record_stack_base_and_size... |
764 // actually, this should do exactly the same as thread->record_stack_base_and_size... |
767 address base = 0; |
765 thread->set_stack_base(os::current_stack_base()); |
768 size_t size = 0; |
766 thread->set_stack_size(os::current_stack_size()); |
769 query_stack_dimensions(&base, &size); |
|
770 thread->set_stack_base(base); |
|
771 thread->set_stack_size(size); |
|
772 } |
767 } |
773 |
768 |
774 const pthread_t pthread_id = ::pthread_self(); |
769 const pthread_t pthread_id = ::pthread_self(); |
775 const tid_t kernel_thread_id = ::thread_self(); |
770 const tid_t kernel_thread_id = ::thread_self(); |
776 |
771 |
4295 } |
4290 } |
4296 |
4291 |
4297 ///////////////////////////////////////////////////////////////////////////// |
4292 ///////////////////////////////////////////////////////////////////////////// |
4298 // thread stack |
4293 // thread stack |
4299 |
4294 |
4300 // Function to query the current stack size using pthread_getthrds_np. |
|
4301 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) { |
|
4302 |
|
4303 // Information about this api can be found (a) in the pthread.h header and |
|
4304 // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm |
|
4305 // |
|
4306 // The use of this API to find out the current stack is kind of undefined. |
|
4307 // But after a lot of tries and asking IBM about it, I concluded that it is safe |
|
4308 // enough for cases where I let the pthread library create its stacks. For cases |
|
4309 // where I create an own stack and pass this to pthread_create, it seems not to |
|
4310 // work (the returned stack size in that case is 0). |
|
4311 |
|
4312 pthread_t tid = pthread_self(); |
|
4313 struct __pthrdsinfo pinfo; |
|
4314 char dummy[1]; // Just needed to satisfy pthread_getthrds_np. |
|
4315 int dummy_size = sizeof(dummy); |
|
4316 |
|
4317 memset(&pinfo, 0, sizeof(pinfo)); |
|
4318 |
|
4319 const int rc = pthread_getthrds_np(&tid, PTHRDSINFO_QUERY_ALL, &pinfo, |
|
4320 sizeof(pinfo), dummy, &dummy_size); |
|
4321 |
|
4322 if (rc != 0) { |
|
4323 trcVerbose("pthread_getthrds_np failed (%d)", rc); |
|
4324 return false; |
|
4325 } |
|
4326 guarantee0(pinfo.__pi_stackend); |
|
4327 |
|
4328 // The following may happen when invoking pthread_getthrds_np on a pthread |
|
4329 // running on a user provided stack (when handing down a stack to pthread |
|
4330 // create, see pthread_attr_setstackaddr). |
|
4331 // Not sure what to do then. |
|
4332 |
|
4333 guarantee0(pinfo.__pi_stacksize); |
|
4334 |
|
4335 // Note: we get three values from pthread_getthrds_np: |
|
4336 // __pi_stackaddr, __pi_stacksize, __pi_stackend |
|
4337 // |
|
4338 // high addr --------------------- |
|
4339 // |
|
4340 // | pthread internal data, like ~2K |
|
4341 // | |
|
4342 // | --------------------- __pi_stackend (usually not page aligned, (xxxxF890)) |
|
4343 // | |
|
4344 // | |
|
4345 // | |
|
4346 // | |
|
4347 // | |
|
4348 // | |
|
4349 // | --------------------- (__pi_stackend - __pi_stacksize) |
|
4350 // | |
|
4351 // | padding to align the following AIX guard pages, if enabled. |
|
4352 // | |
|
4353 // V --------------------- __pi_stackaddr |
|
4354 // |
|
4355 // low addr AIX guard pages, if enabled (AIXTHREAD_GUARDPAGES > 0) |
|
4356 // |
|
4357 |
|
4358 address stack_base = (address)(pinfo.__pi_stackend); |
|
4359 address stack_low_addr = (address)align_ptr_up(pinfo.__pi_stackaddr, |
|
4360 os::vm_page_size()); |
|
4361 size_t stack_size = stack_base - stack_low_addr; |
|
4362 |
|
4363 if (p_stack_base) { |
|
4364 *p_stack_base = stack_base; |
|
4365 } |
|
4366 |
|
4367 if (p_stack_size) { |
|
4368 *p_stack_size = stack_size; |
|
4369 } |
|
4370 |
|
4371 return true; |
|
4372 } |
|
4373 |
|
4374 // Get the current stack base from the OS (actually, the pthread library). |
4295 // Get the current stack base from the OS (actually, the pthread library). |
|
4296 // Note: usually not page aligned. |
4375 address os::current_stack_base() { |
4297 address os::current_stack_base() { |
4376 address p; |
4298 AixMisc::stackbounds_t bounds; |
4377 query_stack_dimensions(&p, 0); |
4299 bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds); |
4378 return p; |
4300 guarantee(rc, "Unable to retrieve stack bounds."); |
|
4301 return bounds.base; |
4379 } |
4302 } |
4380 |
4303 |
4381 // Get the current stack size from the OS (actually, the pthread library). |
4304 // Get the current stack size from the OS (actually, the pthread library). |
|
4305 // Returned size is such that (base - size) is always aligned to page size. |
4382 size_t os::current_stack_size() { |
4306 size_t os::current_stack_size() { |
4383 size_t s; |
4307 AixMisc::stackbounds_t bounds; |
4384 query_stack_dimensions(0, &s); |
4308 bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds); |
|
4309 guarantee(rc, "Unable to retrieve stack bounds."); |
|
4310 // Align the returned stack size such that the stack low address |
|
4311 // is aligned to page size (Note: base is usually not and we do not care). |
|
4312 // We need to do this because caller code will assume stack low address is |
|
4313 // page aligned and will place guard pages without checking. |
|
4314 address low = bounds.base - bounds.size; |
|
4315 address low_aligned = (address)align_ptr_up(low, os::vm_page_size()); |
|
4316 size_t s = bounds.base - low_aligned; |
4385 return s; |
4317 return s; |
4386 } |
4318 } |
4387 |
4319 |
4388 extern char** environ; |
4320 extern char** environ; |
4389 |
4321 |