< prev index next >

src/os/aix/vm/os_aix.cpp

Print this page
rev 9211 : 8140645: Recent Developments for AIX
Summary: Port recent developments from SAP for AIX to the OpenJDK


  23  *
  24  */
  25 
  26 // According to the AIX OS doc #pragma alloca must be used
  27 // with C++ compiler before referencing the function alloca()
  28 #pragma alloca
  29 
  30 // no precompiled headers
  31 #include "classfile/classLoader.hpp"
  32 #include "classfile/systemDictionary.hpp"
  33 #include "classfile/vmSymbols.hpp"
  34 #include "code/icBuffer.hpp"
  35 #include "code/vtableStubs.hpp"
  36 #include "compiler/compileBroker.hpp"
  37 #include "interpreter/interpreter.hpp"
  38 #include "jvm_aix.h"
  39 #include "libperfstat_aix.hpp"
  40 #include "loadlib_aix.hpp"
  41 #include "memory/allocation.inline.hpp"
  42 #include "memory/filemap.hpp"

  43 #include "mutex_aix.inline.hpp"
  44 #include "oops/oop.inline.hpp"
  45 #include "os_aix.inline.hpp"
  46 #include "os_share_aix.hpp"
  47 #include "porting_aix.hpp"
  48 #include "prims/jniFastGetField.hpp"
  49 #include "prims/jvm.h"
  50 #include "prims/jvm_misc.hpp"
  51 #include "runtime/arguments.hpp"
  52 #include "runtime/atomic.inline.hpp"
  53 #include "runtime/extendedPC.hpp"
  54 #include "runtime/globals.hpp"
  55 #include "runtime/interfaceSupport.hpp"
  56 #include "runtime/java.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/mutexLocker.hpp"
  59 #include "runtime/objectMonitor.hpp"
  60 #include "runtime/orderAccess.inline.hpp"
  61 #include "runtime/os.hpp"
  62 #include "runtime/osThread.hpp"


 158 #define PV_8 0x300000          /* Power PC 8 */
 159 #define PV_8_Compat 0x308000   /* Power PC 8 */
 160 #endif
 161 
 162 #define trcVerbose(fmt, ...) { /* PPC port */  \
 163   if (Verbose) { \
 164     fprintf(stderr, fmt, ##__VA_ARGS__); \
 165     fputc('\n', stderr); fflush(stderr); \
 166   } \
 167 }
 168 #define trc(fmt, ...)        /* PPC port */
 169 
 170 #define ERRBYE(s) { \
 171     trcVerbose(s); \
 172     return -1; \
 173 }
 174 
 175 // Query dimensions of the stack of the calling thread.
 176 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
 177 
 178 // function to check a given stack pointer against given stack limits
 179 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
 180   if (((uintptr_t)sp) & 0x7) {
 181     return false;
 182   }
 183   if (sp > stack_base) {
 184     return false;
 185   }
 186   if (sp < (stackptr_t) ((address)stack_base - stack_size)) {
 187     return false;
 188   }
 189   return true;
 190 }
 191 
 192 // returns true if function is a valid codepointer
 193 inline bool is_valid_codepointer(codeptr_t p) {
 194   if (!p) {
 195     return false;
 196   }
 197   if (((uintptr_t)p) & 0x3) {
 198     return false;
 199   }
 200   if (LoadedLibraries::find_for_text_address((address)p) == NULL) {
 201     return false;
 202   }
 203   return true;
 204 }
 205 
 206 // Macro to check a given stack pointer against given stack limits and to die if test fails.
 207 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \
 208     guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \
 209 }
 210 
 211 // Macro to check the current stack pointer against given stacklimits.
 212 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \
 213   address sp; \
 214   sp = os::current_stack_pointer(); \
 215   CHECK_STACK_PTR(sp, stack_base, stack_size); \
 216 }
 217 
 218 ////////////////////////////////////////////////////////////////////////////////
 219 // global variables (for a description see os_aix.hpp)
 220 


1370     for (int i = 0; i < n; i++) {
1371       if (pelements[i] != NULL) {
1372         FREE_C_HEAP_ARRAY(char, pelements[i]);
1373       }
1374     }
1375     if (pelements != NULL) {
1376       FREE_C_HEAP_ARRAY(char*, pelements);
1377     }
1378   } else {
1379     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
1380     retval = true;
1381   }
1382   return retval;
1383 }
1384 
1385 // Check if addr is inside libjvm.so.
1386 bool os::address_is_in_vm(address addr) {
1387 
1388   // Input could be a real pc or a function pointer literal. The latter
1389   // would be a function descriptor residing in the data segment of a module.
1390 
1391   const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
1392   if (lib) {
1393     if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
1394       return true;
1395     } else {
1396       return false;
1397     }
1398   } else {
1399     lib = LoadedLibraries::find_for_data_address(addr);
1400     if (lib) {
1401       if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
1402         return true;
1403       } else {
1404         return false;
1405       }
1406     } else {
1407       return false;
1408     }
1409   }
1410 }
1411 
1412 // Resolve an AIX function descriptor literal to a code pointer.
1413 // If the input is a valid code pointer to a text segment of a loaded module,
1414 //   it is returned unchanged.
1415 // If the input is a valid AIX function descriptor, it is resolved to the
1416 //   code entry point.
1417 // If the input is neither a valid function descriptor nor a valid code pointer,
1418 //   NULL is returned.
1419 static address resolve_function_descriptor_to_code_pointer(address p) {
1420 
1421   const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(p);
1422   if (lib) {
1423     // its a real code pointer
1424     return p;
1425   } else {
1426     lib = LoadedLibraries::find_for_data_address(p);
1427     if (lib) {
1428       // pointer to data segment, potential function descriptor
1429       address code_entry = (address)(((FunctionDescriptor*)p)->entry());
1430       if (LoadedLibraries::find_for_text_address(code_entry)) {
1431         // Its a function descriptor
1432         return code_entry;
1433       }
1434     }
1435   }
1436   return NULL;
1437 }
1438 
1439 bool os::dll_address_to_function_name(address addr, char *buf,
1440                                       int buflen, int *offset,
1441                                       bool demangle) {
1442   if (offset) {
1443     *offset = -1;
1444   }
1445   // Buf is not optional, but offset is optional.
1446   assert(buf != NULL, "sanity check");
1447   buf[0] = '\0';
1448 
1449   // Resolve function ptr literals first.
1450   addr = resolve_function_descriptor_to_code_pointer(addr);
1451   if (!addr) {
1452     return false;
1453   }
1454 
1455   // Go through Decoder::decode to call getFuncName which reads the name from the traceback table.
1456   return Decoder::decode(addr, buf, buflen, offset, demangle);
1457 }
1458 
1459 static int getModuleName(codeptr_t pc,                    // [in] program counter
1460                          char* p_name, size_t namelen,    // [out] optional: function name
1461                          char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
1462                          ) {
1463 
1464   // initialize output parameters
1465   if (p_name && namelen > 0) {
1466     *p_name = '\0';
1467   }
1468   if (p_errmsg && errmsglen > 0) {
1469     *p_errmsg = '\0';
1470   }
1471 
1472   const LoadedLibraryModule* const lib = LoadedLibraries::find_for_text_address((address)pc);
1473   if (lib) {
1474     if (p_name && namelen > 0) {
1475       sprintf(p_name, "%.*s", namelen, lib->get_shortname());



1476     }
1477     return 0;
1478   }
1479 
1480   trcVerbose("pc outside any module");
1481 
1482   return -1;
1483 }
1484 
1485 bool os::dll_address_to_library_name(address addr, char* buf,
1486                                      int buflen, int* offset) {
1487   if (offset) {
1488     *offset = -1;
1489   }
1490   // Buf is not optional, but offset is optional.
1491   assert(buf != NULL, "sanity check");
1492   buf[0] = '\0';
1493 
1494   // Resolve function ptr literals first.
1495   addr = resolve_function_descriptor_to_code_pointer(addr);
1496   if (!addr) {
1497     return false;
1498   }
1499 
1500   if (::getModuleName((codeptr_t) addr, buf, buflen, 0, 0) == 0) {
1501     return true;


3770   return fetcher.result();
3771 }
3772 
3773 ////////////////////////////////////////////////////////////////////////////////
3774 // debug support
3775 
3776 static address same_page(address x, address y) {
3777   intptr_t page_bits = -os::vm_page_size();
3778   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
3779     return x;
3780   else if (x > y)
3781     return (address)(intptr_t(y) | ~page_bits) + 1;
3782   else
3783     return (address)(intptr_t(y) & page_bits);
3784 }
3785 
3786 bool os::find(address addr, outputStream* st) {
3787 
3788   st->print(PTR_FORMAT ": ", addr);
3789 
3790   const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
3791   if (lib) {
3792     lib->print(st);
3793     return true;
3794   } else {
3795     lib = LoadedLibraries::find_for_data_address(addr);
3796     if (lib) {
3797       lib->print(st);
3798       return true;
3799     } else {
3800       st->print_cr("(outside any module)");
3801     }
3802   }
3803 
3804   return false;
3805 }
3806 
3807 ////////////////////////////////////////////////////////////////////////////////
3808 // misc
3809 
3810 // This does not do anything on Aix. This is basically a hook for being
3811 // able to use structured exception handling (thread-local exception filters)
3812 // on, e.g., Win32.
3813 void
3814 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
3815                          JavaCallArguments* args, Thread* thread) {
3816   f(value, method, args, thread);
3817 }
3818 
3819 void os::print_statistics() {
3820 }
3821 




  23  *
  24  */
  25 
  26 // According to the AIX OS doc #pragma alloca must be used
  27 // with C++ compiler before referencing the function alloca()
  28 #pragma alloca
  29 
  30 // no precompiled headers
  31 #include "classfile/classLoader.hpp"
  32 #include "classfile/systemDictionary.hpp"
  33 #include "classfile/vmSymbols.hpp"
  34 #include "code/icBuffer.hpp"
  35 #include "code/vtableStubs.hpp"
  36 #include "compiler/compileBroker.hpp"
  37 #include "interpreter/interpreter.hpp"
  38 #include "jvm_aix.h"
  39 #include "libperfstat_aix.hpp"
  40 #include "loadlib_aix.hpp"
  41 #include "memory/allocation.inline.hpp"
  42 #include "memory/filemap.hpp"
  43 #include "misc_aix.hpp"
  44 #include "mutex_aix.inline.hpp"
  45 #include "oops/oop.inline.hpp"
  46 #include "os_aix.inline.hpp"
  47 #include "os_share_aix.hpp"
  48 #include "porting_aix.hpp"
  49 #include "prims/jniFastGetField.hpp"
  50 #include "prims/jvm.h"
  51 #include "prims/jvm_misc.hpp"
  52 #include "runtime/arguments.hpp"
  53 #include "runtime/atomic.inline.hpp"
  54 #include "runtime/extendedPC.hpp"
  55 #include "runtime/globals.hpp"
  56 #include "runtime/interfaceSupport.hpp"
  57 #include "runtime/java.hpp"
  58 #include "runtime/javaCalls.hpp"
  59 #include "runtime/mutexLocker.hpp"
  60 #include "runtime/objectMonitor.hpp"
  61 #include "runtime/orderAccess.inline.hpp"
  62 #include "runtime/os.hpp"
  63 #include "runtime/osThread.hpp"


 159 #define PV_8 0x300000          /* Power PC 8 */
 160 #define PV_8_Compat 0x308000   /* Power PC 8 */
 161 #endif
 162 
 163 #define trcVerbose(fmt, ...) { /* PPC port */  \
 164   if (Verbose) { \
 165     fprintf(stderr, fmt, ##__VA_ARGS__); \
 166     fputc('\n', stderr); fflush(stderr); \
 167   } \
 168 }
 169 #define trc(fmt, ...)        /* PPC port */
 170 
 171 #define ERRBYE(s) { \
 172     trcVerbose(s); \
 173     return -1; \
 174 }
 175 
 176 // Query dimensions of the stack of the calling thread.
 177 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
 178 
 179 // Function to check a given stack pointer against given stack limits
 180 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
 181   if (((uintptr_t)sp) & 0x7) {
 182     return false;
 183   }
 184   if (sp > stack_base) {
 185     return false;
 186   }
 187   if (sp < (stackptr_t) ((address)stack_base - stack_size)) {
 188     return false;
 189   }
 190   return true;
 191 }
 192 
 193 // Returns true if function is a valid codepointer
 194 inline bool is_valid_codepointer(codeptr_t p) {
 195   if (!p) {
 196     return false;
 197   }
 198   if (((uintptr_t)p) & 0x3) {
 199     return false;
 200   }
 201   if (!LoadedLibraries::find_for_text_address(p, NULL)) {
 202     return false;
 203   }
 204   return true;
 205 }
 206 
 207 // Macro to check a given stack pointer against given stack limits and to die if test fails.
 208 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \
 209     guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \
 210 }
 211 
 212 // Macro to check the current stack pointer against given stacklimits.
 213 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \
 214   address sp; \
 215   sp = os::current_stack_pointer(); \
 216   CHECK_STACK_PTR(sp, stack_base, stack_size); \
 217 }
 218 
 219 ////////////////////////////////////////////////////////////////////////////////
 220 // global variables (for a description see os_aix.hpp)
 221 


1371     for (int i = 0; i < n; i++) {
1372       if (pelements[i] != NULL) {
1373         FREE_C_HEAP_ARRAY(char, pelements[i]);
1374       }
1375     }
1376     if (pelements != NULL) {
1377       FREE_C_HEAP_ARRAY(char*, pelements);
1378     }
1379   } else {
1380     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
1381     retval = true;
1382   }
1383   return retval;
1384 }
1385 
1386 // Check if addr is inside libjvm.so.
1387 bool os::address_is_in_vm(address addr) {
1388 
1389   // Input could be a real pc or a function pointer literal. The latter
1390   // would be a function descriptor residing in the data segment of a module.
1391   loaded_module_t lm;
1392   if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL) {
1393     return lm.is_in_vm;
1394   } else if (LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
1395     return lm.is_in_vm;











1396   } else {
1397     return false;
1398   }
1399 
1400 }
1401 
1402 // Resolve an AIX function descriptor literal to a code pointer.
1403 // If the input is a valid code pointer to a text segment of a loaded module,
1404 //   it is returned unchanged.
1405 // If the input is a valid AIX function descriptor, it is resolved to the
1406 //   code entry point.
1407 // If the input is neither a valid function descriptor nor a valid code pointer,
1408 //   NULL is returned.
1409 static address resolve_function_descriptor_to_code_pointer(address p) {
1410 
1411   if (LoadedLibraries::find_for_text_address(p, NULL) != NULL) {

1412     // its a real code pointer
1413     return p;
1414   } else if (LoadedLibraries::find_for_data_address(p, NULL) != NULL) {


1415     // pointer to data segment, potential function descriptor
1416     address code_entry = (address)(((FunctionDescriptor*)p)->entry());
1417     if (LoadedLibraries::find_for_text_address(code_entry, NULL) != NULL) {
1418       // Its a function descriptor
1419       return code_entry;
1420     }
1421   }
1422 
1423   return NULL;
1424 }
1425 
1426 bool os::dll_address_to_function_name(address addr, char *buf,
1427                                       int buflen, int *offset,
1428                                       bool demangle) {
1429   if (offset) {
1430     *offset = -1;
1431   }
1432   // Buf is not optional, but offset is optional.
1433   assert(buf != NULL, "sanity check");
1434   buf[0] = '\0';
1435 
1436   // Resolve function ptr literals first.
1437   addr = resolve_function_descriptor_to_code_pointer(addr);
1438   if (!addr) {
1439     return false;
1440   }
1441 
1442   // Go through Decoder::decode to call getFuncName which reads the name from the traceback table.
1443   return Decoder::decode(addr, buf, buflen, offset, demangle);
1444 }
1445 
1446 static int getModuleName(codeptr_t pc,                    // [in] program counter
1447                          char* p_name, size_t namelen,    // [out] optional: function name
1448                          char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
1449                          ) {
1450 

1451   if (p_name && namelen > 0) {
1452     *p_name = '\0';
1453   }
1454   if (p_errmsg && errmsglen > 0) {
1455     *p_errmsg = '\0';
1456   }
1457 


1458   if (p_name && namelen > 0) {
1459     loaded_module_t lm;
1460     if (LoadedLibraries::find_for_text_address(pc, &lm) != NULL) {
1461       strncpy(p_name, lm.shortname, namelen);
1462       p_name[namelen - 1] = '\0';
1463     }
1464     return 0;
1465   }
1466 


1467   return -1;
1468 }
1469 
1470 bool os::dll_address_to_library_name(address addr, char* buf,
1471                                      int buflen, int* offset) {
1472   if (offset) {
1473     *offset = -1;
1474   }
1475   // Buf is not optional, but offset is optional.
1476   assert(buf != NULL, "sanity check");
1477   buf[0] = '\0';
1478 
1479   // Resolve function ptr literals first.
1480   addr = resolve_function_descriptor_to_code_pointer(addr);
1481   if (!addr) {
1482     return false;
1483   }
1484 
1485   if (::getModuleName((codeptr_t) addr, buf, buflen, 0, 0) == 0) {
1486     return true;


3755   return fetcher.result();
3756 }
3757 
3758 ////////////////////////////////////////////////////////////////////////////////
3759 // debug support
3760 
3761 static address same_page(address x, address y) {
3762   intptr_t page_bits = -os::vm_page_size();
3763   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
3764     return x;
3765   else if (x > y)
3766     return (address)(intptr_t(y) | ~page_bits) + 1;
3767   else
3768     return (address)(intptr_t(y) & page_bits);
3769 }
3770 
3771 bool os::find(address addr, outputStream* st) {
3772 
3773   st->print(PTR_FORMAT ": ", addr);
3774 
3775   loaded_module_t lm;
3776   if ( LoadedLibraries::find_for_text_address(addr, &lm) != NULL ||
3777        LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
3778     st->print("%s", lm.path);




3779       return true;



3780   }
3781 
3782   return false;
3783 }
3784 
3785 ////////////////////////////////////////////////////////////////////////////////
3786 // misc
3787 
3788 // This does not do anything on Aix. This is basically a hook for being
3789 // able to use structured exception handling (thread-local exception filters)
3790 // on, e.g., Win32.
3791 void
3792 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
3793                          JavaCallArguments* args, Thread* thread) {
3794   f(value, method, args, thread);
3795 }
3796 
3797 void os::print_statistics() {
3798 }
3799 


< prev index next >