Path: blob/master/src/hotspot/os/aix/os_aix.cpp
64441 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2012, 2020 SAP SE. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425// According to the AIX OS doc #pragma alloca must be used26// with C++ compiler before referencing the function alloca()27#pragma alloca2829// no precompiled headers30#include "jvm.h"31#include "classfile/vmSymbols.hpp"32#include "code/icBuffer.hpp"33#include "code/vtableStubs.hpp"34#include "compiler/compileBroker.hpp"35#include "interpreter/interpreter.hpp"36#include "jvmtifiles/jvmti.h"37#include "logging/log.hpp"38#include "logging/logStream.hpp"39#include "libo4.hpp"40#include "libperfstat_aix.hpp"41#include "libodm_aix.hpp"42#include "loadlib_aix.hpp"43#include "memory/allocation.inline.hpp"44#include "misc_aix.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_misc.hpp"51#include "runtime/arguments.hpp"52#include "runtime/atomic.hpp"53#include "runtime/globals.hpp"54#include "runtime/globals_extension.hpp"55#include "runtime/interfaceSupport.inline.hpp"56#include "runtime/java.hpp"57#include "runtime/javaCalls.hpp"58#include "runtime/mutexLocker.hpp"59#include "runtime/objectMonitor.hpp"60#include "runtime/os.hpp"61#include "runtime/osThread.hpp"62#include "runtime/perfMemory.hpp"63#include "runtime/safefetch.inline.hpp"64#include "runtime/sharedRuntime.hpp"65#include "runtime/statSampler.hpp"66#include "runtime/thread.inline.hpp"67#include "runtime/threadCritical.hpp"68#include "runtime/timer.hpp"69#include "runtime/vm_version.hpp"70#include "services/attachListener.hpp"71#include "services/runtimeService.hpp"72#include "signals_posix.hpp"73#include "utilities/align.hpp"74#include "utilities/decoder.hpp"75#include "utilities/defaultStream.hpp"76#include "utilities/events.hpp"77#include "utilities/growableArray.hpp"78#include "utilities/vmError.hpp"7980// put OS-includes here (sorted alphabetically)81#include <errno.h>82#include <fcntl.h>83#include <inttypes.h>84#include <poll.h>85#include <procinfo.h>86#include <pthread.h>87#include <pwd.h>88#include <semaphore.h>89#include <signal.h>90#include <stdint.h>91#include <stdio.h>92#include <string.h>93#include <unistd.h>94#include <sys/ioctl.h>95#include <sys/ipc.h>96#include <sys/mman.h>97#include <sys/resource.h>98#include <sys/select.h>99#include <sys/shm.h>100#include <sys/socket.h>101#include <sys/stat.h>102#include <sys/sysinfo.h>103#include <sys/systemcfg.h>104#include <sys/time.h>105#include <sys/times.h>106#include <sys/types.h>107#include <sys/utsname.h>108#include <sys/vminfo.h>109110// Missing prototypes for various system APIs.111extern "C"112int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t);113114#if !defined(_AIXVERSION_610)115extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int);116extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int);117extern "C" int getargs(procsinfo*, int, char*, int);118#endif119120#define MAX_PATH (2 * K)121122// for timer info max values which include all bits123#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)124// for multipage initialization error analysis (in 'g_multipage_error')125#define ERROR_MP_OS_TOO_OLD 100126#define ERROR_MP_EXTSHM_ACTIVE 101127#define ERROR_MP_VMGETINFO_FAILED 102128#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103129130// excerpts from systemcfg.h that might be missing on older os levels131#ifndef PV_7132#define PV_7 0x200000 /* Power PC 7 */133#endif134#ifndef PV_7_Compat135#define PV_7_Compat 0x208000 /* Power PC 7 */136#endif137#ifndef PV_8138#define PV_8 0x300000 /* Power PC 8 */139#endif140#ifndef PV_8_Compat141#define PV_8_Compat 0x308000 /* Power PC 8 */142#endif143#ifndef PV_9144#define PV_9 0x400000 /* Power PC 9 */145#endif146#ifndef PV_9_Compat147#define PV_9_Compat 0x408000 /* Power PC 9 */148#endif149150151static address resolve_function_descriptor_to_code_pointer(address p);152153static void vmembk_print_on(outputStream* os);154155////////////////////////////////////////////////////////////////////////////////156// global variables (for a description see os_aix.hpp)157158julong os::Aix::_physical_memory = 0;159160pthread_t os::Aix::_main_thread = ((pthread_t)0);161int os::Aix::_page_size = -1;162163// -1 = uninitialized, 0 if AIX, 1 if OS/400 pase164int os::Aix::_on_pase = -1;165166// 0 = uninitialized, otherwise 32 bit number:167// 0xVVRRTTSS168// VV - major version169// RR - minor version170// TT - tech level, if known, 0 otherwise171// SS - service pack, if known, 0 otherwise172uint32_t os::Aix::_os_version = 0;173174// -1 = uninitialized, 0 - no, 1 - yes175int os::Aix::_xpg_sus_mode = -1;176177// -1 = uninitialized, 0 - no, 1 - yes178int os::Aix::_extshm = -1;179180////////////////////////////////////////////////////////////////////////////////181// local variables182183static volatile jlong max_real_time = 0;184static jlong initial_time_count = 0;185static int clock_tics_per_sec = 100;186187// Process break recorded at startup.188static address g_brk_at_startup = NULL;189190// This describes the state of multipage support of the underlying191// OS. Note that this is of no interest to the outsize world and192// therefore should not be defined in AIX class.193//194// AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The195// latter two (16M "large" resp. 16G "huge" pages) require special196// setup and are normally not available.197//198// AIX supports multiple page sizes per process, for:199// - Stack (of the primordial thread, so not relevant for us)200// - Data - data, bss, heap, for us also pthread stacks201// - Text - text code202// - shared memory203//204// Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...)205// and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...).206//207// For shared memory, page size can be set dynamically via208// shmctl(). Different shared memory regions can have different page209// sizes.210//211// More information can be found at AIBM info center:212// http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm213//214static struct {215size_t pagesize; // sysconf _SC_PAGESIZE (4K)216size_t datapsize; // default data page size (LDR_CNTRL DATAPSIZE)217size_t shmpsize; // default shared memory page size (LDR_CNTRL SHMPSIZE)218size_t pthr_stack_pagesize; // stack page size of pthread threads219size_t textpsize; // default text page size (LDR_CNTRL STACKPSIZE)220bool can_use_64K_pages; // True if we can alloc 64K pages dynamically with Sys V shm.221bool can_use_16M_pages; // True if we can alloc 16M pages dynamically with Sys V shm.222int error; // Error describing if something went wrong at multipage init.223} g_multipage_support = {224(size_t) -1,225(size_t) -1,226(size_t) -1,227(size_t) -1,228(size_t) -1,229false, false,2300231};232233// We must not accidentally allocate memory close to the BRK - even if234// that would work - because then we prevent the BRK segment from235// growing which may result in a malloc OOM even though there is236// enough memory. The problem only arises if we shmat() or mmap() at237// a specific wish address, e.g. to place the heap in a238// compressed-oops-friendly way.239static bool is_close_to_brk(address a) {240assert0(g_brk_at_startup != NULL);241if (a >= g_brk_at_startup &&242a < (g_brk_at_startup + MaxExpectedDataSegmentSize)) {243return true;244}245return false;246}247248julong os::available_memory() {249return Aix::available_memory();250}251252julong os::Aix::available_memory() {253// Avoid expensive API call here, as returned value will always be null.254if (os::Aix::on_pase()) {255return 0x0LL;256}257os::Aix::meminfo_t mi;258if (os::Aix::get_meminfo(&mi)) {259return mi.real_free;260} else {261return ULONG_MAX;262}263}264265julong os::physical_memory() {266return Aix::physical_memory();267}268269// Return true if user is running as root.270271bool os::have_special_privileges() {272static bool init = false;273static bool privileges = false;274if (!init) {275privileges = (getuid() != geteuid()) || (getgid() != getegid());276init = true;277}278return privileges;279}280281// Helper function, emulates disclaim64 using multiple 32bit disclaims282// because we cannot use disclaim64() on AS/400 and old AIX releases.283static bool my_disclaim64(char* addr, size_t size) {284285if (size == 0) {286return true;287}288289// Maximum size 32bit disclaim() accepts. (Theoretically 4GB, but I just do not trust that.)290const unsigned int maxDisclaimSize = 0x40000000;291292const unsigned int numFullDisclaimsNeeded = (size / maxDisclaimSize);293const unsigned int lastDisclaimSize = (size % maxDisclaimSize);294295char* p = addr;296297for (int i = 0; i < numFullDisclaimsNeeded; i ++) {298if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) {299trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno);300return false;301}302p += maxDisclaimSize;303}304305if (lastDisclaimSize > 0) {306if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) {307trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno);308return false;309}310}311312return true;313}314315// Cpu architecture string316#if defined(PPC32)317static char cpu_arch[] = "ppc";318#elif defined(PPC64)319static char cpu_arch[] = "ppc64";320#else321#error Add appropriate cpu_arch setting322#endif323324// Wrap the function "vmgetinfo" which is not available on older OS releases.325static int checked_vmgetinfo(void *out, int command, int arg) {326if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {327guarantee(false, "cannot call vmgetinfo on AS/400 older than V6R1");328}329return ::vmgetinfo(out, command, arg);330}331332// Given an address, returns the size of the page backing that address.333size_t os::Aix::query_pagesize(void* addr) {334335if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {336// AS/400 older than V6R1: no vmgetinfo here, default to 4K337return 4*K;338}339340vm_page_info pi;341pi.addr = (uint64_t)addr;342if (checked_vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) {343return pi.pagesize;344} else {345assert(false, "vmgetinfo failed to retrieve page size");346return 4*K;347}348}349350void os::Aix::initialize_system_info() {351352// Get the number of online(logical) cpus instead of configured.353os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN);354assert(_processor_count > 0, "_processor_count must be > 0");355356// Retrieve total physical storage.357os::Aix::meminfo_t mi;358if (!os::Aix::get_meminfo(&mi)) {359assert(false, "os::Aix::get_meminfo failed.");360}361_physical_memory = (julong) mi.real_total;362}363364// Helper function for tracing page sizes.365static const char* describe_pagesize(size_t pagesize) {366switch (pagesize) {367case 4*K : return "4K";368case 64*K: return "64K";369case 16*M: return "16M";370case 16*G: return "16G";371default:372assert(false, "surprise");373return "??";374}375}376377// Probe OS for multipage support.378// Will fill the global g_multipage_support structure.379// Must be called before calling os::large_page_init().380static void query_multipage_support() {381382guarantee(g_multipage_support.pagesize == -1,383"do not call twice");384385g_multipage_support.pagesize = ::sysconf(_SC_PAGESIZE);386387// This really would surprise me.388assert(g_multipage_support.pagesize == 4*K, "surprise!");389390// Query default data page size (default page size for C-Heap, pthread stacks and .bss).391// Default data page size is defined either by linker options (-bdatapsize)392// or by environment variable LDR_CNTRL (suboption DATAPSIZE). If none is given,393// default should be 4K.394{395void* p = ::malloc(16*M);396g_multipage_support.datapsize = os::Aix::query_pagesize(p);397::free(p);398}399400// Query default shm page size (LDR_CNTRL SHMPSIZE).401// Note that this is pure curiosity. We do not rely on default page size but set402// our own page size after allocated.403{404const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR);405guarantee(shmid != -1, "shmget failed");406void* p = ::shmat(shmid, NULL, 0);407::shmctl(shmid, IPC_RMID, NULL);408guarantee(p != (void*) -1, "shmat failed");409g_multipage_support.shmpsize = os::Aix::query_pagesize(p);410::shmdt(p);411}412413// Before querying the stack page size, make sure we are not running as primordial414// thread (because primordial thread's stack may have different page size than415// pthread thread stacks). Running a VM on the primordial thread won't work for a416// number of reasons so we may just as well guarantee it here.417guarantee0(!os::is_primordial_thread());418419// Query pthread stack page size. Should be the same as data page size because420// pthread stacks are allocated from C-Heap.421{422int dummy = 0;423g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy);424}425426// Query default text page size (LDR_CNTRL TEXTPSIZE).427{428address any_function =429resolve_function_descriptor_to_code_pointer((address)describe_pagesize);430g_multipage_support.textpsize = os::Aix::query_pagesize(any_function);431}432433// Now probe for support of 64K pages and 16M pages.434435// Before OS/400 V6R1, there is no support for pages other than 4K.436if (os::Aix::on_pase_V5R4_or_older()) {437trcVerbose("OS/400 < V6R1 - no large page support.");438g_multipage_support.error = ERROR_MP_OS_TOO_OLD;439goto query_multipage_support_end;440}441442// Now check which page sizes the OS claims it supports, and of those, which actually can be used.443{444const int MAX_PAGE_SIZES = 4;445psize_t sizes[MAX_PAGE_SIZES];446const int num_psizes = checked_vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES);447if (num_psizes == -1) {448trcVerbose("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)", errno);449trcVerbose("disabling multipage support.");450g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED;451goto query_multipage_support_end;452}453guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed.");454assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?");455trcVerbose("vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes);456for (int i = 0; i < num_psizes; i ++) {457trcVerbose(" %s ", describe_pagesize(sizes[i]));458}459460// Can we use 64K, 16M pages?461for (int i = 0; i < num_psizes; i ++) {462const size_t pagesize = sizes[i];463if (pagesize != 64*K && pagesize != 16*M) {464continue;465}466bool can_use = false;467trcVerbose("Probing support for %s pages...", describe_pagesize(pagesize));468const int shmid = ::shmget(IPC_PRIVATE, pagesize,469IPC_CREAT | S_IRUSR | S_IWUSR);470guarantee0(shmid != -1); // Should always work.471// Try to set pagesize.472struct shmid_ds shm_buf = { 0 };473shm_buf.shm_pagesize = pagesize;474if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {475const int en = errno;476::shmctl(shmid, IPC_RMID, NULL); // As early as possible!477trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%d", errno);478} else {479// Attach and double check pageisze.480void* p = ::shmat(shmid, NULL, 0);481::shmctl(shmid, IPC_RMID, NULL); // As early as possible!482guarantee0(p != (void*) -1); // Should always work.483const size_t real_pagesize = os::Aix::query_pagesize(p);484if (real_pagesize != pagesize) {485trcVerbose("real page size (" SIZE_FORMAT_HEX ") differs.", real_pagesize);486} else {487can_use = true;488}489::shmdt(p);490}491trcVerbose("Can use: %s", (can_use ? "yes" : "no"));492if (pagesize == 64*K) {493g_multipage_support.can_use_64K_pages = can_use;494} else if (pagesize == 16*M) {495g_multipage_support.can_use_16M_pages = can_use;496}497}498499} // end: check which pages can be used for shared memory500501query_multipage_support_end:502503trcVerbose("base page size (sysconf _SC_PAGESIZE): %s",504describe_pagesize(g_multipage_support.pagesize));505trcVerbose("Data page size (C-Heap, bss, etc): %s",506describe_pagesize(g_multipage_support.datapsize));507trcVerbose("Text page size: %s",508describe_pagesize(g_multipage_support.textpsize));509trcVerbose("Thread stack page size (pthread): %s",510describe_pagesize(g_multipage_support.pthr_stack_pagesize));511trcVerbose("Default shared memory page size: %s",512describe_pagesize(g_multipage_support.shmpsize));513trcVerbose("Can use 64K pages dynamically with shared memory: %s",514(g_multipage_support.can_use_64K_pages ? "yes" :"no"));515trcVerbose("Can use 16M pages dynamically with shared memory: %s",516(g_multipage_support.can_use_16M_pages ? "yes" :"no"));517trcVerbose("Multipage error details: %d",518g_multipage_support.error);519520// sanity checks521assert0(g_multipage_support.pagesize == 4*K);522assert0(g_multipage_support.datapsize == 4*K || g_multipage_support.datapsize == 64*K);523assert0(g_multipage_support.textpsize == 4*K || g_multipage_support.textpsize == 64*K);524assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize);525assert0(g_multipage_support.shmpsize == 4*K || g_multipage_support.shmpsize == 64*K);526527}528529void os::init_system_properties_values() {530531#ifndef OVERRIDE_LIBPATH532#define DEFAULT_LIBPATH "/lib:/usr/lib"533#else534#define DEFAULT_LIBPATH OVERRIDE_LIBPATH535#endif536#define EXTENSIONS_DIR "/lib/ext"537538// Buffer that fits several sprintfs.539// Note that the space for the trailing null is provided540// by the nulls included by the sizeof operator.541const size_t bufsize =542MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.543(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR)); // extensions dir544char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);545546// sysclasspath, java_home, dll_dir547{548char *pslash;549os::jvm_path(buf, bufsize);550551// Found the full path to libjvm.so.552// Now cut the path to <java_home>/jre if we can.553pslash = strrchr(buf, '/');554if (pslash != NULL) {555*pslash = '\0'; // Get rid of /libjvm.so.556}557pslash = strrchr(buf, '/');558if (pslash != NULL) {559*pslash = '\0'; // Get rid of /{client|server|hotspot}.560}561Arguments::set_dll_dir(buf);562563if (pslash != NULL) {564pslash = strrchr(buf, '/');565if (pslash != NULL) {566*pslash = '\0'; // Get rid of /lib.567}568}569Arguments::set_java_home(buf);570if (!set_boot_path('/', ':')) {571vm_exit_during_initialization("Failed setting boot class path.", NULL);572}573}574575// Where to look for native libraries.576577// On Aix we get the user setting of LIBPATH.578// Eventually, all the library path setting will be done here.579// Get the user setting of LIBPATH.580const char *v = ::getenv("LIBPATH");581const char *v_colon = ":";582if (v == NULL) { v = ""; v_colon = ""; }583584// Concatenate user and invariant part of ld_library_path.585// That's +1 for the colon and +1 for the trailing '\0'.586char *ld_library_path = NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);587sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon);588Arguments::set_library_path(ld_library_path);589FREE_C_HEAP_ARRAY(char, ld_library_path);590591// Extensions directories.592sprintf(buf, "%s" EXTENSIONS_DIR, Arguments::get_java_home());593Arguments::set_ext_dirs(buf);594595FREE_C_HEAP_ARRAY(char, buf);596597#undef DEFAULT_LIBPATH598#undef EXTENSIONS_DIR599}600601////////////////////////////////////////////////////////////////////////////////602// breakpoint support603604void os::breakpoint() {605BREAKPOINT;606}607608extern "C" void breakpoint() {609// use debugger to set breakpoint here610}611612// retrieve memory information.613// Returns false if something went wrong;614// content of pmi undefined in this case.615bool os::Aix::get_meminfo(meminfo_t* pmi) {616617assert(pmi, "get_meminfo: invalid parameter");618619memset(pmi, 0, sizeof(meminfo_t));620621if (os::Aix::on_pase()) {622// On PASE, use the libo4 porting library.623624unsigned long long virt_total = 0;625unsigned long long real_total = 0;626unsigned long long real_free = 0;627unsigned long long pgsp_total = 0;628unsigned long long pgsp_free = 0;629if (libo4::get_memory_info(&virt_total, &real_total, &real_free, &pgsp_total, &pgsp_free)) {630pmi->virt_total = virt_total;631pmi->real_total = real_total;632pmi->real_free = real_free;633pmi->pgsp_total = pgsp_total;634pmi->pgsp_free = pgsp_free;635return true;636}637return false;638639} else {640641// On AIX, I use the (dynamically loaded) perfstat library to retrieve memory statistics642// See:643// http://publib.boulder.ibm.com/infocenter/systems/index.jsp644// ?topic=/com.ibm.aix.basetechref/doc/basetrf1/perfstat_memtot.htm645// http://publib.boulder.ibm.com/infocenter/systems/index.jsp646// ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm647648perfstat_memory_total_t psmt;649memset (&psmt, '\0', sizeof(psmt));650const int rc = libperfstat::perfstat_memory_total(NULL, &psmt, sizeof(psmt), 1);651if (rc == -1) {652trcVerbose("perfstat_memory_total() failed (errno=%d)", errno);653assert(0, "perfstat_memory_total() failed");654return false;655}656657assert(rc == 1, "perfstat_memory_total() - weird return code");658659// excerpt from660// http://publib.boulder.ibm.com/infocenter/systems/index.jsp661// ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm662// The fields of perfstat_memory_total_t:663// u_longlong_t virt_total Total virtual memory (in 4 KB pages).664// u_longlong_t real_total Total real memory (in 4 KB pages).665// u_longlong_t real_free Free real memory (in 4 KB pages).666// u_longlong_t pgsp_total Total paging space (in 4 KB pages).667// u_longlong_t pgsp_free Free paging space (in 4 KB pages).668669pmi->virt_total = psmt.virt_total * 4096;670pmi->real_total = psmt.real_total * 4096;671pmi->real_free = psmt.real_free * 4096;672pmi->pgsp_total = psmt.pgsp_total * 4096;673pmi->pgsp_free = psmt.pgsp_free * 4096;674675return true;676677}678} // end os::Aix::get_meminfo679680//////////////////////////////////////////////////////////////////////////////681// create new thread682683// Thread start routine for all newly created threads684static void *thread_native_entry(Thread *thread) {685686thread->record_stack_base_and_size();687688const pthread_t pthread_id = ::pthread_self();689const tid_t kernel_thread_id = ::thread_self();690691LogTarget(Info, os, thread) lt;692if (lt.is_enabled()) {693address low_address = thread->stack_end();694address high_address = thread->stack_base();695lt.print("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT696", stack [" PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k using %uk pages)).",697os::current_thread_id(), (uintx) kernel_thread_id, low_address, high_address,698(high_address - low_address) / K, os::Aix::query_pagesize(low_address) / K);699}700701// Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()702// by the pthread library). In rare cases, this may not be the case, e.g. when third-party703// tools hook pthread_create(). In this case, we may run into problems establishing704// guard pages on those stacks, because the stacks may reside in memory which is not705// protectable (shmated).706if (thread->stack_base() > ::sbrk(0)) {707log_warning(os, thread)("Thread stack not in data segment.");708}709710// Try to randomize the cache line index of hot stack frames.711// This helps when threads of the same stack traces evict each other's712// cache lines. The threads can be either from the same JVM instance, or713// from different JVM instances. The benefit is especially true for714// processors with hyperthreading technology.715716static int counter = 0;717int pid = os::current_process_id();718alloca(((pid ^ counter++) & 7) * 128);719720thread->initialize_thread_current();721722OSThread* osthread = thread->osthread();723724// Thread_id is pthread id.725osthread->set_thread_id(pthread_id);726727// .. but keep kernel thread id too for diagnostics728osthread->set_kernel_thread_id(kernel_thread_id);729730// Initialize signal mask for this thread.731PosixSignals::hotspot_sigmask(thread);732733// Initialize floating point control register.734os::Aix::init_thread_fpu_state();735736assert(osthread->get_state() == RUNNABLE, "invalid os thread state");737738// Call one more level start routine.739thread->call_run();740741// Note: at this point the thread object may already have deleted itself.742// Prevent dereferencing it from here on out.743thread = NULL;744745log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",746os::current_thread_id(), (uintx) kernel_thread_id);747748return 0;749}750751bool os::create_thread(Thread* thread, ThreadType thr_type,752size_t req_stack_size) {753754assert(thread->osthread() == NULL, "caller responsible");755756// Allocate the OSThread object.757OSThread* osthread = new OSThread(NULL, NULL);758if (osthread == NULL) {759return false;760}761762// Set the correct thread state.763osthread->set_thread_type(thr_type);764765// Initial state is ALLOCATED but not INITIALIZED766osthread->set_state(ALLOCATED);767768thread->set_osthread(osthread);769770// Init thread attributes.771pthread_attr_t attr;772pthread_attr_init(&attr);773guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");774775// Make sure we run in 1:1 kernel-user-thread mode.776if (os::Aix::on_aix()) {777guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???");778guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???");779}780781// Start in suspended state, and in os::thread_start, wake the thread up.782guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");783784// Calculate stack size if it's not specified by caller.785size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);786787// JDK-8187028: It was observed that on some configurations (4K backed thread stacks)788// the real thread stack size may be smaller than the requested stack size, by as much as 64K.789// This very much looks like a pthread lib error. As a workaround, increase the stack size790// by 64K for small thread stacks (arbitrarily choosen to be < 4MB)791if (stack_size < 4096 * K) {792stack_size += 64 * K;793}794795// On Aix, pthread_attr_setstacksize fails with huge values and leaves the796// thread size in attr unchanged. If this is the minimal stack size as set797// by pthread_attr_init this leads to crashes after thread creation. E.g. the798// guard pages might not fit on the tiny stack created.799int ret = pthread_attr_setstacksize(&attr, stack_size);800if (ret != 0) {801log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k",802(thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "),803stack_size / K);804thread->set_osthread(NULL);805delete osthread;806return false;807}808809// Save some cycles and a page by disabling OS guard pages where we have our own810// VM guard pages (in java threads). For other threads, keep system default guard811// pages in place.812if (thr_type == java_thread || thr_type == compiler_thread) {813ret = pthread_attr_setguardsize(&attr, 0);814}815816ResourceMark rm;817pthread_t tid = 0;818819if (ret == 0) {820int limit = 3;821do {822ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);823} while (ret == EAGAIN && limit-- > 0);824}825826if (ret == 0) {827char buf[64];828log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",829thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));830} else {831char buf[64];832log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%d=%s) for attributes: %s.",833thread->name(), ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));834// Log some OS information which might explain why creating the thread failed.835log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());836LogStream st(Log(os, thread)::info());837os::Posix::print_rlimit_info(&st);838os::print_memory_info(&st);839}840841pthread_attr_destroy(&attr);842843if (ret != 0) {844// Need to clean up stuff we've allocated so far.845thread->set_osthread(NULL);846delete osthread;847return false;848}849850// OSThread::thread_id is the pthread id.851osthread->set_thread_id(tid);852853return true;854}855856/////////////////////////////////////////////////////////////////////////////857// attach existing thread858859// bootstrap the main thread860bool os::create_main_thread(JavaThread* thread) {861assert(os::Aix::_main_thread == pthread_self(), "should be called inside main thread");862return create_attached_thread(thread);863}864865bool os::create_attached_thread(JavaThread* thread) {866#ifdef ASSERT867thread->verify_not_published();868#endif869870// Allocate the OSThread object871OSThread* osthread = new OSThread(NULL, NULL);872873if (osthread == NULL) {874return false;875}876877const pthread_t pthread_id = ::pthread_self();878const tid_t kernel_thread_id = ::thread_self();879880// OSThread::thread_id is the pthread id.881osthread->set_thread_id(pthread_id);882883// .. but keep kernel thread id too for diagnostics884osthread->set_kernel_thread_id(kernel_thread_id);885886// initialize floating point control register887os::Aix::init_thread_fpu_state();888889// Initial thread state is RUNNABLE890osthread->set_state(RUNNABLE);891892thread->set_osthread(osthread);893894if (UseNUMA) {895int lgrp_id = os::numa_get_group_id();896if (lgrp_id != -1) {897thread->set_lgrp_id(lgrp_id);898}899}900901// initialize signal mask for this thread902// and save the caller's signal mask903PosixSignals::hotspot_sigmask(thread);904905log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",906os::current_thread_id(), (uintx) kernel_thread_id);907908return true;909}910911void os::pd_start_thread(Thread* thread) {912int status = pthread_continue_np(thread->osthread()->pthread_id());913assert(status == 0, "thr_continue failed");914}915916// Free OS resources related to the OSThread917void os::free_thread(OSThread* osthread) {918assert(osthread != NULL, "osthread not set");919920// We are told to free resources of the argument thread,921// but we can only really operate on the current thread.922assert(Thread::current()->osthread() == osthread,923"os::free_thread but not current thread");924925// Restore caller's signal mask926sigset_t sigmask = osthread->caller_sigmask();927pthread_sigmask(SIG_SETMASK, &sigmask, NULL);928929delete osthread;930}931932////////////////////////////////////////////////////////////////////////////////933// time support934935// Time since start-up in seconds to a fine granularity.936double os::elapsedTime() {937return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution938}939940jlong os::elapsed_counter() {941return javaTimeNanos() - initial_time_count;942}943944jlong os::elapsed_frequency() {945return NANOSECS_PER_SEC; // nanosecond resolution946}947948bool os::supports_vtime() { return true; }949950double os::elapsedVTime() {951struct rusage usage;952int retval = getrusage(RUSAGE_THREAD, &usage);953if (retval == 0) {954return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000);955} else {956// better than nothing, but not much957return elapsedTime();958}959}960961// We use mread_real_time here.962// On AIX: If the CPU has a time register, the result will be RTC_POWER and963// it has to be converted to real time. AIX documentations suggests to do964// this unconditionally, so we do it.965//966// See: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/read_real_time.htm967//968// On PASE: mread_real_time will always return RTC_POWER_PC data, so no969// conversion is necessary. However, mread_real_time will not return970// monotonic results but merely matches read_real_time. So we need a tweak971// to ensure monotonic results.972//973// For PASE no public documentation exists, just word by IBM974jlong os::javaTimeNanos() {975timebasestruct_t time;976int rc = mread_real_time(&time, TIMEBASE_SZ);977if (os::Aix::on_pase()) {978assert(rc == RTC_POWER, "expected time format RTC_POWER from mread_real_time in PASE");979jlong now = jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);980jlong prev = max_real_time;981if (now <= prev) {982return prev; // same or retrograde time;983}984jlong obsv = Atomic::cmpxchg(&max_real_time, prev, now);985assert(obsv >= prev, "invariant"); // Monotonicity986// If the CAS succeeded then we're done and return "now".987// If the CAS failed and the observed value "obsv" is >= now then988// we should return "obsv". If the CAS failed and now > obsv > prv then989// some other thread raced this thread and installed a new value, in which case990// we could either (a) retry the entire operation, (b) retry trying to install now991// or (c) just return obsv. We use (c). No loop is required although in some cases992// we might discard a higher "now" value in deference to a slightly lower but freshly993// installed obsv value. That's entirely benign -- it admits no new orderings compared994// to (a) or (b) -- and greatly reduces coherence traffic.995// We might also condition (c) on the magnitude of the delta between obsv and now.996// Avoiding excessive CAS operations to hot RW locations is critical.997// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate998return (prev == obsv) ? now : obsv;999} else {1000if (rc != RTC_POWER) {1001rc = time_base_to_time(&time, TIMEBASE_SZ);1002assert(rc != -1, "error calling time_base_to_time()");1003}1004return jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);1005}1006}10071008void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {1009info_ptr->max_value = ALL_64_BITS;1010// mread_real_time() is monotonic (see 'os::javaTimeNanos()')1011info_ptr->may_skip_backward = false;1012info_ptr->may_skip_forward = false;1013info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time1014}10151016// Return the real, user, and system times in seconds from an1017// arbitrary fixed point in the past.1018bool os::getTimesSecs(double* process_real_time,1019double* process_user_time,1020double* process_system_time) {1021struct tms ticks;1022clock_t real_ticks = times(&ticks);10231024if (real_ticks == (clock_t) (-1)) {1025return false;1026} else {1027double ticks_per_second = (double) clock_tics_per_sec;1028*process_user_time = ((double) ticks.tms_utime) / ticks_per_second;1029*process_system_time = ((double) ticks.tms_stime) / ticks_per_second;1030*process_real_time = ((double) real_ticks) / ticks_per_second;10311032return true;1033}1034}10351036char * os::local_time_string(char *buf, size_t buflen) {1037struct tm t;1038time_t long_time;1039time(&long_time);1040localtime_r(&long_time, &t);1041jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",1042t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,1043t.tm_hour, t.tm_min, t.tm_sec);1044return buf;1045}10461047struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {1048return localtime_r(clock, res);1049}10501051intx os::current_thread_id() {1052return (intx)pthread_self();1053}10541055int os::current_process_id() {1056return getpid();1057}10581059// DLL functions10601061const char* os::dll_file_extension() { return ".so"; }10621063// This must be hard coded because it's the system's temporary1064// directory not the java application's temp directory, ala java.io.tmpdir.1065const char* os::get_temp_directory() { return "/tmp"; }10661067// Check if addr is inside libjvm.so.1068bool os::address_is_in_vm(address addr) {10691070// Input could be a real pc or a function pointer literal. The latter1071// would be a function descriptor residing in the data segment of a module.1072loaded_module_t lm;1073if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL) {1074return lm.is_in_vm;1075} else if (LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {1076return lm.is_in_vm;1077} else {1078return false;1079}10801081}10821083// Resolve an AIX function descriptor literal to a code pointer.1084// If the input is a valid code pointer to a text segment of a loaded module,1085// it is returned unchanged.1086// If the input is a valid AIX function descriptor, it is resolved to the1087// code entry point.1088// If the input is neither a valid function descriptor nor a valid code pointer,1089// NULL is returned.1090static address resolve_function_descriptor_to_code_pointer(address p) {10911092if (LoadedLibraries::find_for_text_address(p, NULL) != NULL) {1093// It is a real code pointer.1094return p;1095} else if (LoadedLibraries::find_for_data_address(p, NULL) != NULL) {1096// Pointer to data segment, potential function descriptor.1097address code_entry = (address)(((FunctionDescriptor*)p)->entry());1098if (LoadedLibraries::find_for_text_address(code_entry, NULL) != NULL) {1099// It is a function descriptor.1100return code_entry;1101}1102}11031104return NULL;1105}11061107bool os::dll_address_to_function_name(address addr, char *buf,1108int buflen, int *offset,1109bool demangle) {1110if (offset) {1111*offset = -1;1112}1113// Buf is not optional, but offset is optional.1114assert(buf != NULL, "sanity check");1115buf[0] = '\0';11161117// Resolve function ptr literals first.1118addr = resolve_function_descriptor_to_code_pointer(addr);1119if (!addr) {1120return false;1121}11221123return AixSymbols::get_function_name(addr, buf, buflen, offset, NULL, demangle);1124}11251126bool os::dll_address_to_library_name(address addr, char* buf,1127int buflen, int* offset) {1128if (offset) {1129*offset = -1;1130}1131// Buf is not optional, but offset is optional.1132assert(buf != NULL, "sanity check");1133buf[0] = '\0';11341135// Resolve function ptr literals first.1136addr = resolve_function_descriptor_to_code_pointer(addr);1137if (!addr) {1138return false;1139}11401141return AixSymbols::get_module_name(addr, buf, buflen);1142}11431144// Loads .dll/.so and in case of error it checks if .dll/.so was built1145// for the same architecture as Hotspot is running on.1146void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {11471148log_info(os)("attempting shared library load of %s", filename);11491150if (ebuf && ebuflen > 0) {1151ebuf[0] = '\0';1152ebuf[ebuflen - 1] = '\0';1153}11541155if (!filename || strlen(filename) == 0) {1156::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1);1157return NULL;1158}11591160// RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants.1161void * result= ::dlopen(filename, RTLD_LAZY);1162if (result != NULL) {1163Events::log_dll_message(NULL, "Loaded shared library %s", filename);1164// Reload dll cache. Don't do this in signal handling.1165LoadedLibraries::reload();1166log_info(os)("shared library load of %s was successful", filename);1167return result;1168} else {1169// error analysis when dlopen fails1170const char* error_report = ::dlerror();1171if (error_report == NULL) {1172error_report = "dlerror returned no error description";1173}1174if (ebuf != NULL && ebuflen > 0) {1175snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",1176filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);1177}1178Events::log_dll_message(NULL, "Loading shared library %s failed, %s", filename, error_report);1179log_info(os)("shared library load of %s failed, %s", filename, error_report);1180}1181return NULL;1182}11831184void os::print_dll_info(outputStream *st) {1185st->print_cr("Dynamic libraries:");1186LoadedLibraries::print(st);1187}11881189void os::get_summary_os_info(char* buf, size_t buflen) {1190// There might be something more readable than uname results for AIX.1191struct utsname name;1192uname(&name);1193snprintf(buf, buflen, "%s %s", name.release, name.version);1194}11951196int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1197// Not yet implemented.1198return 0;1199}12001201void os::print_os_info_brief(outputStream* st) {1202uint32_t ver = os::Aix::os_version();1203st->print_cr("AIX kernel version %u.%u.%u.%u",1204(ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);12051206os::Posix::print_uname_info(st);12071208// Linux uses print_libversion_info(st); here.1209}12101211void os::print_os_info(outputStream* st) {1212st->print_cr("OS:");12131214os::Posix::print_uname_info(st);12151216uint32_t ver = os::Aix::os_version();1217st->print_cr("AIX kernel version %u.%u.%u.%u",1218(ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);12191220os::Posix::print_uptime_info(st);12211222os::Posix::print_rlimit_info(st);12231224os::Posix::print_load_average(st);12251226// _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.1227long tmax = sysconf(_SC_THREAD_THREADS_MAX);1228st->print_cr("maximum #threads within a process:%ld", tmax);12291230// print wpar info1231libperfstat::wparinfo_t wi;1232if (libperfstat::get_wparinfo(&wi)) {1233st->print_cr("wpar info");1234st->print_cr("name: %s", wi.name);1235st->print_cr("id: %d", wi.wpar_id);1236st->print_cr("type: %s", (wi.app_wpar ? "application" : "system"));1237}12381239VM_Version::print_platform_virtualization_info(st);1240}12411242void os::print_memory_info(outputStream* st) {12431244st->print_cr("Memory:");12451246st->print_cr(" Base page size (sysconf _SC_PAGESIZE): %s",1247describe_pagesize(g_multipage_support.pagesize));1248st->print_cr(" Data page size (C-Heap, bss, etc): %s",1249describe_pagesize(g_multipage_support.datapsize));1250st->print_cr(" Text page size: %s",1251describe_pagesize(g_multipage_support.textpsize));1252st->print_cr(" Thread stack page size (pthread): %s",1253describe_pagesize(g_multipage_support.pthr_stack_pagesize));1254st->print_cr(" Default shared memory page size: %s",1255describe_pagesize(g_multipage_support.shmpsize));1256st->print_cr(" Can use 64K pages dynamically with shared memory: %s",1257(g_multipage_support.can_use_64K_pages ? "yes" :"no"));1258st->print_cr(" Can use 16M pages dynamically with shared memory: %s",1259(g_multipage_support.can_use_16M_pages ? "yes" :"no"));1260st->print_cr(" Multipage error: %d",1261g_multipage_support.error);1262st->cr();1263st->print_cr(" os::vm_page_size: %s", describe_pagesize(os::vm_page_size()));12641265// print out LDR_CNTRL because it affects the default page sizes1266const char* const ldr_cntrl = ::getenv("LDR_CNTRL");1267st->print_cr(" LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>");12681269// Print out EXTSHM because it is an unsupported setting.1270const char* const extshm = ::getenv("EXTSHM");1271st->print_cr(" EXTSHM=%s.", extshm ? extshm : "<unset>");1272if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) {1273st->print_cr(" *** Unsupported! Please remove EXTSHM from your environment! ***");1274}12751276// Print out AIXTHREAD_GUARDPAGES because it affects the size of pthread stacks.1277const char* const aixthread_guardpages = ::getenv("AIXTHREAD_GUARDPAGES");1278st->print_cr(" AIXTHREAD_GUARDPAGES=%s.",1279aixthread_guardpages ? aixthread_guardpages : "<unset>");1280st->cr();12811282os::Aix::meminfo_t mi;1283if (os::Aix::get_meminfo(&mi)) {1284if (os::Aix::on_aix()) {1285st->print_cr("physical total : " SIZE_FORMAT, mi.real_total);1286st->print_cr("physical free : " SIZE_FORMAT, mi.real_free);1287st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total);1288st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free);1289} else {1290// PASE - Numbers are result of QWCRSSTS; they mean:1291// real_total: Sum of all system pools1292// real_free: always 01293// pgsp_total: we take the size of the system ASP1294// pgsp_free: size of system ASP times percentage of system ASP unused1295st->print_cr("physical total : " SIZE_FORMAT, mi.real_total);1296st->print_cr("system asp total : " SIZE_FORMAT, mi.pgsp_total);1297st->print_cr("%% system asp used : %.2f",1298mi.pgsp_total ? (100.0f * (mi.pgsp_total - mi.pgsp_free) / mi.pgsp_total) : -1.0f);1299}1300}1301st->cr();13021303// Print program break.1304st->print_cr("Program break at VM startup: " PTR_FORMAT ".", p2i(g_brk_at_startup));1305address brk_now = (address)::sbrk(0);1306if (brk_now != (address)-1) {1307st->print_cr("Program break now : " PTR_FORMAT " (distance: " SIZE_FORMAT "k).",1308p2i(brk_now), (size_t)((brk_now - g_brk_at_startup) / K));1309}1310st->print_cr("MaxExpectedDataSegmentSize : " SIZE_FORMAT "k.", MaxExpectedDataSegmentSize / K);1311st->cr();13121313// Print segments allocated with os::reserve_memory.1314st->print_cr("internal virtual memory regions used by vm:");1315vmembk_print_on(st);1316}13171318// Get a string for the cpuinfo that is a summary of the cpu type1319void os::get_summary_cpu_info(char* buf, size_t buflen) {1320// read _system_configuration.version1321switch (_system_configuration.version) {1322case PV_9:1323strncpy(buf, "Power PC 9", buflen);1324break;1325case PV_8:1326strncpy(buf, "Power PC 8", buflen);1327break;1328case PV_7:1329strncpy(buf, "Power PC 7", buflen);1330break;1331case PV_6_1:1332strncpy(buf, "Power PC 6 DD1.x", buflen);1333break;1334case PV_6:1335strncpy(buf, "Power PC 6", buflen);1336break;1337case PV_5:1338strncpy(buf, "Power PC 5", buflen);1339break;1340case PV_5_2:1341strncpy(buf, "Power PC 5_2", buflen);1342break;1343case PV_5_3:1344strncpy(buf, "Power PC 5_3", buflen);1345break;1346case PV_5_Compat:1347strncpy(buf, "PV_5_Compat", buflen);1348break;1349case PV_6_Compat:1350strncpy(buf, "PV_6_Compat", buflen);1351break;1352case PV_7_Compat:1353strncpy(buf, "PV_7_Compat", buflen);1354break;1355case PV_8_Compat:1356strncpy(buf, "PV_8_Compat", buflen);1357break;1358case PV_9_Compat:1359strncpy(buf, "PV_9_Compat", buflen);1360break;1361default:1362strncpy(buf, "unknown", buflen);1363}1364}13651366void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {1367// Nothing to do beyond of what os::print_cpu_info() does.1368}13691370static char saved_jvm_path[MAXPATHLEN] = {0};13711372// Find the full path to the current module, libjvm.so.1373void os::jvm_path(char *buf, jint buflen) {1374// Error checking.1375if (buflen < MAXPATHLEN) {1376assert(false, "must use a large-enough buffer");1377buf[0] = '\0';1378return;1379}1380// Lazy resolve the path to current module.1381if (saved_jvm_path[0] != 0) {1382strcpy(buf, saved_jvm_path);1383return;1384}13851386Dl_info dlinfo;1387int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);1388assert(ret != 0, "cannot locate libjvm");1389char* rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);1390assert(rp != NULL, "error in realpath(): maybe the 'path' argument is too long?");13911392if (Arguments::sun_java_launcher_is_altjvm()) {1393// Support for the java launcher's '-XXaltjvm=<path>' option. Typical1394// value for buf is "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.so".1395// If "/jre/lib/" appears at the right place in the string, then1396// assume we are installed in a JDK and we're done. Otherwise, check1397// for a JAVA_HOME environment variable and fix up the path so it1398// looks like libjvm.so is installed there (append a fake suffix1399// hotspot/libjvm.so).1400const char *p = buf + strlen(buf) - 1;1401for (int count = 0; p > buf && count < 4; ++count) {1402for (--p; p > buf && *p != '/'; --p)1403/* empty */ ;1404}14051406if (strncmp(p, "/jre/lib/", 9) != 0) {1407// Look for JAVA_HOME in the environment.1408char* java_home_var = ::getenv("JAVA_HOME");1409if (java_home_var != NULL && java_home_var[0] != 0) {1410char* jrelib_p;1411int len;14121413// Check the current module name "libjvm.so".1414p = strrchr(buf, '/');1415if (p == NULL) {1416return;1417}1418assert(strstr(p, "/libjvm") == p, "invalid library name");14191420rp = os::Posix::realpath(java_home_var, buf, buflen);1421if (rp == NULL) {1422return;1423}14241425// determine if this is a legacy image or modules image1426// modules image doesn't have "jre" subdirectory1427len = strlen(buf);1428assert(len < buflen, "Ran out of buffer room");1429jrelib_p = buf + len;1430snprintf(jrelib_p, buflen-len, "/jre/lib");1431if (0 != access(buf, F_OK)) {1432snprintf(jrelib_p, buflen-len, "/lib");1433}14341435if (0 == access(buf, F_OK)) {1436// Use current module name "libjvm.so"1437len = strlen(buf);1438snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");1439} else {1440// Go back to path of .so1441rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);1442if (rp == NULL) {1443return;1444}1445}1446}1447}1448}14491450strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path));1451saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0';1452}14531454void os::print_jni_name_prefix_on(outputStream* st, int args_size) {1455// no prefix required, not even "_"1456}14571458void os::print_jni_name_suffix_on(outputStream* st, int args_size) {1459// no suffix required1460}14611462////////////////////////////////////////////////////////////////////////////////1463// Virtual Memory14641465// We need to keep small simple bookkeeping for os::reserve_memory and friends.14661467#define VMEM_MAPPED 11468#define VMEM_SHMATED 214691470struct vmembk_t {1471int type; // 1 - mmap, 2 - shmat1472char* addr;1473size_t size; // Real size, may be larger than usersize.1474size_t pagesize; // page size of area1475vmembk_t* next;14761477bool contains_addr(char* p) const {1478return p >= addr && p < (addr + size);1479}14801481bool contains_range(char* p, size_t s) const {1482return contains_addr(p) && contains_addr(p + s - 1);1483}14841485void print_on(outputStream* os) const {1486os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (" UINTX_FORMAT1487" bytes, %d %s pages), %s",1488addr, addr + size - 1, size, size / pagesize, describe_pagesize(pagesize),1489(type == VMEM_SHMATED ? "shmat" : "mmap")1490);1491}14921493// Check that range is a sub range of memory block (or equal to memory block);1494// also check that range is fully page aligned to the page size if the block.1495void assert_is_valid_subrange(char* p, size_t s) const {1496if (!contains_range(p, s)) {1497trcVerbose("[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "1498"range of [" PTR_FORMAT " - " PTR_FORMAT "].",1499p2i(p), p2i(p + s), p2i(addr), p2i(addr + size));1500guarantee0(false);1501}1502if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {1503trcVerbose("range [" PTR_FORMAT " - " PTR_FORMAT "] is not"1504" aligned to pagesize (%lu)", p2i(p), p2i(p + s), (unsigned long) pagesize);1505guarantee0(false);1506}1507}1508};15091510static struct {1511vmembk_t* first;1512MiscUtils::CritSect cs;1513} vmem;15141515static void vmembk_add(char* addr, size_t size, size_t pagesize, int type) {1516vmembk_t* p = (vmembk_t*) ::malloc(sizeof(vmembk_t));1517assert0(p);1518if (p) {1519MiscUtils::AutoCritSect lck(&vmem.cs);1520p->addr = addr; p->size = size;1521p->pagesize = pagesize;1522p->type = type;1523p->next = vmem.first;1524vmem.first = p;1525}1526}15271528static vmembk_t* vmembk_find(char* addr) {1529MiscUtils::AutoCritSect lck(&vmem.cs);1530for (vmembk_t* p = vmem.first; p; p = p->next) {1531if (p->addr <= addr && (p->addr + p->size) > addr) {1532return p;1533}1534}1535return NULL;1536}15371538static void vmembk_remove(vmembk_t* p0) {1539MiscUtils::AutoCritSect lck(&vmem.cs);1540assert0(p0);1541assert0(vmem.first); // List should not be empty.1542for (vmembk_t** pp = &(vmem.first); *pp; pp = &((*pp)->next)) {1543if (*pp == p0) {1544*pp = p0->next;1545::free(p0);1546return;1547}1548}1549assert0(false); // Not found?1550}15511552static void vmembk_print_on(outputStream* os) {1553MiscUtils::AutoCritSect lck(&vmem.cs);1554for (vmembk_t* vmi = vmem.first; vmi; vmi = vmi->next) {1555vmi->print_on(os);1556os->cr();1557}1558}15591560// Reserve and attach a section of System V memory.1561// If <requested_addr> is not NULL, function will attempt to attach the memory at the given1562// address. Failing that, it will attach the memory anywhere.1563// If <requested_addr> is NULL, function will attach the memory anywhere.1564static char* reserve_shmated_memory (size_t bytes, char* requested_addr) {15651566trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "1567PTR_FORMAT "...", bytes, p2i(requested_addr));15681569// We must prevent anyone from attaching too close to the1570// BRK because that may cause malloc OOM.1571if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {1572trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment.", p2i(requested_addr));1573// Since we treat an attach to the wrong address as an error later anyway,1574// we return NULL here1575return NULL;1576}15771578// For old AS/400's (V5R4 and older) we should not even be here - System V shared memory is not1579// really supported (max size 4GB), so reserve_mmapped_memory should have been used instead.1580if (os::Aix::on_pase_V5R4_or_older()) {1581ShouldNotReachHere();1582}15831584// Align size of shm up to 64K to avoid errors if we later try to change the page size.1585const size_t size = align_up(bytes, 64*K);15861587// Reserve the shared segment.1588int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR);1589if (shmid == -1) {1590trcVerbose("shmget(.., " UINTX_FORMAT ", ..) failed (errno: %d).", size, errno);1591return NULL;1592}15931594// Important note:1595// It is very important that we, upon leaving this function, do not leave a shm segment alive.1596// We must right after attaching it remove it from the system. System V shm segments are global and1597// survive the process.1598// So, from here on: Do not assert, do not return, until we have called shmctl(IPC_RMID) (A).15991600struct shmid_ds shmbuf;1601memset(&shmbuf, 0, sizeof(shmbuf));1602shmbuf.shm_pagesize = 64*K;1603if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) != 0) {1604trcVerbose("Failed to set page size (need " UINTX_FORMAT " 64K pages) - shmctl failed with %d.",1605size / (64*K), errno);1606// I want to know if this ever happens.1607assert(false, "failed to set page size for shmat");1608}16091610// Now attach the shared segment.1611// Note that I attach with SHM_RND - which means that the requested address is rounded down, if1612// needed, to the next lowest segment boundary. Otherwise the attach would fail if the address1613// were not a segment boundary.1614char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND);1615const int errno_shmat = errno;16161617// (A) Right after shmat and before handing shmat errors delete the shm segment.1618if (::shmctl(shmid, IPC_RMID, NULL) == -1) {1619trcVerbose("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno);1620assert(false, "failed to remove shared memory segment!");1621}16221623// Handle shmat error. If we failed to attach, just return.1624if (addr == (char*)-1) {1625trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", p2i(requested_addr), errno_shmat);1626return NULL;1627}16281629// Just for info: query the real page size. In case setting the page size did not1630// work (see above), the system may have given us something other then 4K (LDR_CNTRL).1631const size_t real_pagesize = os::Aix::query_pagesize(addr);1632if (real_pagesize != shmbuf.shm_pagesize) {1633trcVerbose("pagesize is, surprisingly, " SIZE_FORMAT, real_pagesize);1634}16351636if (addr) {1637trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",1638p2i(addr), p2i(addr + size - 1), size, size/real_pagesize, describe_pagesize(real_pagesize));1639} else {1640if (requested_addr != NULL) {1641trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, p2i(requested_addr));1642} else {1643trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);1644}1645}16461647// book-keeping1648vmembk_add(addr, size, real_pagesize, VMEM_SHMATED);1649assert0(is_aligned_to(addr, os::vm_page_size()));16501651return addr;1652}16531654static bool release_shmated_memory(char* addr, size_t size) {16551656trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1657p2i(addr), p2i(addr + size - 1));16581659bool rc = false;16601661// TODO: is there a way to verify shm size without doing bookkeeping?1662if (::shmdt(addr) != 0) {1663trcVerbose("error (%d).", errno);1664} else {1665trcVerbose("ok.");1666rc = true;1667}1668return rc;1669}16701671static bool uncommit_shmated_memory(char* addr, size_t size) {1672trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1673p2i(addr), p2i(addr + size - 1));16741675const bool rc = my_disclaim64(addr, size);16761677if (!rc) {1678trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", p2i(addr), size);1679return false;1680}1681return true;1682}16831684//////////////////////////////// mmap-based routines /////////////////////////////////16851686// Reserve memory via mmap.1687// If <requested_addr> is given, an attempt is made to attach at the given address.1688// Failing that, memory is allocated at any address.1689static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) {1690trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT "...",1691bytes, p2i(requested_addr));16921693if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {1694trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", p2i(requested_addr));1695return NULL;1696}16971698// We must prevent anyone from attaching too close to the1699// BRK because that may cause malloc OOM.1700if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {1701trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment.", p2i(requested_addr));1702// Since we treat an attach to the wrong address as an error later anyway,1703// we return NULL here1704return NULL;1705}17061707// In 64K mode, we lie and claim the global page size (os::vm_page_size()) is 64K1708// (complicated story). This mostly works just fine since 64K is a multiple of the1709// actual 4K lowest page size. Only at a few seams light shines thru, e.g. when1710// calling mmap. mmap will return memory aligned to the lowest pages size - 4K -1711// so we must make sure - transparently - that the caller only ever sees 64K1712// aligned mapping start addresses.1713const size_t alignment = os::vm_page_size();17141715// Size shall always be a multiple of os::vm_page_size (esp. in 64K mode).1716const size_t size = align_up(bytes, os::vm_page_size());17171718// alignment: Allocate memory large enough to include an aligned range of the right size and1719// cut off the leading and trailing waste pages.1720assert0(alignment != 0 && is_aligned_to(alignment, os::vm_page_size())); // see above1721const size_t extra_size = size + alignment;17221723// Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to1724// later use msync(MS_INVALIDATE) (see os::uncommit_memory).1725int flags = MAP_ANONYMOUS | MAP_SHARED;17261727// MAP_FIXED is needed to enforce requested_addr - manpage is vague about what1728// it means if wishaddress is given but MAP_FIXED is not set.1729//1730// Important! Behaviour differs depending on whether SPEC1170 mode is active or not.1731// SPEC1170 mode active: behaviour like POSIX, MAP_FIXED will clobber existing mappings.1732// SPEC1170 mode not active: behaviour, unlike POSIX, is that no existing mappings will1733// get clobbered.1734if (requested_addr != NULL) {1735if (!os::Aix::xpg_sus_mode()) { // not SPEC1170 Behaviour1736flags |= MAP_FIXED;1737}1738}17391740char* addr = (char*)::mmap(requested_addr, extra_size,1741PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);17421743if (addr == MAP_FAILED) {1744trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", p2i(requested_addr), size, errno);1745return NULL;1746} else if (requested_addr != NULL && addr != requested_addr) {1747trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) succeeded, but at a different address than requested (" PTR_FORMAT "), will unmap",1748p2i(requested_addr), size, p2i(addr));1749::munmap(addr, extra_size);1750return NULL;1751}17521753// Handle alignment.1754char* const addr_aligned = align_up(addr, alignment);1755const size_t waste_pre = addr_aligned - addr;1756char* const addr_aligned_end = addr_aligned + size;1757const size_t waste_post = extra_size - waste_pre - size;1758if (waste_pre > 0) {1759::munmap(addr, waste_pre);1760}1761if (waste_post > 0) {1762::munmap(addr_aligned_end, waste_post);1763}1764addr = addr_aligned;17651766trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",1767p2i(addr), p2i(addr + bytes), bytes);17681769// bookkeeping1770vmembk_add(addr, size, 4*K, VMEM_MAPPED);17711772// Test alignment, see above.1773assert0(is_aligned_to(addr, os::vm_page_size()));17741775return addr;1776}17771778static bool release_mmaped_memory(char* addr, size_t size) {1779assert0(is_aligned_to(addr, os::vm_page_size()));1780assert0(is_aligned_to(size, os::vm_page_size()));17811782trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1783p2i(addr), p2i(addr + size - 1));1784bool rc = false;17851786if (::munmap(addr, size) != 0) {1787trcVerbose("failed (%d)\n", errno);1788rc = false;1789} else {1790trcVerbose("ok.");1791rc = true;1792}17931794return rc;1795}17961797static bool uncommit_mmaped_memory(char* addr, size_t size) {17981799assert0(is_aligned_to(addr, os::vm_page_size()));1800assert0(is_aligned_to(size, os::vm_page_size()));18011802trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1803p2i(addr), p2i(addr + size - 1));1804bool rc = false;18051806// Uncommit mmap memory with msync MS_INVALIDATE.1807if (::msync(addr, size, MS_INVALIDATE) != 0) {1808trcVerbose("failed (%d)\n", errno);1809rc = false;1810} else {1811trcVerbose("ok.");1812rc = true;1813}18141815return rc;1816}18171818int os::vm_page_size() {1819// Seems redundant as all get out.1820assert(os::Aix::page_size() != -1, "must call os::init");1821return os::Aix::page_size();1822}18231824// Aix allocates memory by pages.1825int os::vm_allocation_granularity() {1826assert(os::Aix::page_size() != -1, "must call os::init");1827return os::Aix::page_size();1828}18291830#ifdef PRODUCT1831static void warn_fail_commit_memory(char* addr, size_t size, bool exec,1832int err) {1833warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT1834", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,1835os::errno_name(err), err);1836}1837#endif18381839void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,1840const char* mesg) {1841assert(mesg != NULL, "mesg must be specified");1842if (!pd_commit_memory(addr, size, exec)) {1843// Add extra info in product mode for vm_exit_out_of_memory():1844PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)1845vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);1846}1847}18481849bool os::pd_commit_memory(char* addr, size_t size, bool exec) {18501851assert(is_aligned_to(addr, os::vm_page_size()),1852"addr " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1853p2i(addr), os::vm_page_size());1854assert(is_aligned_to(size, os::vm_page_size()),1855"size " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1856size, os::vm_page_size());18571858vmembk_t* const vmi = vmembk_find(addr);1859guarantee0(vmi);1860vmi->assert_is_valid_subrange(addr, size);18611862trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", p2i(addr), p2i(addr + size - 1));18631864if (UseExplicitCommit) {1865// AIX commits memory on touch. So, touch all pages to be committed.1866for (char* p = addr; p < (addr + size); p += 4*K) {1867*p = '\0';1868}1869}18701871return true;1872}18731874bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) {1875return pd_commit_memory(addr, size, exec);1876}18771878void os::pd_commit_memory_or_exit(char* addr, size_t size,1879size_t alignment_hint, bool exec,1880const char* mesg) {1881// Alignment_hint is ignored on this OS.1882pd_commit_memory_or_exit(addr, size, exec, mesg);1883}18841885bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {1886assert(is_aligned_to(addr, os::vm_page_size()),1887"addr " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1888p2i(addr), os::vm_page_size());1889assert(is_aligned_to(size, os::vm_page_size()),1890"size " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1891size, os::vm_page_size());18921893// Dynamically do different things for mmap/shmat.1894const vmembk_t* const vmi = vmembk_find(addr);1895guarantee0(vmi);1896vmi->assert_is_valid_subrange(addr, size);18971898if (vmi->type == VMEM_SHMATED) {1899return uncommit_shmated_memory(addr, size);1900} else {1901return uncommit_mmaped_memory(addr, size);1902}1903}19041905bool os::pd_create_stack_guard_pages(char* addr, size_t size) {1906// Do not call this; no need to commit stack pages on AIX.1907ShouldNotReachHere();1908return true;1909}19101911bool os::remove_stack_guard_pages(char* addr, size_t size) {1912// Do not call this; no need to commit stack pages on AIX.1913ShouldNotReachHere();1914return true;1915}19161917void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {1918}19191920void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {1921}19221923void os::numa_make_global(char *addr, size_t bytes) {1924}19251926void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {1927}19281929bool os::numa_topology_changed() {1930return false;1931}19321933size_t os::numa_get_groups_num() {1934return 1;1935}19361937int os::numa_get_group_id() {1938return 0;1939}19401941size_t os::numa_get_leaf_groups(int *ids, size_t size) {1942if (size > 0) {1943ids[0] = 0;1944return 1;1945}1946return 0;1947}19481949int os::numa_get_group_id_for_address(const void* address) {1950return 0;1951}19521953bool os::get_page_info(char *start, page_info* info) {1954return false;1955}19561957char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {1958return end;1959}19601961// Reserves and attaches a shared memory segment.1962char* os::pd_reserve_memory(size_t bytes, bool exec) {1963// Always round to os::vm_page_size(), which may be larger than 4K.1964bytes = align_up(bytes, os::vm_page_size());19651966// In 4K mode always use mmap.1967// In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.1968if (os::vm_page_size() == 4*K) {1969return reserve_mmaped_memory(bytes, NULL /* requested_addr */);1970} else {1971if (bytes >= Use64KPagesThreshold) {1972return reserve_shmated_memory(bytes, NULL /* requested_addr */);1973} else {1974return reserve_mmaped_memory(bytes, NULL /* requested_addr */);1975}1976}1977}19781979bool os::pd_release_memory(char* addr, size_t size) {19801981// Dynamically do different things for mmap/shmat.1982vmembk_t* const vmi = vmembk_find(addr);1983guarantee0(vmi);1984vmi->assert_is_valid_subrange(addr, size);19851986// Always round to os::vm_page_size(), which may be larger than 4K.1987size = align_up(size, os::vm_page_size());1988addr = align_up(addr, os::vm_page_size());19891990bool rc = false;1991bool remove_bookkeeping = false;1992if (vmi->type == VMEM_SHMATED) {1993// For shmatted memory, we do:1994// - If user wants to release the whole range, release the memory (shmdt).1995// - If user only wants to release a partial range, uncommit (disclaim) that1996// range. That way, at least, we do not use memory anymore (bust still page1997// table space).1998if (addr == vmi->addr && size == vmi->size) {1999rc = release_shmated_memory(addr, size);2000remove_bookkeeping = true;2001} else {2002rc = uncommit_shmated_memory(addr, size);2003}2004} else {2005// In mmap-mode:2006// - If the user wants to release the full range, we do that and remove the mapping.2007// - If the user wants to release part of the range, we release that part, but need2008// to adjust bookkeeping.2009assert(is_aligned(size, 4 * K), "Sanity");2010rc = release_mmaped_memory(addr, size);2011if (addr == vmi->addr && size == vmi->size) {2012remove_bookkeeping = true;2013} else {2014if (addr == vmi->addr && size < vmi->size) {2015// Chopped from head2016vmi->addr += size;2017vmi->size -= size;2018} else if (addr + size == vmi->addr + vmi->size) {2019// Chopped from tail2020vmi->size -= size;2021} else {2022// releasing a mapping in the middle of the original mapping:2023// For now we forbid this, since this is an invalid scenario2024// (the bookkeeping is easy enough to fix if needed but there2025// is no use case for it; any occurrence is likely an error.2026ShouldNotReachHere();2027}2028}2029}20302031// update bookkeeping2032if (rc && remove_bookkeeping) {2033vmembk_remove(vmi);2034}20352036return rc;2037}20382039static bool checked_mprotect(char* addr, size_t size, int prot) {20402041// Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will2042// not tell me if protection failed when trying to protect an un-protectable range.2043//2044// This means if the memory was allocated using shmget/shmat, protection wont work2045// but mprotect will still return 0:2046//2047// See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm20482049Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);2050bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;20512052if (!rc) {2053const char* const s_errno = os::errno_name(errno);2054warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno);2055return false;2056}20572058// mprotect success check2059//2060// Mprotect said it changed the protection but can I believe it?2061//2062// To be sure I need to check the protection afterwards. Try to2063// read from protected memory and check whether that causes a segfault.2064//2065if (!os::Aix::xpg_sus_mode()) {20662067if (CanUseSafeFetch32()) {20682069const bool read_protected =2070(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&2071SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;20722073if (prot & PROT_READ) {2074rc = !read_protected;2075} else {2076rc = read_protected;2077}20782079if (!rc) {2080if (os::Aix::on_pase()) {2081// There is an issue on older PASE systems where mprotect() will return success but the2082// memory will not be protected.2083// This has nothing to do with the problem of using mproect() on SPEC1170 incompatible2084// machines; we only see it rarely, when using mprotect() to protect the guard page of2085// a stack. It is an OS error.2086//2087// A valid strategy is just to try again. This usually works. :-/20882089::usleep(1000);2090Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);2091if (::mprotect(addr, size, prot) == 0) {2092const bool read_protected_2 =2093(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&2094SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;2095rc = true;2096}2097}2098}2099}2100}21012102assert(rc == true, "mprotect failed.");21032104return rc;2105}21062107// Set protections specified2108bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {2109unsigned int p = 0;2110switch (prot) {2111case MEM_PROT_NONE: p = PROT_NONE; break;2112case MEM_PROT_READ: p = PROT_READ; break;2113case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;2114case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;2115default:2116ShouldNotReachHere();2117}2118// is_committed is unused.2119return checked_mprotect(addr, size, p);2120}21212122bool os::guard_memory(char* addr, size_t size) {2123return checked_mprotect(addr, size, PROT_NONE);2124}21252126bool os::unguard_memory(char* addr, size_t size) {2127return checked_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC);2128}21292130// Large page support21312132static size_t _large_page_size = 0;21332134// Enable large page support if OS allows that.2135void os::large_page_init() {2136return; // Nothing to do. See query_multipage_support and friends.2137}21382139char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {2140fatal("os::reserve_memory_special should not be called on AIX.");2141return NULL;2142}21432144bool os::pd_release_memory_special(char* base, size_t bytes) {2145fatal("os::release_memory_special should not be called on AIX.");2146return false;2147}21482149size_t os::large_page_size() {2150return _large_page_size;2151}21522153bool os::can_commit_large_page_memory() {2154// Does not matter, we do not support huge pages.2155return false;2156}21572158bool os::can_execute_large_page_memory() {2159// Does not matter, we do not support huge pages.2160return false;2161}21622163char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {2164assert(file_desc >= 0, "file_desc is not valid");2165char* result = NULL;21662167// Always round to os::vm_page_size(), which may be larger than 4K.2168bytes = align_up(bytes, os::vm_page_size());2169result = reserve_mmaped_memory(bytes, requested_addr);21702171if (result != NULL) {2172if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {2173vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));2174}2175}2176return result;2177}21782179// Reserve memory at an arbitrary address, only if that area is2180// available (and not reserved for something else).2181char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {2182char* addr = NULL;21832184// Always round to os::vm_page_size(), which may be larger than 4K.2185bytes = align_up(bytes, os::vm_page_size());21862187// In 4K mode always use mmap.2188// In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.2189if (os::vm_page_size() == 4*K) {2190return reserve_mmaped_memory(bytes, requested_addr);2191} else {2192if (bytes >= Use64KPagesThreshold) {2193return reserve_shmated_memory(bytes, requested_addr);2194} else {2195return reserve_mmaped_memory(bytes, requested_addr);2196}2197}21982199return addr;2200}22012202// Used to convert frequent JVM_Yield() to nops2203bool os::dont_yield() {2204return DontYieldALot;2205}22062207void os::naked_yield() {2208sched_yield();2209}22102211////////////////////////////////////////////////////////////////////////////////2212// thread priority support22132214// From AIX manpage to pthread_setschedparam2215// (see: http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?2216// topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_setschedparam.htm):2217//2218// "If schedpolicy is SCHED_OTHER, then sched_priority must be in the2219// range from 40 to 80, where 40 is the least favored priority and 802220// is the most favored."2221//2222// (Actually, I doubt this even has an impact on AIX, as we do kernel2223// scheduling there; however, this still leaves iSeries.)2224//2225// We use the same values for AIX and PASE.2226int os::java_to_os_priority[CriticalPriority + 1] = {222754, // 0 Entry should never be used2228222955, // 1 MinPriority223055, // 2223156, // 32232223356, // 4223457, // 5 NormPriority223557, // 62236223758, // 7223858, // 8223959, // 9 NearMaxPriority2240224160, // 10 MaxPriority2242224360 // 11 CriticalPriority2244};22452246static int prio_init() {2247if (ThreadPriorityPolicy == 1) {2248if (geteuid() != 0) {2249if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy) && !FLAG_IS_JIMAGE_RESOURCE(ThreadPriorityPolicy)) {2250warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \2251"e.g., being the root user. If the necessary permission is not " \2252"possessed, changes to priority will be silently ignored.");2253}2254}2255}2256if (UseCriticalJavaThreadPriority) {2257os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];2258}2259return 0;2260}22612262OSReturn os::set_native_priority(Thread* thread, int newpri) {2263if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;2264pthread_t thr = thread->osthread()->pthread_id();2265int policy = SCHED_OTHER;2266struct sched_param param;2267param.sched_priority = newpri;2268int ret = pthread_setschedparam(thr, policy, ¶m);22692270if (ret != 0) {2271trcVerbose("Could not change priority for thread %d to %d (error %d, %s)",2272(int)thr, newpri, ret, os::errno_name(ret));2273}2274return (ret == 0) ? OS_OK : OS_ERR;2275}22762277OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {2278if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {2279*priority_ptr = java_to_os_priority[NormPriority];2280return OS_OK;2281}2282pthread_t thr = thread->osthread()->pthread_id();2283int policy = SCHED_OTHER;2284struct sched_param param;2285int ret = pthread_getschedparam(thr, &policy, ¶m);2286*priority_ptr = param.sched_priority;22872288return (ret == 0) ? OS_OK : OS_ERR;2289}22902291// To install functions for atexit system call2292extern "C" {2293static void perfMemory_exit_helper() {2294perfMemory_exit();2295}2296}22972298// This is called _before_ the most of global arguments have been parsed.2299void os::init(void) {2300// This is basic, we want to know if that ever changes.2301// (Shared memory boundary is supposed to be a 256M aligned.)2302assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected");23032304// Record process break at startup.2305g_brk_at_startup = (address) ::sbrk(0);2306assert(g_brk_at_startup != (address) -1, "sbrk failed");23072308// First off, we need to know whether we run on AIX or PASE, and2309// the OS level we run on.2310os::Aix::initialize_os_info();23112312// Scan environment (SPEC1170 behaviour, etc).2313os::Aix::scan_environment();23142315// Probe multipage support.2316query_multipage_support();23172318// Act like we only have one page size by eliminating corner cases which2319// we did not support very well anyway.2320// We have two input conditions:2321// 1) Data segment page size. This is controlled by linker setting (datapsize) on the2322// launcher, and/or by LDR_CNTRL environment variable. The latter overrules the linker2323// setting.2324// Data segment page size is important for us because it defines the thread stack page2325// size, which is needed for guard page handling, stack banging etc.2326// 2) The ability to allocate 64k pages dynamically. If this is a given, java heap can2327// and should be allocated with 64k pages.2328//2329// So, we do the following:2330// LDR_CNTRL can_use_64K_pages_dynamically what we do remarks2331// 4K no 4K old systems (aix 5.2, as/400 v5r4) or new systems with AME activated2332// 4k yes 64k (treat 4k stacks as 64k) different loader than java and standard settings2333// 64k no --- AIX 5.2 ? ---2334// 64k yes 64k new systems and standard java loader (we set datapsize=64k when linking)23352336// We explicitly leave no option to change page size, because only upgrading would work,2337// not downgrading (if stack page size is 64k you cannot pretend its 4k).23382339if (g_multipage_support.datapsize == 4*K) {2340// datapsize = 4K. Data segment, thread stacks are 4K paged.2341if (g_multipage_support.can_use_64K_pages) {2342// .. but we are able to use 64K pages dynamically.2343// This would be typical for java launchers which are not linked2344// with datapsize=64K (like, any other launcher but our own).2345//2346// In this case it would be smart to allocate the java heap with 64K2347// to get the performance benefit, and to fake 64k pages for the2348// data segment (when dealing with thread stacks).2349//2350// However, leave a possibility to downgrade to 4K, using2351// -XX:-Use64KPages.2352if (Use64KPages) {2353trcVerbose("64K page mode (faked for data segment)");2354Aix::_page_size = 64*K;2355} else {2356trcVerbose("4K page mode (Use64KPages=off)");2357Aix::_page_size = 4*K;2358}2359} else {2360// .. and not able to allocate 64k pages dynamically. Here, just2361// fall back to 4K paged mode and use mmap for everything.2362trcVerbose("4K page mode");2363Aix::_page_size = 4*K;2364FLAG_SET_ERGO(Use64KPages, false);2365}2366} else {2367// datapsize = 64k. Data segment, thread stacks are 64k paged.2368// This normally means that we can allocate 64k pages dynamically.2369// (There is one special case where this may be false: EXTSHM=on.2370// but we decided to not support that mode).2371assert0(g_multipage_support.can_use_64K_pages);2372Aix::_page_size = 64*K;2373trcVerbose("64K page mode");2374FLAG_SET_ERGO(Use64KPages, true);2375}23762377// For now UseLargePages is just ignored.2378FLAG_SET_ERGO(UseLargePages, false);2379_page_sizes.add(Aix::_page_size);23802381// debug trace2382trcVerbose("os::vm_page_size %s", describe_pagesize(os::vm_page_size()));23832384// Next, we need to initialize libo4 and libperfstat libraries.2385if (os::Aix::on_pase()) {2386os::Aix::initialize_libo4();2387} else {2388os::Aix::initialize_libperfstat();2389}23902391// Reset the perfstat information provided by ODM.2392if (os::Aix::on_aix()) {2393libperfstat::perfstat_reset();2394}23952396// Now initialze basic system properties. Note that for some of the values we2397// need libperfstat etc.2398os::Aix::initialize_system_info();23992400clock_tics_per_sec = sysconf(_SC_CLK_TCK);24012402// _main_thread points to the thread that created/loaded the JVM.2403Aix::_main_thread = pthread_self();24042405initial_time_count = javaTimeNanos();24062407os::Posix::init();2408}24092410// This is called _after_ the global arguments have been parsed.2411jint os::init_2(void) {24122413// This could be set after os::Posix::init() but all platforms2414// have to set it the same so we have to mirror Solaris.2415DEBUG_ONLY(os::set_mutex_init_done();)24162417os::Posix::init_2();24182419if (os::Aix::on_pase()) {2420trcVerbose("Running on PASE.");2421} else {2422trcVerbose("Running on AIX (not PASE).");2423}24242425trcVerbose("processor count: %d", os::_processor_count);2426trcVerbose("physical memory: %lu", Aix::_physical_memory);24272428// Initially build up the loaded dll map.2429LoadedLibraries::reload();2430if (Verbose) {2431trcVerbose("Loaded Libraries: ");2432LoadedLibraries::print(tty);2433}24342435if (PosixSignals::init() == JNI_ERR) {2436return JNI_ERR;2437}24382439// Check and sets minimum stack sizes against command line options2440if (Posix::set_minimum_stack_sizes() == JNI_ERR) {2441return JNI_ERR;2442}24432444// Not supported.2445FLAG_SET_ERGO(UseNUMA, false);2446FLAG_SET_ERGO(UseNUMAInterleaving, false);24472448if (MaxFDLimit) {2449// Set the number of file descriptors to max. print out error2450// if getrlimit/setrlimit fails but continue regardless.2451struct rlimit nbr_files;2452int status = getrlimit(RLIMIT_NOFILE, &nbr_files);2453if (status != 0) {2454log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));2455} else {2456nbr_files.rlim_cur = nbr_files.rlim_max;2457status = setrlimit(RLIMIT_NOFILE, &nbr_files);2458if (status != 0) {2459log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));2460}2461}2462}24632464if (PerfAllowAtExitRegistration) {2465// Only register atexit functions if PerfAllowAtExitRegistration is set.2466// At exit functions can be delayed until process exit time, which2467// can be problematic for embedded VM situations. Embedded VMs should2468// call DestroyJavaVM() to assure that VM resources are released.24692470// Note: perfMemory_exit_helper atexit function may be removed in2471// the future if the appropriate cleanup code can be added to the2472// VM_Exit VMOperation's doit method.2473if (atexit(perfMemory_exit_helper) != 0) {2474warning("os::init_2 atexit(perfMemory_exit_helper) failed");2475}2476}24772478// initialize thread priority policy2479prio_init();24802481return JNI_OK;2482}24832484int os::active_processor_count() {2485// User has overridden the number of active processors2486if (ActiveProcessorCount > 0) {2487log_trace(os)("active_processor_count: "2488"active processor count set by user : %d",2489ActiveProcessorCount);2490return ActiveProcessorCount;2491}24922493int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);2494assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");2495return online_cpus;2496}24972498void os::set_native_thread_name(const char *name) {2499// Not yet implemented.2500return;2501}25022503bool os::bind_to_processor(uint processor_id) {2504// Not yet implemented.2505return false;2506}25072508////////////////////////////////////////////////////////////////////////////////2509// debug support25102511bool os::find(address addr, outputStream* st) {25122513st->print(PTR_FORMAT ": ", addr);25142515loaded_module_t lm;2516if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL ||2517LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {2518st->print_cr("%s", lm.path);2519return true;2520}25212522return false;2523}25242525////////////////////////////////////////////////////////////////////////////////2526// misc25272528// This does not do anything on Aix. This is basically a hook for being2529// able to use structured exception handling (thread-local exception filters)2530// on, e.g., Win32.2531void2532os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,2533JavaCallArguments* args, JavaThread* thread) {2534f(value, method, args, thread);2535}25362537void os::print_statistics() {2538}25392540bool os::message_box(const char* title, const char* message) {2541int i;2542fdStream err(defaultStream::error_fd());2543for (i = 0; i < 78; i++) err.print_raw("=");2544err.cr();2545err.print_raw_cr(title);2546for (i = 0; i < 78; i++) err.print_raw("-");2547err.cr();2548err.print_raw_cr(message);2549for (i = 0; i < 78; i++) err.print_raw("=");2550err.cr();25512552char buf[16];2553// Prevent process from exiting upon "read error" without consuming all CPU2554while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }25552556return buf[0] == 'y' || buf[0] == 'Y';2557}25582559// This code originates from JDK's sysOpen and open64_w2560// from src/solaris/hpi/src/system_md.c25612562int os::open(const char *path, int oflag, int mode) {25632564if (strlen(path) > MAX_PATH - 1) {2565errno = ENAMETOOLONG;2566return -1;2567}2568// AIX 7.X now supports O_CLOEXEC too, like modern Linux; but we have to be careful, see2569// IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE2570int oflag_with_o_cloexec = oflag | O_CLOEXEC;25712572int fd = ::open64(path, oflag_with_o_cloexec, mode);2573if (fd == -1) {2574// we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804)2575fd = ::open64(path, oflag, mode);2576if (fd == -1) {2577return -1;2578}2579}25802581// If the open succeeded, the file might still be a directory.2582{2583struct stat64 buf64;2584int ret = ::fstat64(fd, &buf64);2585int st_mode = buf64.st_mode;25862587if (ret != -1) {2588if ((st_mode & S_IFMT) == S_IFDIR) {2589errno = EISDIR;2590::close(fd);2591return -1;2592}2593} else {2594::close(fd);2595return -1;2596}2597}25982599// All file descriptors that are opened in the JVM and not2600// specifically destined for a subprocess should have the2601// close-on-exec flag set. If we don't set it, then careless 3rd2602// party native code might fork and exec without closing all2603// appropriate file descriptors (e.g. as we do in closeDescriptors in2604// UNIXProcess.c), and this in turn might:2605//2606// - cause end-of-file to fail to be detected on some file2607// descriptors, resulting in mysterious hangs, or2608//2609// - might cause an fopen in the subprocess to fail on a system2610// suffering from bug 1085341.26112612// Validate that the use of the O_CLOEXEC flag on open above worked.2613static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;2614if (O_CLOEXEC_is_known_to_work == 0) {2615int flags = ::fcntl(fd, F_GETFD);2616if (flags != -1) {2617if ((flags & FD_CLOEXEC) != 0) {2618O_CLOEXEC_is_known_to_work = 1;2619} else { // it does not work2620::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2621O_CLOEXEC_is_known_to_work = -1;2622}2623}2624} else if (O_CLOEXEC_is_known_to_work == -1) {2625int flags = ::fcntl(fd, F_GETFD);2626if (flags != -1) {2627::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2628}2629}26302631return fd;2632}26332634// create binary file, rewriting existing file if required2635int os::create_binary_file(const char* path, bool rewrite_existing) {2636int oflags = O_WRONLY | O_CREAT;2637oflags |= rewrite_existing ? O_TRUNC : O_EXCL;2638return ::open64(path, oflags, S_IREAD | S_IWRITE);2639}26402641// return current position of file pointer2642jlong os::current_file_offset(int fd) {2643return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);2644}26452646// move file pointer to the specified offset2647jlong os::seek_to_file_offset(int fd, jlong offset) {2648return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);2649}26502651// This code originates from JDK's sysAvailable2652// from src/solaris/hpi/src/native_threads/src/sys_api_td.c26532654int os::available(int fd, jlong *bytes) {2655jlong cur, end;2656int mode;2657struct stat64 buf64;26582659if (::fstat64(fd, &buf64) >= 0) {2660mode = buf64.st_mode;2661if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {2662int n;2663if (::ioctl(fd, FIONREAD, &n) >= 0) {2664*bytes = n;2665return 1;2666}2667}2668}2669if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {2670return 0;2671} else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {2672return 0;2673} else if (::lseek64(fd, cur, SEEK_SET) == -1) {2674return 0;2675}2676*bytes = end - cur;2677return 1;2678}26792680// Map a block of memory.2681char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,2682char *addr, size_t bytes, bool read_only,2683bool allow_exec) {2684int prot;2685int flags = MAP_PRIVATE;26862687if (read_only) {2688prot = PROT_READ;2689flags = MAP_SHARED;2690} else {2691prot = PROT_READ | PROT_WRITE;2692flags = MAP_PRIVATE;2693}26942695if (allow_exec) {2696prot |= PROT_EXEC;2697}26982699if (addr != NULL) {2700flags |= MAP_FIXED;2701}27022703// Allow anonymous mappings if 'fd' is -1.2704if (fd == -1) {2705flags |= MAP_ANONYMOUS;2706}27072708char* mapped_address = (char*)::mmap(addr, (size_t)bytes, prot, flags,2709fd, file_offset);2710if (mapped_address == MAP_FAILED) {2711return NULL;2712}2713return mapped_address;2714}27152716// Remap a block of memory.2717char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,2718char *addr, size_t bytes, bool read_only,2719bool allow_exec) {2720// same as map_memory() on this OS2721return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,2722allow_exec);2723}27242725// Unmap a block of memory.2726bool os::pd_unmap_memory(char* addr, size_t bytes) {2727return munmap(addr, bytes) == 0;2728}27292730// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)2731// are used by JVM M&M and JVMTI to get user+sys or user CPU time2732// of a thread.2733//2734// current_thread_cpu_time() and thread_cpu_time(Thread*) returns2735// the fast estimate available on the platform.27362737jlong os::current_thread_cpu_time() {2738// return user + sys since the cost is the same2739const jlong n = os::thread_cpu_time(Thread::current(), true /* user + sys */);2740assert(n >= 0, "negative CPU time");2741return n;2742}27432744jlong os::thread_cpu_time(Thread* thread) {2745// consistent with what current_thread_cpu_time() returns2746const jlong n = os::thread_cpu_time(thread, true /* user + sys */);2747assert(n >= 0, "negative CPU time");2748return n;2749}27502751jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {2752const jlong n = os::thread_cpu_time(Thread::current(), user_sys_cpu_time);2753assert(n >= 0, "negative CPU time");2754return n;2755}27562757static bool thread_cpu_time_unchecked(Thread* thread, jlong* p_sys_time, jlong* p_user_time) {2758bool error = false;27592760jlong sys_time = 0;2761jlong user_time = 0;27622763// Reimplemented using getthrds64().2764//2765// Works like this:2766// For the thread in question, get the kernel thread id. Then get the2767// kernel thread statistics using that id.2768//2769// This only works of course when no pthread scheduling is used,2770// i.e. there is a 1:1 relationship to kernel threads.2771// On AIX, see AIXTHREAD_SCOPE variable.27722773pthread_t pthtid = thread->osthread()->pthread_id();27742775// retrieve kernel thread id for the pthread:2776tid64_t tid = 0;2777struct __pthrdsinfo pinfo;2778// I just love those otherworldly IBM APIs which force me to hand down2779// dummy buffers for stuff I dont care for...2780char dummy[1];2781int dummy_size = sizeof(dummy);2782if (pthread_getthrds_np(&pthtid, PTHRDSINFO_QUERY_TID, &pinfo, sizeof(pinfo),2783dummy, &dummy_size) == 0) {2784tid = pinfo.__pi_tid;2785} else {2786tty->print_cr("pthread_getthrds_np failed.");2787error = true;2788}27892790// retrieve kernel timing info for that kernel thread2791if (!error) {2792struct thrdentry64 thrdentry;2793if (getthrds64(getpid(), &thrdentry, sizeof(thrdentry), &tid, 1) == 1) {2794sys_time = thrdentry.ti_ru.ru_stime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_stime.tv_usec * 1000LL;2795user_time = thrdentry.ti_ru.ru_utime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_utime.tv_usec * 1000LL;2796} else {2797tty->print_cr("pthread_getthrds_np failed.");2798error = true;2799}2800}28012802if (p_sys_time) {2803*p_sys_time = sys_time;2804}28052806if (p_user_time) {2807*p_user_time = user_time;2808}28092810if (error) {2811return false;2812}28132814return true;2815}28162817jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {2818jlong sys_time;2819jlong user_time;28202821if (!thread_cpu_time_unchecked(thread, &sys_time, &user_time)) {2822return -1;2823}28242825return user_sys_cpu_time ? sys_time + user_time : user_time;2826}28272828void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2829info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2830info_ptr->may_skip_backward = false; // elapsed time not wall time2831info_ptr->may_skip_forward = false; // elapsed time not wall time2832info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2833}28342835void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2836info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2837info_ptr->may_skip_backward = false; // elapsed time not wall time2838info_ptr->may_skip_forward = false; // elapsed time not wall time2839info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2840}28412842bool os::is_thread_cpu_time_supported() {2843return true;2844}28452846// System loadavg support. Returns -1 if load average cannot be obtained.2847// For now just return the system wide load average (no processor sets).2848int os::loadavg(double values[], int nelem) {28492850guarantee(nelem >= 0 && nelem <= 3, "argument error");2851guarantee(values, "argument error");28522853if (os::Aix::on_pase()) {28542855// AS/400 PASE: use libo4 porting library2856double v[3] = { 0.0, 0.0, 0.0 };28572858if (libo4::get_load_avg(v, v + 1, v + 2)) {2859for (int i = 0; i < nelem; i ++) {2860values[i] = v[i];2861}2862return nelem;2863} else {2864return -1;2865}28662867} else {28682869// AIX: use libperfstat2870libperfstat::cpuinfo_t ci;2871if (libperfstat::get_cpuinfo(&ci)) {2872for (int i = 0; i < nelem; i++) {2873values[i] = ci.loadavg[i];2874}2875} else {2876return -1;2877}2878return nelem;2879}2880}28812882void os::pause() {2883char filename[MAX_PATH];2884if (PauseAtStartupFile && PauseAtStartupFile[0]) {2885jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);2886} else {2887jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());2888}28892890int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);2891if (fd != -1) {2892struct stat buf;2893::close(fd);2894while (::stat(filename, &buf) == 0) {2895(void)::poll(NULL, 0, 100);2896}2897} else {2898trcVerbose("Could not open pause file '%s', continuing immediately.", filename);2899}2900}29012902bool os::is_primordial_thread(void) {2903if (pthread_self() == (pthread_t)1) {2904return true;2905} else {2906return false;2907}2908}29092910// OS recognitions (PASE/AIX, OS level) call this before calling any2911// one of Aix::on_pase(), Aix::os_version() static2912void os::Aix::initialize_os_info() {29132914assert(_on_pase == -1 && _os_version == 0, "already called.");29152916struct utsname uts;2917memset(&uts, 0, sizeof(uts));2918strcpy(uts.sysname, "?");2919if (::uname(&uts) == -1) {2920trcVerbose("uname failed (%d)", errno);2921guarantee(0, "Could not determine whether we run on AIX or PASE");2922} else {2923trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" "2924"node \"%s\" machine \"%s\"\n",2925uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);2926const int major = atoi(uts.version);2927assert(major > 0, "invalid OS version");2928const int minor = atoi(uts.release);2929assert(minor > 0, "invalid OS release");2930_os_version = (major << 24) | (minor << 16);2931char ver_str[20] = {0};2932const char* name_str = "unknown OS";2933if (strcmp(uts.sysname, "OS400") == 0) {2934// We run on AS/400 PASE. We do not support versions older than V5R4M0.2935_on_pase = 1;2936if (os_version_short() < 0x0504) {2937trcVerbose("OS/400 releases older than V5R4M0 not supported.");2938assert(false, "OS/400 release too old.");2939}2940name_str = "OS/400 (pase)";2941jio_snprintf(ver_str, sizeof(ver_str), "%u.%u", major, minor);2942} else if (strcmp(uts.sysname, "AIX") == 0) {2943// We run on AIX. We do not support versions older than AIX 7.1.2944_on_pase = 0;2945// Determine detailed AIX version: Version, Release, Modification, Fix Level.2946odmWrapper::determine_os_kernel_version(&_os_version);2947if (os_version_short() < 0x0701) {2948trcVerbose("AIX releases older than AIX 7.1 are not supported.");2949assert(false, "AIX release too old.");2950}2951name_str = "AIX";2952jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",2953major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);2954} else {2955assert(false, "%s", name_str);2956}2957trcVerbose("We run on %s %s", name_str, ver_str);2958}29592960guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release");2961} // end: os::Aix::initialize_os_info()29622963// Scan environment for important settings which might effect the VM.2964// Trace out settings. Warn about invalid settings and/or correct them.2965//2966// Must run after os::Aix::initialue_os_info().2967void os::Aix::scan_environment() {29682969char* p;2970int rc;29712972// Warn explicity if EXTSHM=ON is used. That switch changes how2973// System V shared memory behaves. One effect is that page size of2974// shared memory cannot be change dynamically, effectivly preventing2975// large pages from working.2976// This switch was needed on AIX 32bit, but on AIX 64bit the general2977// recommendation is (in OSS notes) to switch it off.2978p = ::getenv("EXTSHM");2979trcVerbose("EXTSHM=%s.", p ? p : "<unset>");2980if (p && strcasecmp(p, "ON") == 0) {2981_extshm = 1;2982trcVerbose("*** Unsupported mode! Please remove EXTSHM from your environment! ***");2983if (!AllowExtshm) {2984// We allow under certain conditions the user to continue. However, we want this2985// to be a fatal error by default. On certain AIX systems, leaving EXTSHM=ON means2986// that the VM is not able to allocate 64k pages for the heap.2987// We do not want to run with reduced performance.2988vm_exit_during_initialization("EXTSHM is ON. Please remove EXTSHM from your environment.");2989}2990} else {2991_extshm = 0;2992}29932994// SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs.2995// Not tested, not supported.2996//2997// Note that it might be worth the trouble to test and to require it, if only to2998// get useful return codes for mprotect.2999//3000// Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before3001// exec() ? before loading the libjvm ? ....)3002p = ::getenv("XPG_SUS_ENV");3003trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>");3004if (p && strcmp(p, "ON") == 0) {3005_xpg_sus_mode = 1;3006trcVerbose("Unsupported setting: XPG_SUS_ENV=ON");3007// This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to3008// clobber address ranges. If we ever want to support that, we have to do some3009// testing first.3010guarantee(false, "XPG_SUS_ENV=ON not supported");3011} else {3012_xpg_sus_mode = 0;3013}30143015if (os::Aix::on_pase()) {3016p = ::getenv("QIBM_MULTI_THREADED");3017trcVerbose("QIBM_MULTI_THREADED=%s.", p ? p : "<unset>");3018}30193020p = ::getenv("LDR_CNTRL");3021trcVerbose("LDR_CNTRL=%s.", p ? p : "<unset>");3022if (os::Aix::on_pase() && os::Aix::os_version_short() == 0x0701) {3023if (p && ::strstr(p, "TEXTPSIZE")) {3024trcVerbose("*** WARNING - LDR_CNTRL contains TEXTPSIZE. "3025"you may experience hangs or crashes on OS/400 V7R1.");3026}3027}30283029p = ::getenv("AIXTHREAD_GUARDPAGES");3030trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>");30313032} // end: os::Aix::scan_environment()30333034// PASE: initialize the libo4 library (PASE porting library).3035void os::Aix::initialize_libo4() {3036guarantee(os::Aix::on_pase(), "OS/400 only.");3037if (!libo4::init()) {3038trcVerbose("libo4 initialization failed.");3039assert(false, "libo4 initialization failed");3040} else {3041trcVerbose("libo4 initialized.");3042}3043}30443045// AIX: initialize the libperfstat library.3046void os::Aix::initialize_libperfstat() {3047assert(os::Aix::on_aix(), "AIX only");3048if (!libperfstat::init()) {3049trcVerbose("libperfstat initialization failed.");3050assert(false, "libperfstat initialization failed");3051} else {3052trcVerbose("libperfstat initialized.");3053}3054}30553056/////////////////////////////////////////////////////////////////////////////3057// thread stack30583059// Get the current stack base from the OS (actually, the pthread library).3060// Note: usually not page aligned.3061address os::current_stack_base() {3062AixMisc::stackbounds_t bounds;3063bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);3064guarantee(rc, "Unable to retrieve stack bounds.");3065return bounds.base;3066}30673068// Get the current stack size from the OS (actually, the pthread library).3069// Returned size is such that (base - size) is always aligned to page size.3070size_t os::current_stack_size() {3071AixMisc::stackbounds_t bounds;3072bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);3073guarantee(rc, "Unable to retrieve stack bounds.");3074// Align the returned stack size such that the stack low address3075// is aligned to page size (Note: base is usually not and we do not care).3076// We need to do this because caller code will assume stack low address is3077// page aligned and will place guard pages without checking.3078address low = bounds.base - bounds.size;3079address low_aligned = (address)align_up(low, os::vm_page_size());3080size_t s = bounds.base - low_aligned;3081return s;3082}30833084// Get the default path to the core file3085// Returns the length of the string3086int os::get_core_path(char* buffer, size_t bufferSize) {3087const char* p = get_current_directory(buffer, bufferSize);30883089if (p == NULL) {3090assert(p != NULL, "failed to get current directory");3091return 0;3092}30933094jio_snprintf(buffer, bufferSize, "%s/core or core.%d",3095p, current_process_id());30963097return strlen(buffer);3098}30993100bool os::start_debugging(char *buf, int buflen) {3101int len = (int)strlen(buf);3102char *p = &buf[len];31033104jio_snprintf(p, buflen -len,3105"\n\n"3106"Do you want to debug the problem?\n\n"3107"To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n"3108"Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"3109"Otherwise, press RETURN to abort...",3110os::current_process_id(),3111os::current_thread_id(), thread_self());31123113bool yes = os::message_box("Unexpected Error", buf);31143115if (yes) {3116// yes, user asked VM to launch debugger3117jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id());31183119os::fork_and_exec(buf);3120yes = false;3121}3122return yes;3123}31243125static inline time_t get_mtime(const char* filename) {3126struct stat st;3127int ret = os::stat(filename, &st);3128assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));3129return st.st_mtime;3130}31313132int os::compare_file_modified_times(const char* file1, const char* file2) {3133time_t t1 = get_mtime(file1);3134time_t t2 = get_mtime(file2);3135return t1 - t2;3136}31373138bool os::supports_map_sync() {3139return false;3140}31413142void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}314331443145