jdk

Форк
0
/
os_aix.cpp 
2840 строк · 95.9 Кб
1
/*
2
 * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
3
 * Copyright (c) 2012, 2024 SAP SE. All rights reserved.
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
 *
6
 * This code is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License version 2 only, as
8
 * published by the Free Software Foundation.
9
 *
10
 * This code is distributed in the hope that it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * version 2 for more details (a copy is included in the LICENSE file that
14
 * accompanied this code).
15
 *
16
 * You should have received a copy of the GNU General Public License version
17
 * 2 along with this work; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
 *
20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
 * or visit www.oracle.com if you need additional information or have any
22
 * questions.
23
 *
24
 */
25

26
// no precompiled headers
27
#include "classfile/vmSymbols.hpp"
28
#include "code/vtableStubs.hpp"
29
#include "compiler/compileBroker.hpp"
30
#include "interpreter/interpreter.hpp"
31
#include "jvm.h"
32
#include "jvmtifiles/jvmti.h"
33
#include "libperfstat_aix.hpp"
34
#include "libodm_aix.hpp"
35
#include "loadlib_aix.hpp"
36
#include "logging/log.hpp"
37
#include "logging/logStream.hpp"
38
#include "memory/allocation.inline.hpp"
39
#include "misc_aix.hpp"
40
#include "oops/oop.inline.hpp"
41
#include "os_aix.inline.hpp"
42
#include "os_posix.hpp"
43
#include "porting_aix.hpp"
44
#include "prims/jniFastGetField.hpp"
45
#include "prims/jvm_misc.hpp"
46
#include "runtime/arguments.hpp"
47
#include "runtime/atomic.hpp"
48
#include "runtime/globals.hpp"
49
#include "runtime/globals_extension.hpp"
50
#include "runtime/interfaceSupport.inline.hpp"
51
#include "runtime/java.hpp"
52
#include "runtime/javaCalls.hpp"
53
#include "runtime/javaThread.hpp"
54
#include "runtime/mutexLocker.hpp"
55
#include "runtime/objectMonitor.hpp"
56
#include "runtime/os.hpp"
57
#include "runtime/osInfo.hpp"
58
#include "runtime/osThread.hpp"
59
#include "runtime/perfMemory.hpp"
60
#include "runtime/safefetch.hpp"
61
#include "runtime/sharedRuntime.hpp"
62
#include "runtime/statSampler.hpp"
63
#include "runtime/threadCritical.hpp"
64
#include "runtime/threads.hpp"
65
#include "runtime/timer.hpp"
66
#include "runtime/vm_version.hpp"
67
#include "services/attachListener.hpp"
68
#include "services/runtimeService.hpp"
69
#include "signals_posix.hpp"
70
#include "utilities/align.hpp"
71
#include "utilities/checkedCast.hpp"
72
#include "utilities/debug.hpp"
73
#include "utilities/decoder.hpp"
74
#include "utilities/defaultStream.hpp"
75
#include "utilities/events.hpp"
76
#include "utilities/growableArray.hpp"
77
#include "utilities/vmError.hpp"
78
#if INCLUDE_JFR
79
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
80
#endif
81

82
// put OS-includes here (sorted alphabetically)
83
#include <alloca.h>
84
#include <errno.h>
85
#include <fcntl.h>
86
#include <inttypes.h>
87
#include <poll.h>
88
#include <procinfo.h>
89
#include <pthread.h>
90
#include <pwd.h>
91
#include <semaphore.h>
92
#include <signal.h>
93
#include <stdint.h>
94
#include <stdio.h>
95
#include <string.h>
96
#include <unistd.h>
97
#include <sys/ioctl.h>
98
#include <sys/ipc.h>
99
#include <sys/mman.h>
100
// sys/mman.h defines MAP_ANON_64K beginning with AIX7.3 TL1
101
#ifndef MAP_ANON_64K
102
  #define MAP_ANON_64K 0x400
103
#else
104
  STATIC_ASSERT(MAP_ANON_64K == 0x400);
105
#endif
106
#include <sys/resource.h>
107
#include <sys/select.h>
108
#include <sys/shm.h>
109
#include <sys/socket.h>
110
#include <sys/stat.h>
111
#include <sys/sysinfo.h>
112
#include <sys/systemcfg.h>
113
#include <sys/time.h>
114
#include <sys/times.h>
115
#include <sys/types.h>
116
#include <sys/utsname.h>
117
#include <sys/vminfo.h>
118

119
#ifndef _LARGE_FILES
120
#error Hotspot on AIX must be compiled with -D_LARGE_FILES
121
#endif
122

123
// Missing prototypes for various system APIs.
124
extern "C"
125
int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t);
126

127
#if !defined(_AIXVERSION_610)
128
extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int);
129
extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int);
130
extern "C" int getargs(procsinfo*, int, char*, int);
131
#endif
132

133
#define MAX_PATH (2 * K)
134

135
// for timer info max values which include all bits
136
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
137
// for multipage initialization error analysis (in 'g_multipage_error')
138
#define ERROR_MP_OS_TOO_OLD                          100
139
#define ERROR_MP_EXTSHM_ACTIVE                       101
140
#define ERROR_MP_VMGETINFO_FAILED                    102
141
#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
142

143
// excerpts from sys/systemcfg.h that might be missing on older os levels
144
#ifndef PV_7
145
  #define PV_7 0x200000          /* Power PC 7 */
146
#endif
147
#ifndef PV_7_Compat
148
  #define PV_7_Compat 0x208000   /* Power PC 7 */
149
#endif
150
#ifndef PV_8
151
  #define PV_8 0x300000          /* Power PC 8 */
152
#endif
153
#ifndef PV_8_Compat
154
  #define PV_8_Compat 0x308000   /* Power PC 8 */
155
#endif
156
#ifndef PV_9
157
  #define PV_9 0x400000          /* Power PC 9 */
158
#endif
159
#ifndef PV_9_Compat
160
  #define PV_9_Compat  0x408000  /* Power PC 9 */
161
#endif
162
#ifndef PV_10
163
  #define PV_10 0x500000          /* Power PC 10 */
164
#endif
165
#ifndef PV_10_Compat
166
  #define PV_10_Compat  0x508000  /* Power PC 10 */
167
#endif
168

169
static address resolve_function_descriptor_to_code_pointer(address p);
170

171
static void vmembk_print_on(outputStream* os);
172

173
////////////////////////////////////////////////////////////////////////////////
174
// global variables (for a description see os_aix.hpp)
175

176
julong    os::Aix::_physical_memory = 0;
177

178
pthread_t os::Aix::_main_thread = ((pthread_t)0);
179

180
// 0 = uninitialized, otherwise 32 bit number:
181
//  0xVVRRTTSS
182
//  VV - major version
183
//  RR - minor version
184
//  TT - tech level, if known, 0 otherwise
185
//  SS - service pack, if known, 0 otherwise
186
uint32_t  os::Aix::_os_version = 0;
187

188
// -1 = uninitialized, 0 - no, 1 - yes
189
int       os::Aix::_xpg_sus_mode = -1;
190

191
// -1 = uninitialized, 0 - no, 1 - yes
192
int       os::Aix::_extshm = -1;
193

194
////////////////////////////////////////////////////////////////////////////////
195
// local variables
196

197
static volatile jlong max_real_time = 0;
198

199
// Process break recorded at startup.
200
static address g_brk_at_startup = nullptr;
201

202
// This describes the state of multipage support of the underlying
203
// OS. Note that this is of no interest to the outsize world and
204
// therefore should not be defined in AIX class.
205
//
206
// AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The
207
// latter two (16M "large" resp. 16G "huge" pages) require special
208
// setup and are normally not available.
209
//
210
// AIX supports multiple page sizes per process, for:
211
//  - Stack (of the primordial thread, so not relevant for us)
212
//  - Data - data, bss, heap, for us also pthread stacks
213
//  - Text - text code
214
//  - shared memory
215
//
216
// Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...)
217
// and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...).
218
//
219
// For shared memory, page size can be set dynamically via
220
// shmctl(). Different shared memory regions can have different page
221
// sizes.
222
//
223
// More information can be found at AIBM info center:
224
//   http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm
225
//
226
static struct {
227
  size_t pagesize;             // sysconf _SC_PAGESIZE (4K)
228
  size_t datapsize;            // default data page size (LDR_CNTRL DATAPSIZE)
229
  size_t shmpsize;             // default shared memory page size (LDR_CNTRL SHMPSIZE)
230
  size_t pthr_stack_pagesize;  // stack page size of pthread threads
231
  size_t textpsize;            // default text page size (LDR_CNTRL STACKPSIZE)
232
  bool can_use_64K_pages;      // True if we can alloc 64K pages dynamically with Sys V shm.
233
  bool can_use_16M_pages;      // True if we can alloc 16M pages dynamically with Sys V shm.
234
  bool can_use_64K_mmap_pages; // True if we can alloc 64K pages dynamically with mmap.
235
  int error;                   // Error describing if something went wrong at multipage init.
236
} g_multipage_support = {
237
  (size_t) -1,
238
  (size_t) -1,
239
  (size_t) -1,
240
  (size_t) -1,
241
  (size_t) -1,
242
  false, false, false,
243
  0
244
};
245

246
// We must not accidentally allocate memory close to the BRK - even if
247
// that would work - because then we prevent the BRK segment from
248
// growing which may result in a malloc OOM even though there is
249
// enough memory. The problem only arises if we shmat() or mmap() at
250
// a specific wish address, e.g. to place the heap in a
251
// compressed-oops-friendly way.
252
static bool is_close_to_brk(address a) {
253
  assert0(g_brk_at_startup != nullptr);
254
  if (a >= g_brk_at_startup &&
255
      a < (g_brk_at_startup + MaxExpectedDataSegmentSize)) {
256
    return true;
257
  }
258
  return false;
259
}
260

261
julong os::free_memory() {
262
  return Aix::available_memory();
263
}
264

265
julong os::available_memory() {
266
  return Aix::available_memory();
267
}
268

269
julong os::Aix::available_memory() {
270
  os::Aix::meminfo_t mi;
271
  if (os::Aix::get_meminfo(&mi)) {
272
    return mi.real_free;
273
  } else {
274
    return ULONG_MAX;
275
  }
276
}
277

278
jlong os::total_swap_space() {
279
  perfstat_memory_total_t memory_info;
280
  if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
281
    return -1;
282
  }
283
  return (jlong)(memory_info.pgsp_total * 4 * K);
284
}
285

286
jlong os::free_swap_space() {
287
  perfstat_memory_total_t memory_info;
288
  if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
289
    return -1;
290
  }
291
  return (jlong)(memory_info.pgsp_free * 4 * K);
292
}
293

294
julong os::physical_memory() {
295
  return Aix::physical_memory();
296
}
297

298
size_t os::rss() { return (size_t)0; }
299

300
// Cpu architecture string
301
#if defined(PPC32)
302
static char cpu_arch[] = "ppc";
303
#elif defined(PPC64)
304
static char cpu_arch[] = "ppc64";
305
#else
306
#error Add appropriate cpu_arch setting
307
#endif
308

309
// Given an address, returns the size of the page backing that address.
310
size_t os::Aix::query_pagesize(void* addr) {
311
  vm_page_info pi;
312
  pi.addr = (uint64_t)addr;
313
  if (::vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) {
314
    return pi.pagesize;
315
  } else {
316
    log_warning(pagesize)("vmgetinfo(VM_PAGE_INFO) failed (errno: %d)", errno);
317
    assert(false, "vmgetinfo failed to retrieve page size");
318
    return 4*K;
319
  }
320
}
321

322
void os::Aix::initialize_system_info() {
323

324
  // Get the number of online(logical) cpus instead of configured.
325
  os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN);
326
  assert(_processor_count > 0, "_processor_count must be > 0");
327

328
  // Retrieve total physical storage.
329
  os::Aix::meminfo_t mi;
330
  if (!os::Aix::get_meminfo(&mi)) {
331
    assert(false, "os::Aix::get_meminfo failed.");
332
  }
333
  _physical_memory = (julong) mi.real_total;
334
}
335

336
// Helper function for tracing page sizes.
337
static const char* describe_pagesize(size_t pagesize) {
338
  switch (pagesize) {
339
    case 4*K : return "4K";
340
    case 64*K: return "64K";
341
    case 16*M: return "16M";
342
    case 16*G: return "16G";
343
    default:
344
      assert(false, "surprise");
345
      return "??";
346
  }
347
}
348

349
// Probe OS for multipage support.
350
// Will fill the global g_multipage_support structure.
351
// Must be called before calling os::large_page_init().
352
static void query_multipage_support() {
353

354
  guarantee(g_multipage_support.pagesize == (size_t)-1,
355
            "do not call twice");
356

357
  g_multipage_support.pagesize = ::sysconf(_SC_PAGESIZE);
358

359
  // This really would surprise me.
360
  assert(g_multipage_support.pagesize == 4*K, "surprise!");
361

362
  // Query default data page size (default page size for C-Heap, pthread stacks and .bss).
363
  // Default data page size is defined either by linker options (-bdatapsize)
364
  // or by environment variable LDR_CNTRL (suboption DATAPSIZE). If none is given,
365
  // default should be 4K.
366
  {
367
    void* p = ::malloc(16*M);
368
    g_multipage_support.datapsize = os::Aix::query_pagesize(p);
369
    ::free(p);
370
  }
371

372
  // Query default shm page size (LDR_CNTRL SHMPSIZE).
373
  // Note that this is pure curiosity. We do not rely on default page size but set
374
  // our own page size after allocated.
375
  {
376
    const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR);
377
    assert(shmid != -1, "shmget failed");
378
    if (shmid != -1) {
379
      void* p = ::shmat(shmid, nullptr, 0);
380
      ::shmctl(shmid, IPC_RMID, nullptr);
381
      assert(p != (void*) -1, "shmat failed");
382
      if (p != (void*) -1) {
383
        g_multipage_support.shmpsize = os::Aix::query_pagesize(p);
384
        ::shmdt(p);
385
      }
386
    }
387
  }
388

389
  // Before querying the stack page size, make sure we are not running as primordial
390
  // thread (because primordial thread's stack may have different page size than
391
  // pthread thread stacks). Running a VM on the primordial thread won't work for a
392
  // number of reasons so we may just as well guarantee it here.
393
  guarantee0(!os::is_primordial_thread());
394

395
  // Query pthread stack page size. Should be the same as data page size because
396
  // pthread stacks are allocated from C-Heap.
397
  {
398
    int dummy = 0;
399
    g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy);
400
  }
401

402
  // Query default text page size (LDR_CNTRL TEXTPSIZE).
403
  {
404
    address any_function =
405
      resolve_function_descriptor_to_code_pointer((address)describe_pagesize);
406
    g_multipage_support.textpsize = os::Aix::query_pagesize(any_function);
407
  }
408

409
  // Now check which page sizes the OS claims it supports, and of those, which actually can be used.
410
  {
411
    const int MAX_PAGE_SIZES = 4;
412
    psize_t sizes[MAX_PAGE_SIZES];
413
    const int num_psizes = ::vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES);
414
    if (num_psizes == -1) {
415
      log_warning(pagesize)("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d), disabling multipage support.", errno);
416
      g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED;
417
      goto query_multipage_support_end;
418
    }
419
    guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed.");
420
    assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?");
421
    log_info(pagesize)("vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes);
422
    for (int i = 0; i < num_psizes; i ++) {
423
      trcVerbose(" %s ", describe_pagesize(sizes[i]));
424
    }
425

426
    // Can we use 64K, 16M pages?
427
    for (int i = 0; i < num_psizes; i ++) {
428
      const size_t pagesize = sizes[i];
429
      if (pagesize != 64*K && pagesize != 16*M) {
430
        continue;
431
      }
432
      bool can_use = false;
433
      trcVerbose("Probing support for %s pages...", describe_pagesize(pagesize));
434
      const int shmid = ::shmget(IPC_PRIVATE, pagesize,
435
        IPC_CREAT | S_IRUSR | S_IWUSR);
436
      assert(shmid != -1, "shmget failed");
437
      if (shmid != -1) {
438
        // Try to set pagesize.
439
        struct shmid_ds shm_buf = { };
440
        shm_buf.shm_pagesize = pagesize;
441
        if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {
442
          const int en = errno;
443
          ::shmctl(shmid, IPC_RMID, nullptr); // As early as possible!
444
          log_warning(pagesize)("shmctl(SHM_PAGESIZE) failed with errno=%d", errno);
445
        } else {
446
          // Attach and double check pageisze.
447
          void* p = ::shmat(shmid, nullptr, 0);
448
          ::shmctl(shmid, IPC_RMID, nullptr); // As early as possible!
449
          assert(p != (void*) -1, "shmat failed");
450
          if (p != (void*) -1) {
451
            const size_t real_pagesize = os::Aix::query_pagesize(p);
452
            if (real_pagesize != pagesize) {
453
              log_warning(pagesize)("real page size (" SIZE_FORMAT_X ") differs.", real_pagesize);
454
            } else {
455
              can_use = true;
456
            }
457
            ::shmdt(p);
458
          }
459
        }
460
      }
461
      trcVerbose("Can use: %s", (can_use ? "yes" : "no"));
462
      if (pagesize == 64*K) {
463
        g_multipage_support.can_use_64K_pages = can_use;
464
      } else if (pagesize == 16*M) {
465
        g_multipage_support.can_use_16M_pages = can_use;
466
      }
467
    }
468

469
    // Can we use mmap with 64K pages? (Should be available with AIX7.3 TL1)
470
    {
471
      void* p = mmap(NULL, 64*K, PROT_READ | PROT_WRITE, MAP_ANON_64K | MAP_ANONYMOUS | MAP_SHARED, -1, 0);
472
      assert(p != (void*) -1, "mmap failed");
473
      if (p != (void*) -1) {
474
        g_multipage_support.can_use_64K_mmap_pages = (64*K == os::Aix::query_pagesize(p));
475
        munmap(p, 64*K);
476
      }
477
    }
478

479
  } // end: check which pages can be used for shared memory
480

481
query_multipage_support_end:
482

483
  trcVerbose("base page size (sysconf _SC_PAGESIZE): %s",
484
      describe_pagesize(g_multipage_support.pagesize));
485
  trcVerbose("Data page size (C-Heap, bss, etc): %s",
486
      describe_pagesize(g_multipage_support.datapsize));
487
  trcVerbose("Text page size: %s",
488
      describe_pagesize(g_multipage_support.textpsize));
489
  trcVerbose("Thread stack page size (pthread): %s",
490
      describe_pagesize(g_multipage_support.pthr_stack_pagesize));
491
  trcVerbose("Can use 64K pages with mmap memory: %s",
492
      (g_multipage_support.can_use_64K_mmap_pages ? "yes" :"no"));
493
  trcVerbose("Default shared memory page size: %s",
494
      describe_pagesize(g_multipage_support.shmpsize));
495
  trcVerbose("Can use 64K pages dynamically with shared memory: %s",
496
      (g_multipage_support.can_use_64K_pages ? "yes" :"no"));
497
  trcVerbose("Can use 16M pages dynamically with shared memory: %s",
498
      (g_multipage_support.can_use_16M_pages ? "yes" :"no"));
499
  trcVerbose("Multipage error details: %d",
500
      g_multipage_support.error);
501

502
  // sanity checks
503
  assert0(g_multipage_support.pagesize == 4*K);
504
  assert0(g_multipage_support.datapsize == 4*K || g_multipage_support.datapsize == 64*K);
505
  assert0(g_multipage_support.textpsize == 4*K || g_multipage_support.textpsize == 64*K);
506
  assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize);
507
  assert0(g_multipage_support.shmpsize == 4*K || g_multipage_support.shmpsize == 64*K);
508

509
}
510

511
void os::init_system_properties_values() {
512

513
#ifndef OVERRIDE_LIBPATH
514
  #define DEFAULT_LIBPATH "/lib:/usr/lib"
515
#else
516
  #define DEFAULT_LIBPATH OVERRIDE_LIBPATH
517
#endif
518
#define EXTENSIONS_DIR  "/lib/ext"
519

520
  // Buffer that fits several snprintfs.
521
  // Note that the space for the trailing null is provided
522
  // by the nulls included by the sizeof operator.
523
  const size_t bufsize =
524
    MAX2((size_t)MAXPATHLEN,  // For dll_dir & friends.
525
         (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR)); // extensions dir
526
  char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
527

528
  // sysclasspath, java_home, dll_dir
529
  {
530
    char *pslash;
531
    os::jvm_path(buf, bufsize);
532

533
    // Found the full path to libjvm.so.
534
    // Now cut the path to <java_home>/jre if we can.
535
    pslash = strrchr(buf, '/');
536
    if (pslash != nullptr) {
537
      *pslash = '\0';            // Get rid of /libjvm.so.
538
    }
539
    pslash = strrchr(buf, '/');
540
    if (pslash != nullptr) {
541
      *pslash = '\0';            // Get rid of /{client|server|hotspot}.
542
    }
543
    Arguments::set_dll_dir(buf);
544

545
    if (pslash != nullptr) {
546
      pslash = strrchr(buf, '/');
547
      if (pslash != nullptr) {
548
        *pslash = '\0';        // Get rid of /lib.
549
      }
550
    }
551
    Arguments::set_java_home(buf);
552
    if (!set_boot_path('/', ':')) {
553
      vm_exit_during_initialization("Failed setting boot class path.", nullptr);
554
    }
555
  }
556

557
  // Where to look for native libraries.
558

559
  // On Aix we get the user setting of LIBPATH.
560
  // Eventually, all the library path setting will be done here.
561
  // Get the user setting of LIBPATH.
562
  const char *v = ::getenv("LIBPATH");
563
  const char *v_colon = ":";
564
  if (v == nullptr) { v = ""; v_colon = ""; }
565

566
  // Concatenate user and invariant part of ld_library_path.
567
  // That's +1 for the colon and +1 for the trailing '\0'.
568
  size_t pathsize = strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1;
569
  char *ld_library_path = NEW_C_HEAP_ARRAY(char, pathsize, mtInternal);
570
  os::snprintf_checked(ld_library_path, pathsize, "%s%s" DEFAULT_LIBPATH, v, v_colon);
571
  Arguments::set_library_path(ld_library_path);
572
  FREE_C_HEAP_ARRAY(char, ld_library_path);
573

574
  // Extensions directories.
575
  os::snprintf_checked(buf, bufsize, "%s" EXTENSIONS_DIR, Arguments::get_java_home());
576
  Arguments::set_ext_dirs(buf);
577

578
  FREE_C_HEAP_ARRAY(char, buf);
579

580
#undef DEFAULT_LIBPATH
581
#undef EXTENSIONS_DIR
582
}
583

584
// retrieve memory information.
585
// Returns false if something went wrong;
586
// content of pmi undefined in this case.
587
bool os::Aix::get_meminfo(meminfo_t* pmi) {
588

589
  assert(pmi, "get_meminfo: invalid parameter");
590
  memset(pmi, 0, sizeof(meminfo_t));
591

592
  // dynamically loaded perfstat library is used to retrieve memory statistics
593
  perfstat_memory_total_t psmt;
594
  memset (&psmt, '\0', sizeof(psmt));
595
  const int rc = libperfstat::perfstat_memory_total(nullptr, &psmt, sizeof(psmt), 1);
596
  if (rc == -1) {
597
    log_warning(os)("perfstat_memory_total() failed (errno=%d)", errno);
598
    assert(0, "perfstat_memory_total() failed");
599
    return false;
600
  }
601

602
  assert(rc == 1, "perfstat_memory_total() - weird return code");
603

604
  // The fields of perfstat_memory_total_t:
605
  // u_longlong_t virt_total         Total virtual memory (in 4 KB pages).
606
  // u_longlong_t real_total         Total real memory (in 4 KB pages).
607
  // u_longlong_t real_free          Free real memory (in 4 KB pages).
608
  // u_longlong_t pgsp_total         Total paging space (in 4 KB pages).
609
  // u_longlong_t pgsp_free          Free paging space (in 4 KB pages).
610
  pmi->virt_total = psmt.virt_total * 4096;
611
  pmi->real_total = psmt.real_total * 4096;
612
  pmi->real_free = psmt.real_free * 4096;
613
  pmi->pgsp_total = psmt.pgsp_total * 4096;
614
  pmi->pgsp_free = psmt.pgsp_free * 4096;
615

616
  return true;
617
} // end os::Aix::get_meminfo
618

619
//////////////////////////////////////////////////////////////////////////////
620
// create new thread
621

622
// Thread start routine for all newly created threads
623
static void *thread_native_entry(Thread *thread) {
624

625
  thread->record_stack_base_and_size();
626

627
  const pthread_t pthread_id = ::pthread_self();
628
  const tid_t kernel_thread_id = ::thread_self();
629

630
  LogTarget(Info, os, thread) lt;
631
  if (lt.is_enabled()) {
632
    address low_address = thread->stack_end();
633
    address high_address = thread->stack_base();
634
    lt.print("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT
635
             ", stack [" PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k using %luk pages)).",
636
             os::current_thread_id(), (uintx) kernel_thread_id, p2i(low_address), p2i(high_address),
637
             (high_address - low_address) / K, os::Aix::query_pagesize(low_address) / K);
638
  }
639

640
  // Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()
641
  // by the pthread library). In rare cases, this may not be the case, e.g. when third-party
642
  // tools hook pthread_create(). In this case, we may run into problems establishing
643
  // guard pages on those stacks, because the stacks may reside in memory which is not
644
  // protectable (shmated).
645
  if (thread->stack_base() > ::sbrk(0)) {
646
    log_warning(os, thread)("Thread stack not in data segment.");
647
  }
648

649
  // Try to randomize the cache line index of hot stack frames.
650
  // This helps when threads of the same stack traces evict each other's
651
  // cache lines. The threads can be either from the same JVM instance, or
652
  // from different JVM instances. The benefit is especially true for
653
  // processors with hyperthreading technology.
654

655
  static int counter = 0;
656
  int pid = os::current_process_id();
657
  alloca(((pid ^ counter++) & 7) * 128);
658

659
  thread->initialize_thread_current();
660

661
  OSThread* osthread = thread->osthread();
662

663
  // Thread_id is pthread id.
664
  osthread->set_thread_id(pthread_id);
665

666
  // .. but keep kernel thread id too for diagnostics
667
  osthread->set_kernel_thread_id(kernel_thread_id);
668

669
  // Initialize signal mask for this thread.
670
  PosixSignals::hotspot_sigmask(thread);
671

672
  // Initialize floating point control register.
673
  os::Aix::init_thread_fpu_state();
674

675
  assert(osthread->get_state() == RUNNABLE, "invalid os thread state");
676

677
  // Call one more level start routine.
678
  thread->call_run();
679

680
  // Note: at this point the thread object may already have deleted itself.
681
  // Prevent dereferencing it from here on out.
682
  thread = nullptr;
683

684
  log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
685
    os::current_thread_id(), (uintx) kernel_thread_id);
686

687
  return 0;
688
}
689

690
bool os::create_thread(Thread* thread, ThreadType thr_type,
691
                       size_t req_stack_size) {
692

693
  assert(thread->osthread() == nullptr, "caller responsible");
694

695
  // Allocate the OSThread object.
696
  OSThread* osthread = new (std::nothrow) OSThread();
697
  if (osthread == nullptr) {
698
    return false;
699
  }
700

701
  // Set the correct thread state.
702
  osthread->set_thread_type(thr_type);
703

704
  // Initial state is ALLOCATED but not INITIALIZED
705
  osthread->set_state(ALLOCATED);
706

707
  thread->set_osthread(osthread);
708

709
  // Init thread attributes.
710
  pthread_attr_t attr;
711
  int rslt = pthread_attr_init(&attr);
712
  guarantee(rslt == 0, "pthread_attr_init has to return 0");
713
  guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");
714

715
  // Make sure we run in 1:1 kernel-user-thread mode.
716
  guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???");
717
  guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???");
718

719
  // Start in suspended state, and in os::thread_start, wake the thread up.
720
  guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");
721

722
  // Calculate stack size if it's not specified by caller.
723
  size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
724

725
  // JDK-8187028: It was observed that on some configurations (4K backed thread stacks)
726
  // the real thread stack size may be smaller than the requested stack size, by as much as 64K.
727
  // This very much looks like a pthread lib error. As a workaround, increase the stack size
728
  // by 64K for small thread stacks (arbitrarily chosen to be < 4MB)
729
  if (stack_size < 4096 * K) {
730
    stack_size += 64 * K;
731
  }
732

733
  // On Aix, pthread_attr_setstacksize fails with huge values and leaves the
734
  // thread size in attr unchanged. If this is the minimal stack size as set
735
  // by pthread_attr_init this leads to crashes after thread creation. E.g. the
736
  // guard pages might not fit on the tiny stack created.
737
  int ret = pthread_attr_setstacksize(&attr, stack_size);
738
  if (ret != 0) {
739
    log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k",
740
                            (thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "),
741
                            stack_size / K);
742
    thread->set_osthread(nullptr);
743
    delete osthread;
744
    pthread_attr_destroy(&attr);
745
    return false;
746
  }
747

748
  // Save some cycles and a page by disabling OS guard pages where we have our own
749
  // VM guard pages (in java threads). For other threads, keep system default guard
750
  // pages in place.
751
  if (thr_type == java_thread || thr_type == compiler_thread) {
752
    ret = pthread_attr_setguardsize(&attr, 0);
753
  }
754

755
  ResourceMark rm;
756
  pthread_t tid = 0;
757

758
  if (ret == 0) {
759
    int limit = 3;
760
    do {
761
      ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
762
    } while (ret == EAGAIN && limit-- > 0);
763
  }
764

765
  if (ret == 0) {
766
    char buf[64];
767
    log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
768
                         thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
769
  } else {
770
    char buf[64];
771
    log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%d=%s) for attributes: %s.",
772
                            thread->name(), ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
773
    // Log some OS information which might explain why creating the thread failed.
774
    log_warning(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
775
    log_warning(os, thread)("Checking JVM parameter MaxExpectedDataSegmentSize (currently " SIZE_FORMAT "k)  might be helpful", MaxExpectedDataSegmentSize/K);
776
    LogStream st(Log(os, thread)::info());
777
    os::Posix::print_rlimit_info(&st);
778
    os::print_memory_info(&st);
779
  }
780

781
  pthread_attr_destroy(&attr);
782

783
  if (ret != 0) {
784
    // Need to clean up stuff we've allocated so far.
785
    thread->set_osthread(nullptr);
786
    delete osthread;
787
    return false;
788
  }
789

790
  // OSThread::thread_id is the pthread id.
791
  osthread->set_thread_id(tid);
792

793
  return true;
794
}
795

796
/////////////////////////////////////////////////////////////////////////////
797
// attach existing thread
798

799
// bootstrap the main thread
800
bool os::create_main_thread(JavaThread* thread) {
801
  assert(os::Aix::_main_thread == pthread_self(), "should be called inside main thread");
802
  return create_attached_thread(thread);
803
}
804

805
bool os::create_attached_thread(JavaThread* thread) {
806
#ifdef ASSERT
807
    thread->verify_not_published();
808
#endif
809

810
  // Allocate the OSThread object
811
  OSThread* osthread = new (std::nothrow) OSThread();
812

813
  if (osthread == nullptr) {
814
    return false;
815
  }
816

817
  const pthread_t pthread_id = ::pthread_self();
818
  const tid_t kernel_thread_id = ::thread_self();
819

820
  // OSThread::thread_id is the pthread id.
821
  osthread->set_thread_id(pthread_id);
822

823
  // .. but keep kernel thread id too for diagnostics
824
  osthread->set_kernel_thread_id(kernel_thread_id);
825

826
  // initialize floating point control register
827
  os::Aix::init_thread_fpu_state();
828

829
  // Initial thread state is RUNNABLE
830
  osthread->set_state(RUNNABLE);
831

832
  thread->set_osthread(osthread);
833

834
  if (UseNUMA) {
835
    int lgrp_id = os::numa_get_group_id();
836
    if (lgrp_id != -1) {
837
      thread->set_lgrp_id(lgrp_id);
838
    }
839
  }
840

841
  // initialize signal mask for this thread
842
  // and save the caller's signal mask
843
  PosixSignals::hotspot_sigmask(thread);
844

845
  log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread  id: " UINTX_FORMAT
846
                       ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).",
847
                       os::current_thread_id(), (uintx) kernel_thread_id,
848
                       p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K);
849

850
  return true;
851
}
852

853
void os::pd_start_thread(Thread* thread) {
854
  int status = pthread_continue_np(thread->osthread()->pthread_id());
855
  assert(status == 0, "thr_continue failed");
856
}
857

858
// Free OS resources related to the OSThread
859
void os::free_thread(OSThread* osthread) {
860
  assert(osthread != nullptr, "osthread not set");
861

862
  // We are told to free resources of the argument thread,
863
  // but we can only really operate on the current thread.
864
  assert(Thread::current()->osthread() == osthread,
865
         "os::free_thread but not current thread");
866

867
  // Restore caller's signal mask
868
  sigset_t sigmask = osthread->caller_sigmask();
869
  pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
870

871
  delete osthread;
872
}
873

874
////////////////////////////////////////////////////////////////////////////////
875
// time support
876

877
double os::elapsedVTime() {
878
  struct rusage usage;
879
  int retval = getrusage(RUSAGE_THREAD, &usage);
880
  if (retval == 0) {
881
    return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000);
882
  } else {
883
    // better than nothing, but not much
884
    return elapsedTime();
885
  }
886
}
887

888
// We use mread_real_time here.
889
// On AIX: If the CPU has a time register, the result will be RTC_POWER and
890
// it has to be converted to real time. AIX documentations suggests to do
891
// this unconditionally, so we do it.
892
//
893
// See: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/read_real_time.htm
894
//
895
jlong os::javaTimeNanos() {
896
  timebasestruct_t time;
897
  int rc = mread_real_time(&time, TIMEBASE_SZ);
898

899
  if (rc != RTC_POWER) {
900
    rc = time_base_to_time(&time, TIMEBASE_SZ);
901
    assert(rc != -1, "error calling time_base_to_time()");
902
  }
903
  return jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);
904
}
905

906
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
907
  info_ptr->max_value = ALL_64_BITS;
908
  // mread_real_time() is monotonic (see 'os::javaTimeNanos()')
909
  info_ptr->may_skip_backward = false;
910
  info_ptr->may_skip_forward = false;
911
  info_ptr->kind = JVMTI_TIMER_ELAPSED;    // elapsed not CPU time
912
}
913

914
intx os::current_thread_id() {
915
  return (intx)pthread_self();
916
}
917

918
int os::current_process_id() {
919
  return getpid();
920
}
921

922
// DLL functions
923

924
// This must be hard coded because it's the system's temporary
925
// directory not the java application's temp directory, ala java.io.tmpdir.
926
const char* os::get_temp_directory() { return "/tmp"; }
927

928
void os::prepare_native_symbols() {
929
  LoadedLibraries::reload();
930
}
931

932
// Check if addr is inside libjvm.so.
933
bool os::address_is_in_vm(address addr) {
934

935
  // Input could be a real pc or a function pointer literal. The latter
936
  // would be a function descriptor residing in the data segment of a module.
937
  loaded_module_t lm;
938
  if (LoadedLibraries::find_for_text_address(addr, &lm)) {
939
    return lm.is_in_vm;
940
  } else if (LoadedLibraries::find_for_data_address(addr, &lm)) {
941
    return lm.is_in_vm;
942
  } else {
943
    return false;
944
  }
945

946
}
947

948
// Resolve an AIX function descriptor literal to a code pointer.
949
// If the input is a valid code pointer to a text segment of a loaded module,
950
//   it is returned unchanged.
951
// If the input is a valid AIX function descriptor, it is resolved to the
952
//   code entry point.
953
// If the input is neither a valid function descriptor nor a valid code pointer,
954
//   null is returned.
955
static address resolve_function_descriptor_to_code_pointer(address p) {
956

957
  if (LoadedLibraries::find_for_text_address(p, nullptr)) {
958
    // It is a real code pointer.
959
    return p;
960
  } else if (LoadedLibraries::find_for_data_address(p, nullptr)) {
961
    // Pointer to data segment, potential function descriptor.
962
    address code_entry = (address)(((FunctionDescriptor*)p)->entry());
963
    if (LoadedLibraries::find_for_text_address(code_entry, nullptr)) {
964
      // It is a function descriptor.
965
      return code_entry;
966
    }
967
  }
968

969
  return nullptr;
970
}
971

972
bool os::dll_address_to_function_name(address addr, char *buf,
973
                                      int buflen, int *offset,
974
                                      bool demangle) {
975
  if (offset) {
976
    *offset = -1;
977
  }
978
  // Buf is not optional, but offset is optional.
979
  assert(buf != nullptr, "sanity check");
980
  buf[0] = '\0';
981

982
  // Resolve function ptr literals first.
983
  addr = resolve_function_descriptor_to_code_pointer(addr);
984
  if (!addr) {
985
    return false;
986
  }
987

988
  return AixSymbols::get_function_name(addr, buf, buflen, offset, nullptr, demangle);
989
}
990

991
bool os::dll_address_to_library_name(address addr, char* buf,
992
                                     int buflen, int* offset) {
993
  if (offset) {
994
    *offset = -1;
995
  }
996
  // Buf is not optional, but offset is optional.
997
  assert(buf != nullptr, "sanity check");
998
  buf[0] = '\0';
999

1000
  // Resolve function ptr literals first.
1001
  addr = resolve_function_descriptor_to_code_pointer(addr);
1002
  if (!addr) {
1003
    return false;
1004
  }
1005

1006
  address  base = nullptr;
1007
  if (!AixSymbols::get_module_name_and_base(addr, buf, buflen, &base)
1008
      || base == nullptr) {
1009
    return false;
1010
  }
1011
  assert(addr >= base && addr <= base + INT_MAX, "address not in library text range");
1012
  if (offset != nullptr) {
1013
    *offset = addr - base;
1014
  }
1015

1016
  return true;
1017
}
1018

1019
static void* dll_load_library(const char *filename, int *eno, char *ebuf, int ebuflen) {
1020

1021
  log_info(os)("attempting shared library load of %s", filename);
1022
  if (ebuf && ebuflen > 0) {
1023
    ebuf[0] = '\0';
1024
    ebuf[ebuflen - 1] = '\0';
1025
  }
1026

1027
  if (!filename || strlen(filename) == 0) {
1028
    if (ebuf != nullptr && ebuflen > 0) {
1029
      ::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1);
1030
    }
1031
    return nullptr;
1032
  }
1033

1034
  // RTLD_LAZY has currently the same behavior as RTLD_NOW
1035
  // The dl is loaded immediately with all its dependants.
1036
  int dflags = RTLD_LAZY;
1037
  // check for filename ending with ')', it indicates we want to load
1038
  // a MEMBER module that is a member of an archive.
1039
  int flen = strlen(filename);
1040
  if (flen > 0 && filename[flen - 1] == ')') {
1041
    dflags |= RTLD_MEMBER;
1042
  }
1043

1044
  void* result;
1045
  const char* error_report = nullptr;
1046
  JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
1047
  result = Aix_dlopen(filename, dflags, eno, &error_report);
1048
  if (result != nullptr) {
1049
    Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
1050
    // Reload dll cache. Don't do this in signal handling.
1051
    LoadedLibraries::reload();
1052
    log_info(os)("shared library load of %s was successful", filename);
1053
    return result;
1054
  } else {
1055
    // error analysis when dlopen fails
1056
    if (error_report == nullptr) {
1057
      error_report = "dlerror returned no error description";
1058
    }
1059
    if (ebuf != nullptr && ebuflen > 0) {
1060
      snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",
1061
               filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);
1062
    }
1063
    Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
1064
    log_info(os)("shared library load of %s failed, %s", filename, error_report);
1065
    JFR_ONLY(load_event.set_error_msg(error_report);)
1066
  }
1067
  return nullptr;
1068
}
1069
// Load library named <filename>
1070
// If filename matches <name>.so, and loading fails, repeat with <name>.a.
1071
void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
1072
  void* result = nullptr;
1073
  char* const file_path = strdup(filename);
1074
  char* const pointer_to_dot = strrchr(file_path, '.');
1075
  const char old_extension[] = ".so";
1076
  const char new_extension[] = ".a";
1077
  STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension));
1078
  // First try to load the existing file.
1079
  int eno=0;
1080
  result = dll_load_library(filename, &eno, ebuf, ebuflen);
1081
  // If the load fails,we try to reload by changing the extension to .a for .so files only.
1082
  // Shared object in .so format dont have braces, hence they get removed for archives with members.
1083
  if (result == nullptr && eno == ENOENT && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) {
1084
    snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension);
1085
    result = dll_load_library(file_path, &eno, ebuf, ebuflen);
1086
  }
1087
  FREE_C_HEAP_ARRAY(char, file_path);
1088
  return result;
1089
}
1090

1091
void os::print_dll_info(outputStream *st) {
1092
  st->print_cr("Dynamic libraries:");
1093
  LoadedLibraries::print(st);
1094
}
1095

1096
void os::get_summary_os_info(char* buf, size_t buflen) {
1097
  // There might be something more readable than uname results for AIX.
1098
  struct utsname name;
1099
  uname(&name);
1100
  snprintf(buf, buflen, "%s %s", name.release, name.version);
1101
}
1102

1103
int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
1104

1105
  if (!LoadedLibraries::for_each(callback, param)) {
1106
    return -1;
1107
  }
1108

1109
  return 0;
1110
}
1111

1112
void os::print_os_info_brief(outputStream* st) {
1113
  uint32_t ver = os::Aix::os_version();
1114
  st->print_cr("AIX kernel version %u.%u.%u.%u",
1115
               (ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
1116

1117
  os::Posix::print_uname_info(st);
1118

1119
  // Linux uses print_libversion_info(st); here.
1120
}
1121

1122
void os::print_os_info(outputStream* st) {
1123
  st->print_cr("OS:");
1124

1125
  os::Posix::print_uname_info(st);
1126

1127
  uint32_t ver = os::Aix::os_version();
1128
  st->print_cr("AIX kernel version %u.%u.%u.%u",
1129
               (ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
1130

1131
  os::Posix::print_uptime_info(st);
1132

1133
  os::Posix::print_rlimit_info(st);
1134

1135
  os::Posix::print_load_average(st);
1136

1137
  // _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
1138
  long tmax = sysconf(_SC_THREAD_THREADS_MAX);
1139
  st->print_cr("maximum #threads within a process:%ld", tmax);
1140

1141
  // print wpar info
1142
  libperfstat::wparinfo_t wi;
1143
  if (libperfstat::get_wparinfo(&wi)) {
1144
    st->print_cr("wpar info");
1145
    st->print_cr("name: %s", wi.name);
1146
    st->print_cr("id:   %d", wi.wpar_id);
1147
    st->print_cr("type: %s", (wi.app_wpar ? "application" : "system"));
1148
  }
1149

1150
  VM_Version::print_platform_virtualization_info(st);
1151
}
1152

1153
void os::print_memory_info(outputStream* st) {
1154

1155
  st->print_cr("Memory:");
1156

1157
  st->print_cr("  Base page size (sysconf _SC_PAGESIZE):  %s",
1158
    describe_pagesize(g_multipage_support.pagesize));
1159
  st->print_cr("  Data page size (C-Heap, bss, etc):      %s",
1160
    describe_pagesize(g_multipage_support.datapsize));
1161
  st->print_cr("  Text page size:                         %s",
1162
    describe_pagesize(g_multipage_support.textpsize));
1163
  st->print_cr("  Thread stack page size (pthread):       %s",
1164
    describe_pagesize(g_multipage_support.pthr_stack_pagesize));
1165
  st->print_cr("  Can use 64K pages with mmap memory:     %s",
1166
    (g_multipage_support.can_use_64K_mmap_pages ? "yes" :"no"));
1167
  st->print_cr("  Default shared memory page size:        %s",
1168
    describe_pagesize(g_multipage_support.shmpsize));
1169
  st->print_cr("  Can use 64K pages dynamically with shared memory:  %s",
1170
    (g_multipage_support.can_use_64K_pages ? "yes" :"no"));
1171
  st->print_cr("  Can use 16M pages dynamically with shared memory: %s",
1172
    (g_multipage_support.can_use_16M_pages ? "yes" :"no"));
1173
  st->print_cr("  Multipage error: %d",
1174
    g_multipage_support.error);
1175
  st->cr();
1176
  st->print_cr("  os::vm_page_size:       %s", describe_pagesize(os::vm_page_size()));
1177

1178
  // print out LDR_CNTRL because it affects the default page sizes
1179
  const char* const ldr_cntrl = ::getenv("LDR_CNTRL");
1180
  st->print_cr("  LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>");
1181

1182
  // Print out EXTSHM because it is an unsupported setting.
1183
  const char* const extshm = ::getenv("EXTSHM");
1184
  st->print_cr("  EXTSHM=%s.", extshm ? extshm : "<unset>");
1185
  if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) {
1186
    st->print_cr("  *** Unsupported! Please remove EXTSHM from your environment! ***");
1187
  }
1188

1189
  // Print out AIXTHREAD_GUARDPAGES because it affects the size of pthread stacks.
1190
  const char* const aixthread_guardpages = ::getenv("AIXTHREAD_GUARDPAGES");
1191
  st->print_cr("  AIXTHREAD_GUARDPAGES=%s.",
1192
      aixthread_guardpages ? aixthread_guardpages : "<unset>");
1193
  st->cr();
1194

1195
  os::Aix::meminfo_t mi;
1196
  if (os::Aix::get_meminfo(&mi)) {
1197
    st->print_cr("physical total : " SIZE_FORMAT, mi.real_total);
1198
    st->print_cr("physical free  : " SIZE_FORMAT, mi.real_free);
1199
    st->print_cr("swap total     : " SIZE_FORMAT, mi.pgsp_total);
1200
    st->print_cr("swap free      : " SIZE_FORMAT, mi.pgsp_free);
1201
  }
1202
  st->cr();
1203

1204
  // Print program break.
1205
  st->print_cr("Program break at VM startup: " PTR_FORMAT ".", p2i(g_brk_at_startup));
1206
  address brk_now = (address)::sbrk(0);
1207
  if (brk_now != (address)-1) {
1208
    st->print_cr("Program break now          : " PTR_FORMAT " (distance: " SIZE_FORMAT "k).",
1209
                 p2i(brk_now), (size_t)((brk_now - g_brk_at_startup) / K));
1210
  }
1211
  st->print_cr("MaxExpectedDataSegmentSize    : " SIZE_FORMAT "k.", MaxExpectedDataSegmentSize / K);
1212
  st->cr();
1213

1214
  // Print segments allocated with os::reserve_memory.
1215
  st->print_cr("internal virtual memory regions used by vm:");
1216
  vmembk_print_on(st);
1217
}
1218

1219
// Get a string for the cpuinfo that is a summary of the cpu type
1220
void os::get_summary_cpu_info(char* buf, size_t buflen) {
1221
  // read _system_configuration.version
1222
  switch (_system_configuration.version) {
1223
  case PV_10:
1224
    strncpy(buf, "Power PC 10", buflen);
1225
    break;
1226
  case PV_9:
1227
    strncpy(buf, "Power PC 9", buflen);
1228
    break;
1229
  case PV_8:
1230
    strncpy(buf, "Power PC 8", buflen);
1231
    break;
1232
  case PV_7:
1233
    strncpy(buf, "Power PC 7", buflen);
1234
    break;
1235
  case PV_6_1:
1236
    strncpy(buf, "Power PC 6 DD1.x", buflen);
1237
    break;
1238
  case PV_6:
1239
    strncpy(buf, "Power PC 6", buflen);
1240
    break;
1241
  case PV_5:
1242
    strncpy(buf, "Power PC 5", buflen);
1243
    break;
1244
  case PV_5_2:
1245
    strncpy(buf, "Power PC 5_2", buflen);
1246
    break;
1247
  case PV_5_3:
1248
    strncpy(buf, "Power PC 5_3", buflen);
1249
    break;
1250
  case PV_5_Compat:
1251
    strncpy(buf, "PV_5_Compat", buflen);
1252
    break;
1253
  case PV_6_Compat:
1254
    strncpy(buf, "PV_6_Compat", buflen);
1255
    break;
1256
  case PV_7_Compat:
1257
    strncpy(buf, "PV_7_Compat", buflen);
1258
    break;
1259
  case PV_8_Compat:
1260
    strncpy(buf, "PV_8_Compat", buflen);
1261
    break;
1262
  case PV_9_Compat:
1263
    strncpy(buf, "PV_9_Compat", buflen);
1264
    break;
1265
  case PV_10_Compat:
1266
    strncpy(buf, "PV_10_Compat", buflen);
1267
    break;
1268
  default:
1269
    strncpy(buf, "unknown", buflen);
1270
  }
1271
}
1272

1273
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
1274
  // Nothing to do beyond of what os::print_cpu_info() does.
1275
}
1276

1277
static char saved_jvm_path[MAXPATHLEN] = {0};
1278

1279
// Find the full path to the current module, libjvm.so.
1280
void os::jvm_path(char *buf, jint buflen) {
1281
  // Error checking.
1282
  if (buflen < MAXPATHLEN) {
1283
    assert(false, "must use a large-enough buffer");
1284
    buf[0] = '\0';
1285
    return;
1286
  }
1287
  // Lazy resolve the path to current module.
1288
  if (saved_jvm_path[0] != 0) {
1289
    strcpy(buf, saved_jvm_path);
1290
    return;
1291
  }
1292

1293
  Dl_info dlinfo;
1294
  int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
1295
  assert(ret != 0, "cannot locate libjvm");
1296
  char* rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);
1297
  assert(rp != nullptr, "error in realpath(): maybe the 'path' argument is too long?");
1298

1299
  if (Arguments::sun_java_launcher_is_altjvm()) {
1300
    // Support for the java launcher's '-XXaltjvm=<path>' option. Typical
1301
    // value for buf is "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.so".
1302
    // If "/jre/lib/" appears at the right place in the string, then
1303
    // assume we are installed in a JDK and we're done. Otherwise, check
1304
    // for a JAVA_HOME environment variable and fix up the path so it
1305
    // looks like libjvm.so is installed there (append a fake suffix
1306
    // hotspot/libjvm.so).
1307
    const char *p = buf + strlen(buf) - 1;
1308
    for (int count = 0; p > buf && count < 4; ++count) {
1309
      for (--p; p > buf && *p != '/'; --p)
1310
        /* empty */ ;
1311
    }
1312

1313
    if (strncmp(p, "/jre/lib/", 9) != 0) {
1314
      // Look for JAVA_HOME in the environment.
1315
      char* java_home_var = ::getenv("JAVA_HOME");
1316
      if (java_home_var != nullptr && java_home_var[0] != 0) {
1317
        char* jrelib_p;
1318
        int len;
1319

1320
        // Check the current module name "libjvm.so".
1321
        p = strrchr(buf, '/');
1322
        if (p == nullptr) {
1323
          return;
1324
        }
1325
        assert(strstr(p, "/libjvm") == p, "invalid library name");
1326

1327
        rp = os::Posix::realpath(java_home_var, buf, buflen);
1328
        if (rp == nullptr) {
1329
          return;
1330
        }
1331

1332
        // determine if this is a legacy image or modules image
1333
        // modules image doesn't have "jre" subdirectory
1334
        len = strlen(buf);
1335
        assert(len < buflen, "Ran out of buffer room");
1336
        jrelib_p = buf + len;
1337
        snprintf(jrelib_p, buflen-len, "/jre/lib");
1338
        if (0 != access(buf, F_OK)) {
1339
          snprintf(jrelib_p, buflen-len, "/lib");
1340
        }
1341

1342
        if (0 == access(buf, F_OK)) {
1343
          // Use current module name "libjvm.so"
1344
          len = strlen(buf);
1345
          snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
1346
        } else {
1347
          // Go back to path of .so
1348
          rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);
1349
          if (rp == nullptr) {
1350
            return;
1351
          }
1352
        }
1353
      }
1354
    }
1355
  }
1356

1357
  strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path));
1358
  saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0';
1359
}
1360

1361
////////////////////////////////////////////////////////////////////////////////
1362
// Virtual Memory
1363

1364
// We need to keep small simple bookkeeping for os::reserve_memory and friends.
1365

1366
#define VMEM_MAPPED  1
1367
#define VMEM_SHMATED 2
1368

1369
struct vmembk_t {
1370
  int type;         // 1 - mmap, 2 - shmat
1371
  char* addr;
1372
  size_t size;      // Real size, may be larger than usersize.
1373
  size_t pagesize;  // page size of area
1374
  vmembk_t* next;
1375

1376
  bool contains_addr(char* p) const {
1377
    return p >= addr && p < (addr + size);
1378
  }
1379

1380
  bool contains_range(char* p, size_t s) const {
1381
    return contains_addr(p) && contains_addr(p + s - 1);
1382
  }
1383

1384
  void print_on(outputStream* os) const {
1385
    os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (" UINTX_FORMAT
1386
      " bytes, %ld %s pages), %s",
1387
      p2i(addr), p2i(addr) + size - 1, size, size / pagesize, describe_pagesize(pagesize),
1388
      (type == VMEM_SHMATED ? "shmat" : "mmap")
1389
    );
1390
  }
1391

1392
  // Check that range is a sub range of memory block (or equal to memory block);
1393
  // also check that range is fully page aligned to the page size if the block.
1394
  void assert_is_valid_subrange(char* p, size_t s) const {
1395
    if (!contains_range(p, s)) {
1396
      fatal(RANGEFMT " is not a sub range of " RANGEFMT, RANGEFMTARGS(p, s),
1397
            RANGEFMTARGS(addr, size));
1398
    }
1399
    if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {
1400
      fatal("range " RANGEFMT " is not aligned to pagesize (%lu)",
1401
            RANGEFMTARGS(p, s), (unsigned long)pagesize);
1402
    }
1403
  }
1404
};
1405

1406
static struct {
1407
  vmembk_t* first;
1408
  MiscUtils::CritSect cs;
1409
} vmem;
1410

1411
static void vmembk_add(char* addr, size_t size, size_t pagesize, int type) {
1412
  vmembk_t* p = (vmembk_t*) ::malloc(sizeof(vmembk_t));
1413
  assert0(p);
1414
  if (p) {
1415
    MiscUtils::AutoCritSect lck(&vmem.cs);
1416
    p->addr = addr; p->size = size;
1417
    p->pagesize = pagesize;
1418
    p->type = type;
1419
    p->next = vmem.first;
1420
    vmem.first = p;
1421
  }
1422
}
1423

1424
static vmembk_t* vmembk_find(char* addr) {
1425
  MiscUtils::AutoCritSect lck(&vmem.cs);
1426
  for (vmembk_t* p = vmem.first; p; p = p->next) {
1427
    if (p->addr <= addr && (p->addr + p->size) > addr) {
1428
      return p;
1429
    }
1430
  }
1431
  return nullptr;
1432
}
1433

1434
static void vmembk_remove(vmembk_t* p0) {
1435
  MiscUtils::AutoCritSect lck(&vmem.cs);
1436
  assert0(p0);
1437
  assert0(vmem.first); // List should not be empty.
1438
  for (vmembk_t** pp = &(vmem.first); *pp; pp = &((*pp)->next)) {
1439
    if (*pp == p0) {
1440
      *pp = p0->next;
1441
      ::free(p0);
1442
      return;
1443
    }
1444
  }
1445
  assert0(false); // Not found?
1446
}
1447

1448
static void vmembk_print_on(outputStream* os) {
1449
  MiscUtils::AutoCritSect lck(&vmem.cs);
1450
  for (vmembk_t* vmi = vmem.first; vmi; vmi = vmi->next) {
1451
    vmi->print_on(os);
1452
    os->cr();
1453
  }
1454
}
1455

1456
// Reserve and attach a section of System V memory.
1457
// If <requested_addr> is not null, function will attempt to attach the memory at the given
1458
// address. Failing that, it will attach the memory anywhere.
1459
// If <requested_addr> is null, function will attach the memory anywhere.
1460
static char* reserve_shmated_memory (size_t bytes, char* requested_addr) {
1461

1462
  trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "
1463
    PTR_FORMAT "...", bytes, p2i(requested_addr));
1464

1465
  // We must prevent anyone from attaching too close to the
1466
  // BRK because that may cause malloc OOM.
1467
  if (requested_addr != nullptr && is_close_to_brk((address)requested_addr)) {
1468
    log_info(os, map)("Wish address " PTR_FORMAT
1469
                      " is too close to the BRK segment.",
1470
                      p2i(requested_addr));
1471
    // Since we treat an attach to the wrong address as an error later anyway,
1472
    // we return null here
1473
    return nullptr;
1474
  }
1475

1476
  // Align size of shm up to 64K to avoid errors if we later try to change the page size.
1477
  const size_t size = align_up(bytes, 64*K);
1478

1479
  // Reserve the shared segment.
1480
  int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR);
1481
  if (shmid == -1) {
1482
    ErrnoPreserver ep;
1483
    log_trace(os, map)("shmget(.., " UINTX_FORMAT ", ..) failed (errno=%s).",
1484
                       size, os::strerror(ep.saved_errno()));
1485
    return nullptr;
1486
  }
1487

1488
  // Important note:
1489
  // It is very important that we, upon leaving this function, do not leave a shm segment alive.
1490
  // We must right after attaching it remove it from the system. System V shm segments are global and
1491
  // survive the process.
1492
  // So, from here on: Do not assert, do not return, until we have called shmctl(IPC_RMID) (A).
1493

1494
  struct shmid_ds shmbuf;
1495
  memset(&shmbuf, 0, sizeof(shmbuf));
1496
  shmbuf.shm_pagesize = 64*K;
1497
  if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) != 0) {
1498
    assert(false,
1499
           "Failed to set page size (need " UINTX_FORMAT
1500
           " 64K pages) - shmctl failed. (errno=%s).",
1501
           size / (64 * K), os::strerror(os::get_last_error()));
1502
  }
1503

1504
  // Now attach the shared segment.
1505
  // Note that we deliberately *don't* pass SHM_RND. The contract of os::attempt_reserve_memory_at() -
1506
  // which invokes this function with a request address != nullptr - is to map at the specified address
1507
  // excactly, or to fail. If the caller passed us an address that is not usable (aka not a valid segment
1508
  // boundary), shmat should not round down the address, or think up a completely new one.
1509
  // (In places where this matters, e.g. when reserving the heap, we take care of passing segment-aligned
1510
  // addresses on Aix. See, e.g., ReservedHeapSpace.
1511
  char* const addr = (char*) shmat(shmid, requested_addr, 0);
1512
  const int errno_shmat = errno;
1513

1514
  // (A) Right after shmat and before handing shmat errors delete the shm segment.
1515
  if (::shmctl(shmid, IPC_RMID, nullptr) == -1) {
1516
    ErrnoPreserver ep;
1517
    log_trace(os, map)("shmctl(%u, IPC_RMID) failed (errno=%s)\n",
1518
                       shmid,
1519
                       os::strerror(ep.saved_errno()));
1520
    assert(false, "failed to remove shared memory segment!");
1521
  }
1522

1523
  // Handle shmat error. If we failed to attach, just return.
1524
  if (addr == (char*)-1) {
1525
    ErrnoPreserver ep;
1526
    log_trace(os, map)("Failed to attach segment at " PTR_FORMAT " (errno=%s).",
1527
                       p2i(requested_addr),
1528
                       os::strerror(ep.saved_errno()));
1529
    return nullptr;
1530
  }
1531

1532
  // Just for info: query the real page size. In case setting the page size did not
1533
  // work (see above), the system may have given us something other then 4K (LDR_CNTRL).
1534
  const size_t real_pagesize = os::Aix::query_pagesize(addr);
1535
  if (real_pagesize != (size_t)shmbuf.shm_pagesize) {
1536
    log_trace(os, map)("pagesize is, surprisingly, " SIZE_FORMAT,
1537
                       real_pagesize);
1538
  }
1539

1540
  if (addr) {
1541
    log_trace(os, map)("shm-allocated succeeded: " RANGEFMT
1542
                       " (" UINTX_FORMAT " %s pages)",
1543
                       RANGEFMTARGS(addr, size),
1544
                       size / real_pagesize,
1545
                       describe_pagesize(real_pagesize));
1546
  } else {
1547
    if (requested_addr != nullptr) {
1548
      log_trace(os, map)("shm-allocate failed: " RANGEFMT,
1549
                         RANGEFMTARGS(requested_addr, size));
1550
    } else {
1551
      log_trace(os, map)("failed to shm-allocate " UINTX_FORMAT
1552
                         " bytes at any address.",
1553
                         size);
1554
    }
1555
  }
1556

1557
  // book-keeping
1558
  vmembk_add(addr, size, real_pagesize, VMEM_SHMATED);
1559
  assert0(is_aligned_to(addr, os::vm_page_size()));
1560

1561
  return addr;
1562
}
1563

1564
static bool release_shmated_memory(char* addr, size_t size) {
1565

1566
  trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
1567
    p2i(addr), p2i(addr + size - 1));
1568

1569
  bool rc = false;
1570

1571
  // TODO: is there a way to verify shm size without doing bookkeeping?
1572
  if (::shmdt(addr) != 0) {
1573
    ErrnoPreserver ep;
1574
    log_trace(os, map)("shmdt failed: " RANGEFMT " errno=(%s)",
1575
                       RANGEFMTARGS(addr, size),
1576
                       os::strerror(ep.saved_errno()));
1577
  } else {
1578
    log_trace(os, map)("shmdt succeded: " RANGEFMT,
1579
                       RANGEFMTARGS(addr, size));
1580
    rc = true;
1581
  }
1582
  return rc;
1583
}
1584

1585
static bool uncommit_shmated_memory(char* addr, size_t size) {
1586
  trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
1587
    p2i(addr), p2i(addr + size - 1));
1588

1589
  const int rc = disclaim64(addr, size, DISCLAIM_ZEROMEM);
1590

1591
  if (rc != 0) {
1592
    ErrnoPreserver ep;
1593
    log_warning(os)("disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed, %s\n", p2i(addr), size, os::strerror(ep.saved_errno()));
1594
    return false;
1595
  }
1596
  return true;
1597
}
1598

1599
////////////////////////////////  mmap-based routines /////////////////////////////////
1600

1601
// Reserve memory via mmap.
1602
// If <requested_addr> is given, an attempt is made to attach at the given address.
1603
// Failing that, memory is allocated at any address.
1604
static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) {
1605
  trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT "...",
1606
    bytes, p2i(requested_addr));
1607

1608
  if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {
1609
    log_trace(os, map)("Wish address " PTR_FORMAT
1610
                       " not aligned to page boundary.",
1611
                       p2i(requested_addr));
1612
    return nullptr;
1613
  }
1614

1615
  // We must prevent anyone from attaching too close to the
1616
  // BRK because that may cause malloc OOM.
1617
  if (requested_addr != nullptr && is_close_to_brk((address)requested_addr)) {
1618
    log_trace(os, map)("Wish address " PTR_FORMAT
1619
                       " is too close to the BRK segment.",
1620
                       p2i(requested_addr));
1621
    // Since we treat an attach to the wrong address as an error later anyway,
1622
    // we return null here
1623
    return nullptr;
1624
  }
1625

1626
  // In 64K mode, we lie and claim the global page size (os::vm_page_size()) is 64K
1627
  //  (complicated story). This mostly works just fine since 64K is a multiple of the
1628
  //  actual 4K lowest page size. Only at a few seams light shines thru, e.g. when
1629
  //  calling mmap. mmap will return memory aligned to the lowest pages size - 4K -
1630
  //  so we must make sure - transparently - that the caller only ever sees 64K
1631
  //  aligned mapping start addresses.
1632
  const size_t alignment = os::vm_page_size();
1633

1634
  // Size shall always be a multiple of os::vm_page_size (esp. in 64K mode).
1635
  const size_t size = align_up(bytes, os::vm_page_size());
1636

1637
  // alignment: Allocate memory large enough to include an aligned range of the right size and
1638
  // cut off the leading and trailing waste pages.
1639
  assert0(alignment != 0 && is_aligned_to(alignment, os::vm_page_size())); // see above
1640
  const size_t extra_size = size + alignment;
1641

1642
  // Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to
1643
  // later use msync(MS_INVALIDATE) (see os::uncommit_memory).
1644
  int flags = MAP_ANONYMOUS | MAP_SHARED;
1645

1646
  if (os::vm_page_size() == 64*K && g_multipage_support.can_use_64K_mmap_pages) {
1647
    flags |= MAP_ANON_64K;
1648
  }
1649

1650
  // MAP_FIXED is needed to enforce requested_addr - manpage is vague about what
1651
  // it means if wishaddress is given but MAP_FIXED is not set.
1652
  //
1653
  // Important! Behaviour differs depending on whether SPEC1170 mode is active or not.
1654
  // SPEC1170 mode active: behaviour like POSIX, MAP_FIXED will clobber existing mappings.
1655
  // SPEC1170 mode not active: behaviour, unlike POSIX, is that no existing mappings will
1656
  // get clobbered.
1657
  if (requested_addr != nullptr) {
1658
    if (!os::Aix::xpg_sus_mode()) {  // not SPEC1170 Behaviour
1659
      flags |= MAP_FIXED;
1660
    }
1661
  }
1662

1663
  char* addr = (char*)::mmap(requested_addr, extra_size,
1664
      PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
1665

1666
  if (addr == MAP_FAILED) {
1667
    ErrnoPreserver ep;
1668
    log_trace(os, map)("mmap failed: " RANGEFMT " errno=(%s)",
1669
                       RANGEFMTARGS(requested_addr, size),
1670
                       os::strerror(ep.saved_errno()));
1671
    return nullptr;
1672
  } else if (requested_addr != nullptr && addr != requested_addr) {
1673
    log_trace(os, map)("mmap succeeded: " RANGEFMT
1674
                       ", but at a different address than"
1675
                       "requested (" PTR_FORMAT "), will unmap",
1676
                       RANGEFMTARGS(requested_addr, size),
1677
                       p2i(addr));
1678
    ::munmap(addr, extra_size);
1679
    return nullptr;
1680
  }
1681

1682
  // Handle alignment.
1683
  char* const addr_aligned = align_up(addr, alignment);
1684
  const size_t waste_pre = addr_aligned - addr;
1685
  char* const addr_aligned_end = addr_aligned + size;
1686
  const size_t waste_post = extra_size - waste_pre - size;
1687
  if (waste_pre > 0) {
1688
    ::munmap(addr, waste_pre);
1689
  }
1690
  if (waste_post > 0) {
1691
    ::munmap(addr_aligned_end, waste_post);
1692
  }
1693
  addr = addr_aligned;
1694

1695
  trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",
1696
    p2i(addr), p2i(addr + bytes), bytes);
1697

1698
  // bookkeeping
1699
  if (os::vm_page_size() == 64*K && g_multipage_support.can_use_64K_mmap_pages) {
1700
    vmembk_add(addr, size, 64*K, VMEM_MAPPED);
1701
  } else {
1702
    vmembk_add(addr, size, 4*K, VMEM_MAPPED);
1703
  }
1704

1705
  // Test alignment, see above.
1706
  assert0(is_aligned_to(addr, os::vm_page_size()));
1707

1708
  return addr;
1709
}
1710

1711
static bool release_mmaped_memory(char* addr, size_t size) {
1712
  assert0(is_aligned_to(addr, os::vm_page_size()));
1713
  assert0(is_aligned_to(size, os::vm_page_size()));
1714

1715
  trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
1716
    p2i(addr), p2i(addr + size - 1));
1717
  bool rc = false;
1718

1719
  if (::munmap(addr, size) != 0) {
1720
    ErrnoPreserver ep;
1721
    log_trace(os, map)("munmap failed: " RANGEFMT " errno=(%s)",
1722
                       RANGEFMTARGS(addr, size),
1723
                       os::strerror(ep.saved_errno()));
1724
    rc = false;
1725
  } else {
1726
    log_trace(os, map)("munmap succeeded: " RANGEFMT,
1727
                       RANGEFMTARGS(addr, size));
1728
    rc = true;
1729
  }
1730

1731
  return rc;
1732
}
1733

1734
static bool uncommit_mmaped_memory(char* addr, size_t size) {
1735

1736
  assert0(is_aligned_to(addr, os::vm_page_size()));
1737
  assert0(is_aligned_to(size, os::vm_page_size()));
1738

1739
  trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
1740
    p2i(addr), p2i(addr + size - 1));
1741
  bool rc = false;
1742

1743
  // Uncommit mmap memory with msync MS_INVALIDATE.
1744
  if (::msync(addr, size, MS_INVALIDATE) != 0) {
1745
    ErrnoPreserver ep;
1746
    log_trace(os, map)("msync failed: " RANGEFMT " errno=(%s)",
1747
                       RANGEFMTARGS(addr, size),
1748
                       os::strerror(ep.saved_errno()));
1749
    rc = false;
1750
  } else {
1751
    log_trace(os, map)("msync succeeded: " RANGEFMT,
1752
                       RANGEFMTARGS(addr, size));
1753
    rc = true;
1754
  }
1755

1756
  return rc;
1757
}
1758

1759
#ifdef PRODUCT
1760
static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
1761
                                    int err) {
1762
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
1763
          ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,
1764
          os::errno_name(err), err);
1765
}
1766
#endif
1767

1768
void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
1769
                                  const char* mesg) {
1770
  assert(mesg != nullptr, "mesg must be specified");
1771
  if (!pd_commit_memory(addr, size, exec)) {
1772
    // Add extra info in product mode for vm_exit_out_of_memory():
1773
    PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
1774
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);
1775
  }
1776
}
1777

1778
bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
1779

1780
  assert(is_aligned_to(addr, os::vm_page_size()),
1781
    "addr " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")",
1782
    p2i(addr), os::vm_page_size());
1783
  assert(is_aligned_to(size, os::vm_page_size()),
1784
    "size " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")",
1785
    size, os::vm_page_size());
1786

1787
  vmembk_t* const vmi = vmembk_find(addr);
1788
  guarantee0(vmi);
1789
  vmi->assert_is_valid_subrange(addr, size);
1790

1791
  log_info(os)("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", p2i(addr), p2i(addr + size - 1));
1792

1793
  if (UseExplicitCommit) {
1794
    // AIX commits memory on touch. So, touch all pages to be committed.
1795
    for (char* p = addr; p < (addr + size); p += 4*K) {
1796
      *p = '\0';
1797
    }
1798
  }
1799

1800
  return true;
1801
}
1802

1803
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) {
1804
  return pd_commit_memory(addr, size, exec);
1805
}
1806

1807
void os::pd_commit_memory_or_exit(char* addr, size_t size,
1808
                                  size_t alignment_hint, bool exec,
1809
                                  const char* mesg) {
1810
  // Alignment_hint is ignored on this OS.
1811
  pd_commit_memory_or_exit(addr, size, exec, mesg);
1812
}
1813

1814
bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {
1815
  assert(is_aligned_to(addr, os::vm_page_size()),
1816
    "addr " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")",
1817
    p2i(addr), os::vm_page_size());
1818
  assert(is_aligned_to(size, os::vm_page_size()),
1819
    "size " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")",
1820
    size, os::vm_page_size());
1821

1822
  // Dynamically do different things for mmap/shmat.
1823
  const vmembk_t* const vmi = vmembk_find(addr);
1824
  guarantee0(vmi);
1825
  vmi->assert_is_valid_subrange(addr, size);
1826

1827
  if (vmi->type == VMEM_SHMATED) {
1828
    return uncommit_shmated_memory(addr, size);
1829
  } else {
1830
    return uncommit_mmaped_memory(addr, size);
1831
  }
1832
}
1833

1834
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
1835
  // Do not call this; no need to commit stack pages on AIX.
1836
  ShouldNotReachHere();
1837
  return true;
1838
}
1839

1840
bool os::remove_stack_guard_pages(char* addr, size_t size) {
1841
  // Do not call this; no need to commit stack pages on AIX.
1842
  ShouldNotReachHere();
1843
  return true;
1844
}
1845

1846
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
1847
}
1848

1849
void os::pd_disclaim_memory(char *addr, size_t bytes) {
1850
}
1851

1852
size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) {
1853
  return page_size;
1854
}
1855

1856
void os::numa_make_global(char *addr, size_t bytes) {
1857
}
1858

1859
void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
1860
}
1861

1862
bool os::numa_topology_changed() {
1863
  return false;
1864
}
1865

1866
size_t os::numa_get_groups_num() {
1867
  return 1;
1868
}
1869

1870
int os::numa_get_group_id() {
1871
  return 0;
1872
}
1873

1874
size_t os::numa_get_leaf_groups(uint *ids, size_t size) {
1875
  if (size > 0) {
1876
    ids[0] = 0;
1877
    return 1;
1878
  }
1879
  return 0;
1880
}
1881

1882
int os::numa_get_group_id_for_address(const void* address) {
1883
  return 0;
1884
}
1885

1886
bool os::numa_get_group_ids_for_range(const void** addresses, int* lgrp_ids, size_t count) {
1887
  return false;
1888
}
1889

1890
// Reserves and attaches a shared memory segment.
1891
char* os::pd_reserve_memory(size_t bytes, bool exec) {
1892
  // Always round to os::vm_page_size(), which may be larger than 4K.
1893
  bytes = align_up(bytes, os::vm_page_size());
1894

1895
  // In 4K mode always use mmap.
1896
  // In 64K mode allocate with mmap if it supports 64K pages, otherwise use 64K shmatted.
1897
  if (os::vm_page_size() == 4*K || g_multipage_support.can_use_64K_mmap_pages) {
1898
    return reserve_mmaped_memory(bytes, nullptr /* requested_addr */);
1899
  } else {
1900
    return reserve_shmated_memory(bytes, nullptr /* requested_addr */);
1901
  }
1902
}
1903

1904
bool os::pd_release_memory(char* addr, size_t size) {
1905

1906
  // Dynamically do different things for mmap/shmat.
1907
  vmembk_t* const vmi = vmembk_find(addr);
1908
  guarantee0(vmi);
1909
  vmi->assert_is_valid_subrange(addr, size);
1910

1911
  // Always round to os::vm_page_size(), which may be larger than 4K.
1912
  size = align_up(size, os::vm_page_size());
1913
  addr = align_up(addr, os::vm_page_size());
1914

1915
  bool rc = false;
1916
  bool remove_bookkeeping = false;
1917
  if (vmi->type == VMEM_SHMATED) {
1918
    // For shmatted memory, we do:
1919
    // - If user wants to release the whole range, release the memory (shmdt).
1920
    // - If user only wants to release a partial range, uncommit (disclaim) that
1921
    //   range. That way, at least, we do not use memory anymore (bust still page
1922
    //   table space).
1923
    if (addr == vmi->addr && size == vmi->size) {
1924
      rc = release_shmated_memory(addr, size);
1925
      remove_bookkeeping = true;
1926
    } else {
1927
      rc = uncommit_shmated_memory(addr, size);
1928
    }
1929
  } else {
1930
    // In mmap-mode:
1931
    //  - If the user wants to release the full range, we do that and remove the mapping.
1932
    //  - If the user wants to release part of the range, we release that part, but need
1933
    //    to adjust bookkeeping.
1934
    assert(is_aligned(size, 4 * K), "Sanity");
1935
    rc = release_mmaped_memory(addr, size);
1936
    if (addr == vmi->addr && size == vmi->size) {
1937
      remove_bookkeeping = true;
1938
    } else {
1939
      if (addr == vmi->addr && size < vmi->size) {
1940
        // Chopped from head
1941
        vmi->addr += size;
1942
        vmi->size -= size;
1943
      } else if (addr + size == vmi->addr + vmi->size) {
1944
        // Chopped from tail
1945
        vmi->size -= size;
1946
      } else {
1947
        // releasing a mapping in the middle of the original mapping:
1948
        // For now we forbid this, since this is an invalid scenario
1949
        // (the bookkeeping is easy enough to fix if needed but there
1950
        //  is no use case for it; any occurrence is likely an error.
1951
        ShouldNotReachHere();
1952
      }
1953
    }
1954
  }
1955

1956
  // update bookkeeping
1957
  if (rc && remove_bookkeeping) {
1958
    vmembk_remove(vmi);
1959
  }
1960

1961
  return rc;
1962
}
1963

1964
static bool checked_mprotect(char* addr, size_t size, int prot) {
1965

1966
  // Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will
1967
  // not tell me if protection failed when trying to protect an un-protectable range.
1968
  //
1969
  // This means if the memory was allocated using shmget/shmat, protection won't work
1970
  // but mprotect will still return 0:
1971
  //
1972
  // See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm
1973

1974
  Events::log_memprotect(nullptr, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);
1975
  bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;
1976

1977
  if (!rc) {
1978
    const char* const s_errno = os::errno_name(errno);
1979
    warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", p2i(addr), p2i(addr) + size, prot, s_errno);
1980
    return false;
1981
  }
1982

1983
  // mprotect success check
1984
  //
1985
  // Mprotect said it changed the protection but can I believe it?
1986
  //
1987
  // To be sure I need to check the protection afterwards. Try to
1988
  // read from protected memory and check whether that causes a segfault.
1989
  //
1990
  if (!os::Aix::xpg_sus_mode()) {
1991

1992
    const bool read_protected =
1993
      (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&
1994
       SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;
1995

1996
    if (prot & PROT_READ) {
1997
      rc = !read_protected;
1998
    } else {
1999
      rc = read_protected;
2000
    }
2001
  }
2002

2003
  assert(rc == true, "mprotect failed.");
2004

2005
  return rc;
2006
}
2007

2008
// Set protections specified
2009
bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {
2010
  unsigned int p = 0;
2011
  switch (prot) {
2012
  case MEM_PROT_NONE: p = PROT_NONE; break;
2013
  case MEM_PROT_READ: p = PROT_READ; break;
2014
  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
2015
  case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
2016
  default:
2017
    ShouldNotReachHere();
2018
  }
2019
  // is_committed is unused.
2020
  return checked_mprotect(addr, size, p);
2021
}
2022

2023
bool os::guard_memory(char* addr, size_t size) {
2024
  return checked_mprotect(addr, size, PROT_NONE);
2025
}
2026

2027
bool os::unguard_memory(char* addr, size_t size) {
2028
  return checked_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC);
2029
}
2030

2031
// Large page support
2032

2033
static size_t _large_page_size = 0;
2034

2035
// Enable large page support if OS allows that.
2036
void os::large_page_init() {
2037
  return; // Nothing to do. See query_multipage_support and friends.
2038
}
2039

2040
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {
2041
  fatal("os::reserve_memory_special should not be called on AIX.");
2042
  return nullptr;
2043
}
2044

2045
bool os::pd_release_memory_special(char* base, size_t bytes) {
2046
  fatal("os::release_memory_special should not be called on AIX.");
2047
  return false;
2048
}
2049

2050
size_t os::large_page_size() {
2051
  return _large_page_size;
2052
}
2053

2054
bool os::can_commit_large_page_memory() {
2055
  // Does not matter, we do not support huge pages.
2056
  return false;
2057
}
2058

2059
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
2060
  assert(file_desc >= 0, "file_desc is not valid");
2061
  char* result = nullptr;
2062

2063
  // Always round to os::vm_page_size(), which may be larger than 4K.
2064
  bytes = align_up(bytes, os::vm_page_size());
2065
  result = reserve_mmaped_memory(bytes, requested_addr);
2066

2067
  if (result != nullptr) {
2068
    if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == nullptr) {
2069
      vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
2070
    }
2071
  }
2072
  return result;
2073
}
2074

2075
// Reserve memory at an arbitrary address, only if that area is
2076
// available (and not reserved for something else).
2077
char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {
2078
  char* addr = nullptr;
2079

2080
  // Always round to os::vm_page_size(), which may be larger than 4K.
2081
  bytes = align_up(bytes, os::vm_page_size());
2082

2083
  // In 4K mode always use mmap.
2084
  // In 64K mode allocate with mmap if it supports 64K pages, otherwise use 64K shmatted.
2085
  if (os::vm_page_size() == 4*K || g_multipage_support.can_use_64K_mmap_pages) {
2086
    return reserve_mmaped_memory(bytes, requested_addr);
2087
  } else {
2088
    return reserve_shmated_memory(bytes, requested_addr);
2089
  }
2090

2091
  return addr;
2092
}
2093

2094
size_t os::vm_min_address() {
2095
  // On AIX, we need to make sure we don't block the sbrk. However, this is
2096
  // done at actual reservation time, where we honor a "no-mmap" area following
2097
  // the break. See MaxExpectedDataSegmentSize. So we can return a very low
2098
  // address here.
2099
  assert(is_aligned(_vm_min_address_default, os::vm_allocation_granularity()), "Sanity");
2100
  return _vm_min_address_default;
2101
}
2102

2103
////////////////////////////////////////////////////////////////////////////////
2104
// thread priority support
2105

2106
// From AIX manpage to pthread_setschedparam
2107
// (see: http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?
2108
//    topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_setschedparam.htm):
2109
//
2110
// "If schedpolicy is SCHED_OTHER, then sched_priority must be in the
2111
// range from 40 to 80, where 40 is the least favored priority and 80
2112
// is the most favored."
2113
//
2114
// (Actually, I doubt this even has an impact on AIX, as we do kernel
2115
// scheduling there; however, this still leaves iSeries.)
2116
//
2117
int os::java_to_os_priority[CriticalPriority + 1] = {
2118
  54,             // 0 Entry should never be used
2119

2120
  55,             // 1 MinPriority
2121
  55,             // 2
2122
  56,             // 3
2123

2124
  56,             // 4
2125
  57,             // 5 NormPriority
2126
  57,             // 6
2127

2128
  58,             // 7
2129
  58,             // 8
2130
  59,             // 9 NearMaxPriority
2131

2132
  60,             // 10 MaxPriority
2133

2134
  60              // 11 CriticalPriority
2135
};
2136

2137
static int prio_init() {
2138
  if (ThreadPriorityPolicy == 1) {
2139
    if (geteuid() != 0) {
2140
      if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy) && !FLAG_IS_JIMAGE_RESOURCE(ThreadPriorityPolicy)) {
2141
        warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \
2142
                "e.g., being the root user. If the necessary permission is not " \
2143
                "possessed, changes to priority will be silently ignored.");
2144
      }
2145
    }
2146
  }
2147
  if (UseCriticalJavaThreadPriority) {
2148
    os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
2149
  }
2150
  return 0;
2151
}
2152

2153
OSReturn os::set_native_priority(Thread* thread, int newpri) {
2154
  if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;
2155
  pthread_t thr = thread->osthread()->pthread_id();
2156
  int policy = SCHED_OTHER;
2157
  struct sched_param param;
2158
  param.sched_priority = newpri;
2159
  int ret = pthread_setschedparam(thr, policy, &param);
2160

2161
  if (ret != 0) {
2162
    log_warning(os)("Could not change priority for thread %d to %d (error %d, %s)",
2163
        (int)thr, newpri, ret, os::errno_name(ret));
2164
  }
2165
  return (ret == 0) ? OS_OK : OS_ERR;
2166
}
2167

2168
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
2169
  if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {
2170
    *priority_ptr = java_to_os_priority[NormPriority];
2171
    return OS_OK;
2172
  }
2173
  pthread_t thr = thread->osthread()->pthread_id();
2174
  int policy = SCHED_OTHER;
2175
  struct sched_param param;
2176
  int ret = pthread_getschedparam(thr, &policy, &param);
2177
  *priority_ptr = param.sched_priority;
2178

2179
  return (ret == 0) ? OS_OK : OS_ERR;
2180
}
2181

2182
// To install functions for atexit system call
2183
extern "C" {
2184
  static void perfMemory_exit_helper() {
2185
    perfMemory_exit();
2186
  }
2187
}
2188

2189
static void set_page_size(size_t page_size) {
2190
  OSInfo::set_vm_page_size(page_size);
2191
  OSInfo::set_vm_allocation_granularity(page_size);
2192
}
2193

2194
// This is called _before_ the most of global arguments have been parsed.
2195
void os::init(void) {
2196
  // This is basic, we want to know if that ever changes.
2197
  // (Shared memory boundary is supposed to be a 256M aligned.)
2198
  assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected");
2199

2200
  // Record process break at startup.
2201
  g_brk_at_startup = (address) ::sbrk(0);
2202
  assert(g_brk_at_startup != (address) -1, "sbrk failed");
2203

2204
  // First off, we need to know the OS level we run on.
2205
  os::Aix::initialize_os_info();
2206

2207
  // Scan environment (SPEC1170 behaviour, etc).
2208
  os::Aix::scan_environment();
2209

2210
  // Probe multipage support.
2211
  query_multipage_support();
2212

2213
  // Act like we only have one page size by eliminating corner cases which
2214
  // we did not support very well anyway.
2215
  // We have two input conditions:
2216
  // 1) Data segment page size. This is controlled by linker setting (datapsize) on the
2217
  //    launcher, and/or by LDR_CNTRL environment variable. The latter overrules the linker
2218
  //    setting.
2219
  //    Data segment page size is important for us because it defines the thread stack page
2220
  //    size, which is needed for guard page handling, stack banging etc.
2221
  // 2) The ability to allocate 64k pages dynamically. If this is a given, java heap can
2222
  //    and should be allocated with 64k pages.
2223
  //
2224
  // So, we do the following:
2225
  // LDR_CNTRL    can_use_64K_pages_dynamically(mmap or shm)       what we do                      remarks
2226
  // 4K           no                                               4K                              old systems (aix 5.2) or new systems with AME activated
2227
  // 4k           yes                                              64k (treat 4k stacks as 64k)    different loader than java and standard settings
2228
  // 64k          no              --- AIX 5.2 ? ---
2229
  // 64k          yes                                              64k                             new systems and standard java loader (we set datapsize=64k when linking)
2230

2231
  // We explicitly leave no option to change page size, because only upgrading would work,
2232
  // not downgrading (if stack page size is 64k you cannot pretend its 4k).
2233

2234
  if (g_multipage_support.datapsize == 4*K) {
2235
    // datapsize = 4K. Data segment, thread stacks are 4K paged.
2236
    if (g_multipage_support.can_use_64K_pages || g_multipage_support.can_use_64K_mmap_pages) {
2237
      // .. but we are able to use 64K pages dynamically.
2238
      // This would be typical for java launchers which are not linked
2239
      // with datapsize=64K (like, any other launcher but our own).
2240
      //
2241
      // In this case it would be smart to allocate the java heap with 64K
2242
      // to get the performance benefit, and to fake 64k pages for the
2243
      // data segment (when dealing with thread stacks).
2244
      //
2245
      // However, leave a possibility to downgrade to 4K, using
2246
      // -XX:-Use64KPages.
2247
      if (Use64KPages) {
2248
        trcVerbose("64K page mode (faked for data segment)");
2249
        set_page_size(64*K);
2250
      } else {
2251
        trcVerbose("4K page mode (Use64KPages=off)");
2252
        set_page_size(4*K);
2253
      }
2254
    } else {
2255
      // .. and not able to allocate 64k pages dynamically. Here, just
2256
      // fall back to 4K paged mode and use mmap for everything.
2257
      trcVerbose("4K page mode");
2258
      set_page_size(4*K);
2259
      FLAG_SET_ERGO(Use64KPages, false);
2260
    }
2261
  } else {
2262
    // datapsize = 64k. Data segment, thread stacks are 64k paged.
2263
    // This normally means that we can allocate 64k pages dynamically.
2264
    // (There is one special case where this may be false: EXTSHM=on.
2265
    // but we decided to not support that mode).
2266
    assert0(g_multipage_support.can_use_64K_pages || g_multipage_support.can_use_64K_mmap_pages);
2267
    set_page_size(64*K);
2268
    trcVerbose("64K page mode");
2269
    FLAG_SET_ERGO(Use64KPages, true);
2270
  }
2271

2272
  // For now UseLargePages is just ignored.
2273
  FLAG_SET_ERGO(UseLargePages, false);
2274
  _page_sizes.add(os::vm_page_size());
2275

2276
  // debug trace
2277
  trcVerbose("os::vm_page_size %s", describe_pagesize(os::vm_page_size()));
2278

2279
  // Next, we need to initialize libperfstat
2280
  os::Aix::initialize_libperfstat();
2281

2282
  // Reset the perfstat information provided by ODM.
2283
  libperfstat::perfstat_reset();
2284

2285
  // Now initialize basic system properties. Note that for some of the values we
2286
  // need libperfstat etc.
2287
  os::Aix::initialize_system_info();
2288

2289
  // _main_thread points to the thread that created/loaded the JVM.
2290
  Aix::_main_thread = pthread_self();
2291

2292
  os::Posix::init();
2293
}
2294

2295
// This is called _after_ the global arguments have been parsed.
2296
jint os::init_2(void) {
2297

2298
  // This could be set after os::Posix::init() but all platforms
2299
  // have to set it the same so we have to mirror Solaris.
2300
  DEBUG_ONLY(os::set_mutex_init_done();)
2301

2302
  os::Posix::init_2();
2303

2304
  trcVerbose("processor count: %d", os::_processor_count);
2305
  trcVerbose("physical memory: %lu", Aix::_physical_memory);
2306

2307
  // Initially build up the loaded dll map.
2308
  LoadedLibraries::reload();
2309
  if (Verbose) {
2310
    trcVerbose("Loaded Libraries: ");
2311
    LoadedLibraries::print(tty);
2312
  }
2313

2314
  if (PosixSignals::init() == JNI_ERR) {
2315
    return JNI_ERR;
2316
  }
2317

2318
  // Check and sets minimum stack sizes against command line options
2319
  if (set_minimum_stack_sizes() == JNI_ERR) {
2320
    return JNI_ERR;
2321
  }
2322

2323
  // Not supported.
2324
  FLAG_SET_ERGO(UseNUMA, false);
2325
  FLAG_SET_ERGO(UseNUMAInterleaving, false);
2326

2327
  if (MaxFDLimit) {
2328
    // Set the number of file descriptors to max. print out error
2329
    // if getrlimit/setrlimit fails but continue regardless.
2330
    struct rlimit nbr_files;
2331
    int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
2332
    if (status != 0) {
2333
      log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));
2334
    } else {
2335
      nbr_files.rlim_cur = nbr_files.rlim_max;
2336
      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
2337
      if (status != 0) {
2338
        log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));
2339
      }
2340
    }
2341
  }
2342

2343
  if (PerfAllowAtExitRegistration) {
2344
    // Only register atexit functions if PerfAllowAtExitRegistration is set.
2345
    // At exit functions can be delayed until process exit time, which
2346
    // can be problematic for embedded VM situations. Embedded VMs should
2347
    // call DestroyJavaVM() to assure that VM resources are released.
2348

2349
    // Note: perfMemory_exit_helper atexit function may be removed in
2350
    // the future if the appropriate cleanup code can be added to the
2351
    // VM_Exit VMOperation's doit method.
2352
    if (atexit(perfMemory_exit_helper) != 0) {
2353
      warning("os::init_2 atexit(perfMemory_exit_helper) failed");
2354
    }
2355
  }
2356

2357
  // initialize thread priority policy
2358
  prio_init();
2359

2360
  return JNI_OK;
2361
}
2362

2363
int os::active_processor_count() {
2364
  // User has overridden the number of active processors
2365
  if (ActiveProcessorCount > 0) {
2366
    log_trace(os)("active_processor_count: "
2367
                  "active processor count set by user : %d",
2368
                  ActiveProcessorCount);
2369
    return ActiveProcessorCount;
2370
  }
2371

2372
  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
2373
  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
2374
  return online_cpus;
2375
}
2376

2377
void os::set_native_thread_name(const char *name) {
2378
  // Not yet implemented.
2379
  return;
2380
}
2381

2382
////////////////////////////////////////////////////////////////////////////////
2383
// debug support
2384

2385
bool os::find(address addr, outputStream* st) {
2386

2387
  st->print(PTR_FORMAT ": ", p2i(addr));
2388

2389
  loaded_module_t lm;
2390
  if (LoadedLibraries::find_for_text_address(addr, &lm) ||
2391
      LoadedLibraries::find_for_data_address(addr, &lm)) {
2392
    st->print_cr("%s", lm.path);
2393
    return true;
2394
  }
2395

2396
  return false;
2397
}
2398

2399
////////////////////////////////////////////////////////////////////////////////
2400
// misc
2401

2402
// This does not do anything on Aix. This is basically a hook for being
2403
// able to use structured exception handling (thread-local exception filters)
2404
// on, e.g., Win32.
2405
void
2406
os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
2407
                         JavaCallArguments* args, JavaThread* thread) {
2408
  f(value, method, args, thread);
2409
}
2410

2411
// This code originates from JDK's sysOpen and open64_w
2412
// from src/solaris/hpi/src/system_md.c
2413

2414
int os::open(const char *path, int oflag, int mode) {
2415

2416
  if (strlen(path) > MAX_PATH - 1) {
2417
    errno = ENAMETOOLONG;
2418
    return -1;
2419
  }
2420
  // AIX 7.X now supports O_CLOEXEC too, like modern Linux; but we have to be careful, see
2421
  // IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE
2422
  int oflag_with_o_cloexec = oflag | O_CLOEXEC;
2423

2424
  int fd = ::open(path, oflag_with_o_cloexec, mode);
2425
  if (fd == -1) {
2426
    // we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804)
2427
    fd = ::open(path, oflag, mode);
2428
    if (fd == -1) {
2429
      return -1;
2430
    }
2431
  }
2432

2433
  // If the open succeeded, the file might still be a directory.
2434
  {
2435
    struct stat buf64;
2436
    int ret = ::fstat(fd, &buf64);
2437
    int st_mode = buf64.st_mode;
2438

2439
    if (ret != -1) {
2440
      if ((st_mode & S_IFMT) == S_IFDIR) {
2441
        errno = EISDIR;
2442
        ::close(fd);
2443
        return -1;
2444
      }
2445
    } else {
2446
      ::close(fd);
2447
      return -1;
2448
    }
2449
  }
2450

2451
  // All file descriptors that are opened in the JVM and not
2452
  // specifically destined for a subprocess should have the
2453
  // close-on-exec flag set. If we don't set it, then careless 3rd
2454
  // party native code might fork and exec without closing all
2455
  // appropriate file descriptors (e.g. as we do in closeDescriptors in
2456
  // UNIXProcess.c), and this in turn might:
2457
  //
2458
  // - cause end-of-file to fail to be detected on some file
2459
  //   descriptors, resulting in mysterious hangs, or
2460
  //
2461
  // - might cause an fopen in the subprocess to fail on a system
2462
  //   suffering from bug 1085341.
2463

2464
  // Validate that the use of the O_CLOEXEC flag on open above worked.
2465
  static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
2466
  if (O_CLOEXEC_is_known_to_work == 0) {
2467
    int flags = ::fcntl(fd, F_GETFD);
2468
    if (flags != -1) {
2469
      if ((flags & FD_CLOEXEC) != 0) {
2470
        O_CLOEXEC_is_known_to_work = 1;
2471
      } else { // it does not work
2472
        ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2473
        O_CLOEXEC_is_known_to_work = -1;
2474
      }
2475
    }
2476
  } else if (O_CLOEXEC_is_known_to_work == -1) {
2477
    int flags = ::fcntl(fd, F_GETFD);
2478
    if (flags != -1) {
2479
      ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2480
    }
2481
  }
2482

2483
  return fd;
2484
}
2485

2486
// return current position of file pointer
2487
jlong os::current_file_offset(int fd) {
2488
  return (jlong)::lseek(fd, (off_t)0, SEEK_CUR);
2489
}
2490

2491
// move file pointer to the specified offset
2492
jlong os::seek_to_file_offset(int fd, jlong offset) {
2493
  return (jlong)::lseek(fd, (off_t)offset, SEEK_SET);
2494
}
2495

2496
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
2497
// are used by JVM M&M and JVMTI to get user+sys or user CPU time
2498
// of a thread.
2499
//
2500
// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
2501
// the fast estimate available on the platform.
2502

2503
jlong os::current_thread_cpu_time() {
2504
  // return user + sys since the cost is the same
2505
  const jlong n = os::thread_cpu_time(Thread::current(), true /* user + sys */);
2506
  assert(n >= 0, "negative CPU time");
2507
  return n;
2508
}
2509

2510
jlong os::thread_cpu_time(Thread* thread) {
2511
  // consistent with what current_thread_cpu_time() returns
2512
  const jlong n = os::thread_cpu_time(thread, true /* user + sys */);
2513
  assert(n >= 0, "negative CPU time");
2514
  return n;
2515
}
2516

2517
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
2518
  const jlong n = os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
2519
  assert(n >= 0, "negative CPU time");
2520
  return n;
2521
}
2522

2523
static bool thread_cpu_time_unchecked(Thread* thread, jlong* p_sys_time, jlong* p_user_time) {
2524
  bool error = false;
2525

2526
  jlong sys_time = 0;
2527
  jlong user_time = 0;
2528

2529
  // Reimplemented using getthrds64().
2530
  //
2531
  // Works like this:
2532
  // For the thread in question, get the kernel thread id. Then get the
2533
  // kernel thread statistics using that id.
2534
  //
2535
  // This only works of course when no pthread scheduling is used,
2536
  // i.e. there is a 1:1 relationship to kernel threads.
2537
  // On AIX, see AIXTHREAD_SCOPE variable.
2538

2539
  pthread_t pthtid = thread->osthread()->pthread_id();
2540

2541
  // retrieve kernel thread id for the pthread:
2542
  tid64_t tid = 0;
2543
  struct __pthrdsinfo pinfo;
2544
  // I just love those otherworldly IBM APIs which force me to hand down
2545
  // dummy buffers for stuff I dont care for...
2546
  char dummy[1];
2547
  int dummy_size = sizeof(dummy);
2548
  if (pthread_getthrds_np(&pthtid, PTHRDSINFO_QUERY_TID, &pinfo, sizeof(pinfo),
2549
                          dummy, &dummy_size) == 0) {
2550
    tid = pinfo.__pi_tid;
2551
  } else {
2552
    tty->print_cr("pthread_getthrds_np failed.");
2553
    error = true;
2554
  }
2555

2556
  // retrieve kernel timing info for that kernel thread
2557
  if (!error) {
2558
    struct thrdentry64 thrdentry;
2559
    if (getthrds64(getpid(), &thrdentry, sizeof(thrdentry), &tid, 1) == 1) {
2560
      sys_time = thrdentry.ti_ru.ru_stime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_stime.tv_usec * 1000LL;
2561
      user_time = thrdentry.ti_ru.ru_utime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_utime.tv_usec * 1000LL;
2562
    } else {
2563
      tty->print_cr("pthread_getthrds_np failed.");
2564
      error = true;
2565
    }
2566
  }
2567

2568
  if (p_sys_time) {
2569
    *p_sys_time = sys_time;
2570
  }
2571

2572
  if (p_user_time) {
2573
    *p_user_time = user_time;
2574
  }
2575

2576
  if (error) {
2577
    return false;
2578
  }
2579

2580
  return true;
2581
}
2582

2583
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
2584
  jlong sys_time;
2585
  jlong user_time;
2586

2587
  if (!thread_cpu_time_unchecked(thread, &sys_time, &user_time)) {
2588
    return -1;
2589
  }
2590

2591
  return user_sys_cpu_time ? sys_time + user_time : user_time;
2592
}
2593

2594
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
2595
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
2596
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
2597
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
2598
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
2599
}
2600

2601
void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
2602
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
2603
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
2604
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
2605
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
2606
}
2607

2608
bool os::is_thread_cpu_time_supported() {
2609
  return true;
2610
}
2611

2612
// System loadavg support. Returns -1 if load average cannot be obtained.
2613
// For now just return the system wide load average (no processor sets).
2614
int os::loadavg(double values[], int nelem) {
2615

2616
  guarantee(nelem >= 0 && nelem <= 3, "argument error");
2617
  guarantee(values, "argument error");
2618

2619
  // AIX: use libperfstat
2620
  libperfstat::cpuinfo_t ci;
2621
  if (libperfstat::get_cpuinfo(&ci)) {
2622
    for (int i = 0; i < nelem; i++) {
2623
      values[i] = ci.loadavg[i];
2624
    }
2625
  } else {
2626
    return -1;
2627
  }
2628
  return nelem;
2629
}
2630

2631
bool os::is_primordial_thread(void) {
2632
  if (pthread_self() == (pthread_t)1) {
2633
    return true;
2634
  } else {
2635
    return false;
2636
  }
2637
}
2638

2639
// OS recognitions (OS level) call this before calling Aix::os_version()
2640
void os::Aix::initialize_os_info() {
2641

2642
  assert(_os_version == 0, "already called.");
2643

2644
  struct utsname uts;
2645
  memset(&uts, 0, sizeof(uts));
2646
  strcpy(uts.sysname, "?");
2647
  if (::uname(&uts) == -1) {
2648
    log_warning(os)("uname failed (%d)", errno);
2649
    guarantee(0, "Could not determine uname information");
2650
  } else {
2651
    log_info(os)("uname says: sysname \"%s\" version \"%s\" release \"%s\" "
2652
               "node \"%s\" machine \"%s\"\n",
2653
               uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);
2654
    const int major = atoi(uts.version);
2655
    assert(major > 0, "invalid OS version");
2656
    const int minor = atoi(uts.release);
2657
    assert(minor > 0, "invalid OS release");
2658
    _os_version = (major << 24) | (minor << 16);
2659
    char ver_str[20] = {0};
2660
    const char* name_str = "unknown OS";
2661

2662
    if (strcmp(uts.sysname, "AIX") == 0) {
2663
      // We run on AIX. We do not support versions older than AIX 7.1.
2664
      // Determine detailed AIX version: Version, Release, Modification, Fix Level.
2665
      odmWrapper::determine_os_kernel_version(&_os_version);
2666
      if (os_version_short() < 0x0701) {
2667
        log_warning(os)("AIX releases older than AIX 7.1 are not supported.");
2668
        assert(false, "AIX release too old.");
2669
      }
2670
      name_str = "AIX";
2671
      jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",
2672
                   major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);
2673
    } else {
2674
      assert(false, "%s", name_str);
2675
    }
2676
    log_info(os)("We run on %s %s", name_str, ver_str);
2677
  }
2678

2679
  guarantee(_os_version, "Could not determine AIX release");
2680
} // end: os::Aix::initialize_os_info()
2681

2682
// Scan environment for important settings which might effect the VM.
2683
// Trace out settings. Warn about invalid settings and/or correct them.
2684
//
2685
// Must run after os::Aix::initialue_os_info().
2686
void os::Aix::scan_environment() {
2687

2688
  char* p;
2689
  int rc;
2690

2691
  // Warn explicitly if EXTSHM=ON is used. That switch changes how
2692
  // System V shared memory behaves. One effect is that page size of
2693
  // shared memory cannot be change dynamically, effectivly preventing
2694
  // large pages from working.
2695
  // This switch was needed on AIX 32bit, but on AIX 64bit the general
2696
  // recommendation is (in OSS notes) to switch it off.
2697
  p = ::getenv("EXTSHM");
2698
  trcVerbose("EXTSHM=%s.", p ? p : "<unset>");
2699
  if (p && strcasecmp(p, "ON") == 0) {
2700
    _extshm = 1;
2701
    log_warning(os)("*** Unsupported mode! Please remove EXTSHM from your environment! ***");
2702
    if (!AllowExtshm) {
2703
      // We allow under certain conditions the user to continue. However, we want this
2704
      // to be a fatal error by default. On certain AIX systems, leaving EXTSHM=ON means
2705
      // that the VM is not able to allocate 64k pages for the heap.
2706
      // We do not want to run with reduced performance.
2707
      vm_exit_during_initialization("EXTSHM is ON. Please remove EXTSHM from your environment.");
2708
    }
2709
  } else {
2710
    _extshm = 0;
2711
  }
2712

2713
  // SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs.
2714
  // Not tested, not supported.
2715
  //
2716
  // Note that it might be worth the trouble to test and to require it, if only to
2717
  // get useful return codes for mprotect.
2718
  //
2719
  // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before
2720
  // exec() ? before loading the libjvm ? ....)
2721
  p = ::getenv("XPG_SUS_ENV");
2722
  trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>");
2723
  if (p && strcmp(p, "ON") == 0) {
2724
    _xpg_sus_mode = 1;
2725
    log_warning(os)("Unsupported setting: XPG_SUS_ENV=ON");
2726
    // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to
2727
    // clobber address ranges. If we ever want to support that, we have to do some
2728
    // testing first.
2729
    guarantee(false, "XPG_SUS_ENV=ON not supported");
2730
  } else {
2731
    _xpg_sus_mode = 0;
2732
  }
2733

2734
  p = ::getenv("LDR_CNTRL");
2735
  trcVerbose("LDR_CNTRL=%s.", p ? p : "<unset>");
2736

2737
  p = ::getenv("AIXTHREAD_GUARDPAGES");
2738
  trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>");
2739

2740
} // end: os::Aix::scan_environment()
2741

2742
void os::Aix::initialize_libperfstat() {
2743
  if (!libperfstat::init()) {
2744
    log_warning(os)("libperfstat initialization failed.");
2745
    assert(false, "libperfstat initialization failed");
2746
  } else {
2747
    trcVerbose("libperfstat initialized.");
2748
  }
2749
}
2750

2751
bool os::Aix::supports_64K_mmap_pages() {
2752
  return g_multipage_support.can_use_64K_mmap_pages;
2753
}
2754

2755
/////////////////////////////////////////////////////////////////////////////
2756
// thread stack
2757

2758
// Get the current stack base and size from the OS (actually, the pthread library).
2759
// Note: base usually not page aligned.
2760
// Returned size is such that (base - size) is always aligned to page size.
2761
void os::current_stack_base_and_size(address* stack_base, size_t* stack_size) {
2762
  AixMisc::stackbounds_t bounds;
2763
  bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);
2764
  guarantee(rc, "Unable to retrieve stack bounds.");
2765
  *stack_base = bounds.base;
2766

2767
  // Align the reported stack size such that the stack low address
2768
  // is aligned to page size (Note: base is usually not and we do not care).
2769
  // We need to do this because caller code will assume stack low address is
2770
  // page aligned and will place guard pages without checking.
2771
  address low = bounds.base - bounds.size;
2772
  address low_aligned = (address)align_up(low, os::vm_page_size());
2773
  *stack_size = bounds.base - low_aligned;
2774
}
2775

2776
// Get the default path to the core file
2777
// Returns the length of the string
2778
int os::get_core_path(char* buffer, size_t bufferSize) {
2779
  const char* p = get_current_directory(buffer, bufferSize);
2780

2781
  if (p == nullptr) {
2782
    assert(p != nullptr, "failed to get current directory");
2783
    return 0;
2784
  }
2785

2786
  jio_snprintf(buffer, bufferSize, "%s/core or core.%d",
2787
                                               p, current_process_id());
2788

2789
  return checked_cast<int>(strlen(buffer));
2790
}
2791

2792
bool os::start_debugging(char *buf, int buflen) {
2793
  int len = (int)strlen(buf);
2794
  char *p = &buf[len];
2795

2796
  jio_snprintf(p, buflen -len,
2797
                 "\n\n"
2798
                 "Do you want to debug the problem?\n\n"
2799
                 "To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n"
2800
                 "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"
2801
                 "Otherwise, press RETURN to abort...",
2802
                 os::current_process_id(),
2803
                 os::current_thread_id(), thread_self());
2804

2805
  bool yes = os::message_box("Unexpected Error", buf);
2806

2807
  if (yes) {
2808
    // yes, user asked VM to launch debugger
2809
    jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id());
2810

2811
    os::fork_and_exec(buf);
2812
    yes = false;
2813
  }
2814
  return yes;
2815
}
2816

2817
static inline time_t get_mtime(const char* filename) {
2818
  struct stat st;
2819
  int ret = os::stat(filename, &st);
2820
  assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));
2821
  return st.st_mtime;
2822
}
2823

2824
int os::compare_file_modified_times(const char* file1, const char* file2) {
2825
  time_t t1 = get_mtime(file1);
2826
  time_t t2 = get_mtime(file2);
2827
  return primitive_compare(t1, t2);
2828
}
2829

2830
bool os::supports_map_sync() {
2831
  return false;
2832
}
2833

2834
void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}
2835

2836
#if INCLUDE_JFR
2837

2838
void os::jfr_report_memory_info() {}
2839

2840
#endif // INCLUDE_JFR
2841

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.