diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp index e20f507a68b2803f2dcfc7d65b762b474de5fa1c..d1cbdccb098aacb2f310c283942692315b8d53ae 100644 --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -1151,6 +1151,7 @@ void nmethod::clear_inline_caches() { // Clear ICStubs of all compiled ICs void nmethod::clear_ic_stubs() { assert_locked_or_safepoint(CompiledIC_lock); + ResourceMark rm; RelocIterator iter(this); while(iter.next()) { if (iter.type() == relocInfo::virtual_call_type) { diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp index 0c92c8876f2945c9a15343fd3226edcedf31ddb9..98624be3271e8230c231769310934b056c1b331a 100644 --- a/src/share/vm/prims/jvmtiEnv.cpp +++ b/src/share/vm/prims/jvmtiEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1000,8 +1000,9 @@ JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count GrowableArray *owned_monitors_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(1, true); - uint32_t debug_bits = 0; - if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { + // It is only safe to perform the direct operation on the current + // thread. All other usage needs to use a vm-safepoint-op for safety. + if (java_thread == calling_thread) { err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); } else { // JVMTI get monitors info at safepoint. Do not require target thread to @@ -1045,8 +1046,9 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i GrowableArray *owned_monitors_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(1, true); - uint32_t debug_bits = 0; - if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { + // It is only safe to perform the direct operation on the current + // thread. All other usage needs to use a vm-safepoint-op for safety. + if (java_thread == calling_thread) { err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); } else { // JVMTI get owned monitors info at safepoint. Do not require target thread to @@ -1087,9 +1089,11 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i jvmtiError JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - uint32_t debug_bits = 0; JavaThread* calling_thread = JavaThread::current(); - if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { + + // It is only safe to perform the direct operation on the current + // thread. All other usage needs to use a vm-safepoint-op for safety. + if (java_thread == calling_thread) { err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr); } else { // get contended monitor information at safepoint. @@ -1298,8 +1302,10 @@ JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jth jvmtiError JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - uint32_t debug_bits = 0; - if (is_thread_fully_suspended(java_thread, true, &debug_bits)) { + + // It is only safe to perform the direct operation on the current + // thread. All other usage needs to use a vm-safepoint-op for safety. + if (java_thread == JavaThread::current()) { err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr); } else { // JVMTI get stack trace at safepoint. Do not require target thread to diff --git a/src/share/vm/prims/jvmtiEnvBase.hpp b/src/share/vm/prims/jvmtiEnvBase.hpp index 084e19b45e4958591bfb3a5a34b327f1880cc068..e8c23b10f05a1fb78cf3c598e6190cff7d6f00a7 100644 --- a/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/src/share/vm/prims/jvmtiEnvBase.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -356,8 +356,12 @@ public: } VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; } void doit() { - ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread, - _owned_monitors_list); + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + if (Threads::includes(_java_thread) && !_java_thread->is_exiting() + && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread, + _owned_monitors_list); + } } jvmtiError result() { return _result; } }; @@ -439,9 +443,13 @@ public: jvmtiError result() { return _result; } VMOp_Type type() const { return VMOp_GetStackTrace; } void doit() { - _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread, - _start_depth, _max_count, - _frame_buffer, _count_ptr); + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + if (Threads::includes(_java_thread) && !_java_thread->is_exiting() + && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread, + _start_depth, _max_count, + _frame_buffer, _count_ptr); + } } }; diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp index 4e269bee1dbc1892c5a6e20d800538e67158982b..e8fc46e75b87b68d6f7d625c7666524a65edeccb 100644 --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1768,10 +1768,39 @@ void Arguments::set_heap_size() { FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction); } - const julong phys_mem = + julong phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM) : (julong)MaxRAM; + // Experimental support for CGroup memory limits + if (UseCGroupMemoryLimitForHeap) { + // This is a rough indicator that a CGroup limit may be in force + // for this process + const char* lim_file = "/sys/fs/cgroup/memory/memory.limit_in_bytes"; + FILE *fp = fopen(lim_file, "r"); + if (fp != NULL) { + julong cgroup_max = 0; + int ret = fscanf(fp, JULONG_FORMAT, &cgroup_max); + if (ret == 1 && cgroup_max > 0) { + // If unlimited, cgroup_max will be a very large, but unspecified + // value, so use initial phys_mem as a limit + if (PrintGCDetails && Verbose) { + // Cannot use gclog_or_tty yet. + tty->print_cr("Setting phys_mem to the min of cgroup limit (" + JULONG_FORMAT "MB) and initial phys_mem (" + JULONG_FORMAT "MB)", cgroup_max/M, phys_mem/M); + } + phys_mem = MIN2(cgroup_max, phys_mem); + } else { + warning("Unable to read/parse cgroup memory limit from %s: %s", + lim_file, errno != 0 ? strerror(errno) : "unknown error"); + } + fclose(fp); + } else { + warning("Unable to open cgroup memory limit file %s (%s)", lim_file, strerror(errno)); + } + } + // If the maximum heap size has not been set with -Xmx, // then set it as fraction of the size of physical memory, // respecting the maximum and minimum sizes of the heap. diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index c76ced47fd8e2120e2b707f28f1d14cd03d9a0d3..6c9bd3b05cc99c19d73d251288124c51d167d714 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2068,6 +2068,10 @@ class CommandLineFlags { "Maximum ergonomically set heap size (in bytes); zero means use " \ "MaxRAM / MaxRAMFraction") \ \ + experimental(bool, UseCGroupMemoryLimitForHeap, false, \ + "Use CGroup memory limit as physical memory limit for heap " \ + "sizing") \ + \ product(uintx, MaxRAMFraction, 4, \ "Maximum fraction (1/n) of real memory used for maximum heap " \ "size") \ diff --git a/src/share/vm/runtime/sweeper.cpp b/src/share/vm/runtime/sweeper.cpp index b4954ff861559b6f7b07712c970359b150d140ee..ba4ce2da2bc72b14a0a68c2b178be3fde6d01d2b 100644 --- a/src/share/vm/runtime/sweeper.cpp +++ b/src/share/vm/runtime/sweeper.cpp @@ -319,6 +319,7 @@ void NMethodSweeper::possibly_sweep() { } void NMethodSweeper::sweep_code_cache() { + ResourceMark rm; Ticks sweep_start_counter = Ticks::now(); _flushed_count = 0; @@ -626,6 +627,7 @@ int NMethodSweeper::process_nmethod(nmethod *nm) { // state of the code cache if it's requested. void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { if (PrintMethodFlushing) { + ResourceMark rm; stringStream s; // Dump code cache state into a buffer before locking the tty, // because log_state() will use locks causing lock conflicts. @@ -643,6 +645,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { } if (LogCompilation && (xtty != NULL)) { + ResourceMark rm; stringStream s; // Dump code cache state into a buffer before locking the tty, // because log_state() will use locks causing lock conflicts.