Merge JDK-8200758-branch
authorherrick
Wed, 27 Mar 2019 08:27:58 -0400
branchJDK-8200758-branch
changeset 57288 0be43184f52a
parent 57287 90fa9a095959 (current diff)
parent 54306 828c4889adfc (diff)
child 57289 1a93286f0767
Merge
test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest
test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-aarch64
test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-ppc64le
test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-s390x
test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest
test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-aarch64
test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-ppc64le
test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-s390x
--- a/make/hotspot/lib/JvmFeatures.gmk	Wed Mar 27 07:45:21 2019 -0400
+++ b/make/hotspot/lib/JvmFeatures.gmk	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2019, 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
@@ -126,7 +126,7 @@
   JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0
   JVM_EXCLUDE_FILES += \
       memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \
-      memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
+      memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp threadStackTracker.cpp
 endif
 
 ifneq ($(call check-jvm-feature, aot), true)
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -901,11 +901,15 @@
     FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
   }
 
+#ifdef _LP64
+  // These are only supported on 64-bit
   if (UseSHA && supports_avx2() && supports_bmi2()) {
     if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
       FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
     }
-  } else if (UseSHA512Intrinsics) {
+  } else
+#endif
+  if (UseSHA512Intrinsics) {
     warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
     FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
   }
--- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019 SAP SE. 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
@@ -63,7 +63,7 @@
 
     if (ret_frame.is_interpreted_frame()) {
       frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked();
-       if (!((Method*)(istate->method))->is_metaspace_object()) {
+       if ((stack_base() >= (address)istate && (address)istate > stack_end()) || !((Method*)(istate->method))->is_metaspace_object()) {
          return false;
        }
        uint64_t reg_bcp = uc->uc_mcontext.gregs[13/*Z_BCP*/];
--- a/src/hotspot/share/gc/shared/concurrentGCThread.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/gc/shared/concurrentGCThread.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -54,13 +54,6 @@
   assert(this == Thread::current(), "just checking");
 }
 
-void ConcurrentGCThread::wait_for_universe_init() {
-  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
-  while (!is_init_completed() && !_should_terminate) {
-    CGC_lock->wait(Mutex::_no_safepoint_check_flag, 1);
-  }
-}
-
 void ConcurrentGCThread::terminate() {
   assert(_should_terminate, "Should only be called on terminate request.");
   // Signal that it is terminated
@@ -74,7 +67,7 @@
 
 void ConcurrentGCThread::run() {
   initialize_in_thread();
-  wait_for_universe_init();
+  wait_init_completed();
 
   run_service();
 
--- a/src/hotspot/share/gc/z/zNMethodTableEntry.hpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/gc/z/zNMethodTableEntry.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -37,13 +37,11 @@
 //  |11111111 11111111 11111111 11111111 11111111 11111111 11111111 111111|1|1|
 //  +---------------------------------------------------------------------+-+-+
 //  |                                                                     | |
-//  |                                                                     | |
-//  |                                                                     | |
 //  |                                      1-1 Unregistered Flag (1-bits) * |
 //  |                                                                       |
 //  |                                          0-0 Registered Flag (1-bits) *
 //  |
-//  * 63-3 NMethod Address (61-bits)
+//  * 63-2 NMethod Address (62-bits)
 //
 
 class nmethod;
--- a/src/hotspot/share/opto/graphKit.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/opto/graphKit.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -2450,6 +2450,8 @@
                                   Node* parm2, Node* parm3,
                                   Node* parm4, Node* parm5,
                                   Node* parm6, Node* parm7) {
+  assert(call_addr != NULL, "must not call NULL targets");
+
   // Slow-path call
   bool is_leaf = !(flags & RC_NO_LEAF);
   bool has_io  = (!is_leaf && !(flags & RC_NO_IO));
--- a/src/hotspot/share/opto/library_call.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/opto/library_call.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -6353,6 +6353,9 @@
   }
   if (state == NULL) return false;
 
+  assert(stubAddr != NULL, "Stub is generated");
+  if (stubAddr == NULL) return false;
+
   // Call the stub.
   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::sha_implCompress_Type(),
                                  stubAddr, stubName, TypePtr::BOTTOM,
@@ -6425,6 +6428,9 @@
     fatal("unknown SHA intrinsic predicate: %d", predicate);
   }
   if (klass_SHA_name != NULL) {
+    assert(stub_addr != NULL, "Stub is generated");
+    if (stub_addr == NULL) return false;
+
     // get DigestBase klass to lookup for SHA klass
     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
     assert(tinst != NULL, "digestBase_obj is not instance???");
--- a/src/hotspot/share/runtime/init.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/init.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -36,6 +36,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/init.hpp"
+#include "runtime/orderAccess.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "services/memTracker.hpp"
@@ -186,11 +187,19 @@
 static volatile bool _init_completed = false;
 
 bool is_init_completed() {
-  return _init_completed;
+  return OrderAccess::load_acquire(&_init_completed);
 }
 
+void wait_init_completed() {
+  MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag);
+  while (!_init_completed) {
+    ml.wait(Monitor::_no_safepoint_check_flag);
+  }
+}
 
 void set_init_completed() {
   assert(Universe::is_fully_initialized(), "Should have completed initialization");
-  _init_completed = true;
+  MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag);
+  OrderAccess::release_store(&_init_completed, true);
+  ml.notify_all();
 }
--- a/src/hotspot/share/runtime/init.hpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/init.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -40,6 +40,7 @@
 void exit_globals();     // call destructors before exit
 
 bool is_init_completed();     // returns true when bootstrapping has completed
+void wait_init_completed();   // wait until set_init_completed() has been called
 void set_init_completed();    // set basic init to completed
 
 #endif // SHARE_RUNTIME_INIT_HPP
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -97,6 +97,7 @@
 Mutex*   DirectivesStack_lock         = NULL;
 Mutex*   MultiArray_lock              = NULL;
 Monitor* Terminator_lock              = NULL;
+Monitor* InitCompleted_lock           = NULL;
 Monitor* BeforeExit_lock              = NULL;
 Monitor* Notify_lock                  = NULL;
 Mutex*   ProfilePrint_lock            = NULL;
@@ -283,6 +284,7 @@
   def(VMOperationRequest_lock      , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
   def(RetData_lock                 , PaddedMutex  , nonleaf,     false, Monitor::_safepoint_check_always);
   def(Terminator_lock              , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
+  def(InitCompleted_lock           , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
   def(VtableStubs_lock             , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
   def(Notify_lock                  , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always);
   def(JNIGlobalAlloc_lock          , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -96,6 +96,7 @@
 extern Mutex*   DirectivesStack_lock;            // a lock held when mutating the dirstack and ref counting directives
 extern Mutex*   MultiArray_lock;                 // a lock used to guard allocation of multi-dim arrays
 extern Monitor* Terminator_lock;                 // a lock used to guard termination of the vm
+extern Monitor* InitCompleted_lock;              // a lock used to signal threads waiting on init completed
 extern Monitor* BeforeExit_lock;                 // a lock used to guard cleanups and shutdown hooks
 extern Monitor* Notify_lock;                     // a lock used to synchronize the start-up of the vm
 extern Mutex*   ProfilePrint_lock;               // a lock used to serialize the printing of profiles
--- a/src/hotspot/share/runtime/synchronizer.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -1270,6 +1270,21 @@
   }
 
   Thread::muxRelease(&gListLock);
+
+  LogStreamHandle(Debug, monitorinflation) lsh_debug;
+  LogStreamHandle(Info, monitorinflation) lsh_info;
+  LogStream * ls = NULL;
+  if (log_is_enabled(Debug, monitorinflation)) {
+    ls = &lsh_debug;
+  } else if ((tally != 0 || inUseTally != 0) &&
+             log_is_enabled(Info, monitorinflation)) {
+    ls = &lsh_info;
+  }
+  if (ls != NULL) {
+    ls->print_cr("omFlush: jt=" INTPTR_FORMAT ", free_monitor_tally=%d"
+                 ", in_use_monitor_tally=%d" ", omFreeProvision=%d",
+                 p2i(Self), tally, inUseTally, Self->omFreeProvision);
+  }
 }
 
 static void post_monitor_inflate_event(EventJavaMonitorInflate* event,
@@ -1665,24 +1680,18 @@
   // than a beginning to end measurement of the phase.
   log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->perThreadTimes, counters->perThreadScavenged);
 
-  LogStreamHandle(Debug, monitorinflation) lsh_debug;
-  LogStreamHandle(Info, monitorinflation) lsh_info;
-  LogStream * ls = NULL;
-  if (log_is_enabled(Debug, monitorinflation)) {
-    ls = &lsh_debug;
-  } else if (counters->perThreadScavenged != 0 && log_is_enabled(Info, monitorinflation)) {
-    ls = &lsh_info;
-  }
-  if (ls != NULL) {
-    ls->print_cr("deflating per-thread idle monitors, %3.7f secs, %d monitors", counters->perThreadTimes, counters->perThreadScavenged);
-  }
-
   gMonitorFreeCount += counters->nScavenged;
 
   if (log_is_enabled(Debug, monitorinflation)) {
     // exit_globals()'s call to audit_and_print_stats() is done
     // at the Info level.
     ObjectSynchronizer::audit_and_print_stats(false /* on_exit */);
+  } else if (log_is_enabled(Info, monitorinflation)) {
+    Thread::muxAcquire(&gListLock, "finish_deflate_idle_monitors");
+    log_info(monitorinflation)("gMonitorPopulation=%d, gOmInUseCount=%d, "
+                               "gMonitorFreeCount=%d", gMonitorPopulation,
+                               gOmInUseCount, gMonitorFreeCount);
+    Thread::muxRelease(&gListLock);
   }
 
   ForceMonitorScavenge = 0;    // Reset
@@ -1708,8 +1717,6 @@
 
   int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
 
-  timer.stop();
-
   Thread::muxAcquire(&gListLock, "deflate_thread_local_monitors");
 
   // Adjust counters
@@ -1718,8 +1725,6 @@
   counters->nScavenged += deflated_count;
   counters->nInuse += thread->omInUseCount;
   counters->perThreadScavenged += deflated_count;
-  // For now, we only care about cumulative per-thread deflation time.
-  counters->perThreadTimes += timer.seconds();
 
   // Move the scavenged monitors back to the global free list.
   if (freeHeadp != NULL) {
@@ -1730,7 +1735,26 @@
     freeTailp->FreeNext = gFreeList;
     gFreeList = freeHeadp;
   }
+
+  timer.stop();
+  // Safepoint logging cares about cumulative perThreadTimes and
+  // we'll capture most of the cost, but not the muxRelease() which
+  // should be cheap.
+  counters->perThreadTimes += timer.seconds();
+
   Thread::muxRelease(&gListLock);
+
+  LogStreamHandle(Debug, monitorinflation) lsh_debug;
+  LogStreamHandle(Info, monitorinflation) lsh_info;
+  LogStream * ls = NULL;
+  if (log_is_enabled(Debug, monitorinflation)) {
+    ls = &lsh_debug;
+  } else if (deflated_count != 0 && log_is_enabled(Info, monitorinflation)) {
+    ls = &lsh_info;
+  }
+  if (ls != NULL) {
+    ls->print_cr("jt=" INTPTR_FORMAT ": deflating per-thread idle monitors, %3.7f secs, %d monitors", p2i(thread), timer.seconds(), deflated_count);
+  }
 }
 
 // Monitor cleanup on JavaThread::exit
@@ -1839,13 +1863,13 @@
 
   // Check gMonitorPopulation:
   if (gMonitorPopulation == chkMonitorPopulation) {
-     ls->print_cr("gMonitorPopulation=%d equals chkMonitorPopulation=%d",
-                  gMonitorPopulation, chkMonitorPopulation);
+    ls->print_cr("gMonitorPopulation=%d equals chkMonitorPopulation=%d",
+                 gMonitorPopulation, chkMonitorPopulation);
   } else {
-     ls->print_cr("ERROR: gMonitorPopulation=%d is not equal to "
-                  "chkMonitorPopulation=%d", gMonitorPopulation,
-                  chkMonitorPopulation);
-     error_cnt++;
+    ls->print_cr("ERROR: gMonitorPopulation=%d is not equal to "
+                 "chkMonitorPopulation=%d", gMonitorPopulation,
+                 chkMonitorPopulation);
+    error_cnt++;
   }
 
   // Check gOmInUseList and gOmInUseCount:
--- a/src/hotspot/share/runtime/synchronizer.hpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -199,11 +199,11 @@
   static u_char* get_gvars_stwRandom_addr();
 };
 
-// ObjectLocker enforced balanced locking and can never thrown an
+// ObjectLocker enforces balanced locking and can never throw an
 // IllegalMonitorStateException. However, a pending exception may
 // have to pass through, and we must also be able to deal with
 // asynchronous exceptions. The caller is responsible for checking
-// the threads pending exception if needed.
+// the thread's pending exception if needed.
 class ObjectLocker : public StackObj {
  private:
   Thread*   _thread;
--- a/src/hotspot/share/runtime/thread.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/runtime/thread.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -4449,7 +4449,7 @@
 
 void Threads::remove(JavaThread* p) {
 
-  // Reclaim the objectmonitors from the omInUseList and omFreeList of the moribund thread.
+  // Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
   ObjectSynchronizer::omFlush(p);
 
   // Extra scope needed for Thread_lock, so we can check
--- a/src/hotspot/share/services/memBaseline.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/services/memBaseline.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -156,6 +156,11 @@
     return false;
   }
 
+  // Walk simple thread stacks
+  if (!ThreadStackTracker::walk_simple_thread_stack_site(&malloc_walker)) {
+    return false;
+  }
+
   _malloc_sites.move(malloc_walker.malloc_sites());
   // The malloc sites are collected in size order
   _malloc_sites_order = by_size;
--- a/src/hotspot/share/services/memReporter.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/services/memReporter.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -26,6 +26,7 @@
 #include "memory/allocation.hpp"
 #include "services/mallocTracker.hpp"
 #include "services/memReporter.hpp"
+#include "services/threadStackTracker.hpp"
 #include "services/virtualMemoryTracker.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -46,11 +47,13 @@
 void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) const {
   const char* scale = current_scale();
   outputStream* out = output();
+  const char* alloc_type = (flag == mtThreadStack) ? "" : "malloc=";
+
   if (flag != mtNone) {
-    out->print("(malloc=" SIZE_FORMAT "%s type=%s",
+    out->print("(%s" SIZE_FORMAT "%s type=%s", alloc_type,
       amount_in_current_scale(amount), scale, NMTUtil::flag_to_name(flag));
   } else {
-    out->print("(malloc=" SIZE_FORMAT "%s",
+    out->print("(%s" SIZE_FORMAT "%s", alloc_type,
       amount_in_current_scale(amount), scale);
   }
 
@@ -126,10 +129,17 @@
 
   // Count thread's native stack in "Thread" category
   if (flag == mtThread) {
-    const VirtualMemory* thread_stack_usage =
-      (const VirtualMemory*)_vm_snapshot->by_type(mtThreadStack);
-    reserved_amount  += thread_stack_usage->reserved();
-    committed_amount += thread_stack_usage->committed();
+    if (ThreadStackTracker::track_as_vm()) {
+      const VirtualMemory* thread_stack_usage =
+        (const VirtualMemory*)_vm_snapshot->by_type(mtThreadStack);
+      reserved_amount  += thread_stack_usage->reserved();
+      committed_amount += thread_stack_usage->committed();
+    } else {
+      const MallocMemory* thread_stack_usage =
+        (const MallocMemory*)_malloc_snapshot->by_type(mtThreadStack);
+      reserved_amount += thread_stack_usage->malloc_size();
+      committed_amount += thread_stack_usage->malloc_size();
+    }
   } else if (flag == mtNMT) {
     // Count malloc headers in "NMT" category
     reserved_amount  += _malloc_snapshot->malloc_overhead()->size();
@@ -150,12 +160,22 @@
       out->print_cr("%27s (  instance classes #" SIZE_FORMAT ", array classes #" SIZE_FORMAT ")",
         " ", _instance_class_count, _array_class_count);
     } else if (flag == mtThread) {
-      // report thread count
-      out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", _malloc_snapshot->thread_count());
-      const VirtualMemory* thread_stack_usage =
-       _vm_snapshot->by_type(mtThreadStack);
-      out->print("%27s (stack: ", " ");
-      print_total(thread_stack_usage->reserved(), thread_stack_usage->committed());
+      if (ThreadStackTracker::track_as_vm()) {
+        const VirtualMemory* thread_stack_usage =
+         _vm_snapshot->by_type(mtThreadStack);
+        // report thread count
+        out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", ThreadStackTracker::thread_count());
+        out->print("%27s (stack: ", " ");
+        print_total(thread_stack_usage->reserved(), thread_stack_usage->committed());
+      } else {
+        MallocMemory* thread_stack_memory = _malloc_snapshot->by_type(mtThreadStack);
+        const char* scale = current_scale();
+        // report thread count
+        assert(ThreadStackTracker::thread_count() == 0, "Not used");
+        out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", thread_stack_memory->malloc_count());
+        out->print("%27s (Stack: " SIZE_FORMAT "%s", " ",
+          amount_in_current_scale(thread_stack_memory->malloc_size()), scale);
+      }
       out->print_cr(")");
     }
 
@@ -368,10 +388,11 @@
     size_t early_amount, size_t early_count, MEMFLAGS flags) const {
   const char* scale = current_scale();
   outputStream* out = output();
+  const char* alloc_type = (flags == mtThread) ? "" : "malloc=";
 
-  out->print("malloc=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
-  // Report type only if it is valid
-  if (flags != mtNone) {
+  out->print("%s" SIZE_FORMAT "%s", alloc_type, amount_in_current_scale(current_amount), scale);
+  // Report type only if it is valid and not under "thread" category
+  if (flags != mtNone && flags != mtThread) {
     out->print(" type=%s", NMTUtil::flag_to_name(flags));
   }
 
@@ -497,15 +518,25 @@
       }
       out->print_cr(")");
 
-      // report thread stack
-      const VirtualMemory* current_thread_stack =
+      out->print("%27s (stack: ", " ");
+      if (ThreadStackTracker::track_as_vm()) {
+        // report thread stack
+        const VirtualMemory* current_thread_stack =
           _current_baseline.virtual_memory(mtThreadStack);
-      const VirtualMemory* early_thread_stack =
-        _early_baseline.virtual_memory(mtThreadStack);
+        const VirtualMemory* early_thread_stack =
+          _early_baseline.virtual_memory(mtThreadStack);
 
-      out->print("%27s (stack: ", " ");
-      print_virtual_memory_diff(current_thread_stack->reserved(), current_thread_stack->committed(),
-        early_thread_stack->reserved(), early_thread_stack->committed());
+        print_virtual_memory_diff(current_thread_stack->reserved(), current_thread_stack->committed(),
+          early_thread_stack->reserved(), early_thread_stack->committed());
+      } else {
+        const MallocMemory* current_thread_stack =
+          _current_baseline.malloc_memory(mtThreadStack);
+        const MallocMemory* early_thread_stack =
+          _early_baseline.malloc_memory(mtThreadStack);
+
+        print_malloc_diff(current_thread_stack->malloc_size(), current_thread_stack->malloc_count(),
+          early_thread_stack->malloc_size(), early_thread_stack->malloc_count(), flag);
+      }
       out->print_cr(")");
     }
 
--- a/src/hotspot/share/services/memTracker.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/services/memTracker.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -31,6 +31,7 @@
 #include "services/memReporter.hpp"
 #include "services/mallocTracker.inline.hpp"
 #include "services/memTracker.hpp"
+#include "services/threadStackTracker.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/vmError.hpp"
@@ -92,7 +93,8 @@
 void MemTracker::init() {
   NMT_TrackingLevel level = tracking_level();
   if (level >= NMT_summary) {
-    if (!VirtualMemoryTracker::late_initialize(level)) {
+    if (!VirtualMemoryTracker::late_initialize(level) ||
+        !ThreadStackTracker::late_initialize(level)) {
       shutdown();
       return;
     }
@@ -164,6 +166,7 @@
     OrderAccess::fence();
     VirtualMemoryTracker::transition(current_level, level);
     MallocTracker::transition(current_level, level);
+    ThreadStackTracker::transition(current_level, level);
   } else {
     // Upgrading tracking level is not supported and has never been supported.
     // Allocating and deallocating malloc tracking structures is not thread safe and
--- a/src/hotspot/share/services/memTracker.hpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/services/memTracker.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -82,6 +82,7 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/threadCritical.hpp"
 #include "services/mallocTracker.hpp"
+#include "services/threadStackTracker.hpp"
 #include "services/virtualMemoryTracker.hpp"
 
 extern volatile bool NMT_stack_walkable;
@@ -241,31 +242,19 @@
     }
   }
 
-#ifdef _AIX
-  // See JDK-8202772 - temporarily disable thread stack tracking on AIX.
-  static inline void record_thread_stack(void* addr, size_t size) {}
-  static inline void release_thread_stack(void* addr, size_t size) {}
-#else
-  static inline void record_thread_stack(void* addr, size_t size) {
+  static void record_thread_stack(void* addr, size_t size) {
     if (tracking_level() < NMT_summary) return;
     if (addr != NULL) {
-      // uses thread stack malloc slot for book keeping number of threads
-      MallocMemorySummary::record_malloc(0, mtThreadStack);
-      record_virtual_memory_reserve(addr, size, CALLER_PC, mtThreadStack);
+      ThreadStackTracker::new_thread_stack((address)addr, size, CALLER_PC);
     }
   }
 
   static inline void release_thread_stack(void* addr, size_t size) {
     if (tracking_level() < NMT_summary) return;
     if (addr != NULL) {
-      // uses thread stack malloc slot for book keeping number of threads
-      MallocMemorySummary::record_free(0, mtThreadStack);
-      ThreadCritical tc;
-      if (tracking_level() < NMT_summary) return;
-      VirtualMemoryTracker::remove_released_region((address)addr, size);
+      ThreadStackTracker::delete_thread_stack((address)addr, size);
     }
   }
-#endif
 
   // Query lock is used to synchronize the access to tracking data.
   // So far, it is only used by JCmd query, but it may be used by
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/services/threadStackTracker.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "runtime/atomic.hpp"
+#include "runtime/threadCritical.hpp"
+#include "services/mallocTracker.hpp"
+#include "services/memTracker.hpp"
+#include "services/virtualMemoryTracker.hpp"
+#include "services/threadStackTracker.hpp"
+
+volatile size_t ThreadStackTracker::_thread_count = 0;
+SortedLinkedList<SimpleThreadStackSite, ThreadStackTracker::compare_thread_stack_base>* ThreadStackTracker::_simple_thread_stacks = NULL;
+
+bool ThreadStackTracker::late_initialize(NMT_TrackingLevel level) {
+  if (level == NMT_detail && !track_as_vm()) {
+    _simple_thread_stacks = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
+      SortedLinkedList<SimpleThreadStackSite, ThreadStackTracker::compare_thread_stack_base>();
+    return (_simple_thread_stacks != NULL);
+  }
+  return true;
+}
+
+bool ThreadStackTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) {
+  assert (from != NMT_minimal, "cannot convert from the lowest tracking level to anything");
+  if (to == NMT_minimal) {
+    assert(from == NMT_summary || from == NMT_detail, "Just check");
+    ThreadCritical tc;
+    if (_simple_thread_stacks != NULL) {
+      delete _simple_thread_stacks;
+      _simple_thread_stacks = NULL;
+    }
+  }
+  return true;
+}
+
+int ThreadStackTracker::compare_thread_stack_base(const SimpleThreadStackSite& s1, const SimpleThreadStackSite& s2) {
+  return s1.base() - s2.base();
+}
+
+void ThreadStackTracker::new_thread_stack(void* base, size_t size, const NativeCallStack& stack) {
+  assert(MemTracker::tracking_level() >= NMT_summary, "Must be");
+  assert(base != NULL, "Should have been filtered");
+  if (track_as_vm()) {
+    ThreadCritical tc;
+    VirtualMemoryTracker::add_reserved_region((address)base, size, stack, mtThreadStack);
+    _thread_count ++;
+  } else {
+    // Use a slot in mallocMemorySummary for thread stack bookkeeping
+    MallocMemorySummary::record_malloc(size, mtThreadStack);
+    if (MemTracker::tracking_level() == NMT_detail) {
+      ThreadCritical tc;
+      assert(_simple_thread_stacks != NULL, "Must be initialized");
+      SimpleThreadStackSite site((address)base, size, stack);
+      _simple_thread_stacks->add(site);
+    }
+  }
+}
+
+void ThreadStackTracker::delete_thread_stack(void* base, size_t size) {
+  assert(MemTracker::tracking_level() >= NMT_summary, "Must be");
+  assert(base != NULL, "Should have been filtered");
+  if(track_as_vm()) {
+    ThreadCritical tc;
+    VirtualMemoryTracker::remove_released_region((address)base, size);
+    _thread_count--;
+  } else {
+    // Use a slot in mallocMemorySummary for thread stack bookkeeping
+    MallocMemorySummary::record_free(size, mtThreadStack);
+    if (MemTracker::tracking_level() == NMT_detail) {
+      ThreadCritical tc;
+      assert(_simple_thread_stacks != NULL, "Must be initialized");
+      SimpleThreadStackSite site((address)base, size);
+      bool removed = _simple_thread_stacks->remove(site);
+      assert(removed, "Must exist");
+    }
+  }
+}
+
+bool ThreadStackTracker::walk_simple_thread_stack_site(MallocSiteWalker* walker) {
+  if (!track_as_vm()) {
+    LinkedListImpl<MallocSite> _sites;
+    {
+      ThreadCritical tc;
+      assert(_simple_thread_stacks != NULL, "Must be initialized");
+      LinkedListIterator<SimpleThreadStackSite> itr(_simple_thread_stacks->head());
+      const SimpleThreadStackSite* ts = itr.next();
+      // Consolidate sites and convert to MallocSites, so we can piggyback into
+      // malloc snapshot
+      while (ts != NULL) {
+        MallocSite site(*ts->call_stack(), mtThreadStack);
+        MallocSite* exist = _sites.find(site);
+        if (exist != NULL) {
+          exist->allocate(ts->size());
+        } else {
+          site.allocate(ts->size());
+          _sites.add(site);
+        }
+        ts = itr.next();
+      }
+    }
+
+    // Piggyback to malloc snapshot
+    LinkedListIterator<MallocSite> site_itr(_sites.head());
+    const MallocSite* s = site_itr.next();
+    while (s != NULL) {
+      walker->do_malloc_site(s);
+      s = site_itr.next();
+    }
+  }
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/services/threadStackTracker.hpp	Wed Mar 27 08:27:58 2019 -0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_SERVICES_THREADSTACKTRACKER_HPP
+#define SHARE_SERVICES_THREADSTACKTRACKER_HPP
+
+#if INCLUDE_NMT
+
+#include "services/allocationSite.hpp"
+#include "services/mallocSiteTable.hpp"
+#include "services/nmtCommon.hpp"
+#include "utilities/nativeCallStack.hpp"
+#include "utilities/linkedlist.hpp"
+
+class SimpleThreadStackSite;
+
+class SimpleThreadStack {
+  friend class SimpleThreadStackSite;
+private:
+  address _base;
+  size_t  _size;
+public:
+  SimpleThreadStack() : _base(NULL), _size(0) { }
+  bool equals(const SimpleThreadStack& s) const {
+    return base() == s.base();
+  }
+
+  size_t  size() const { return _size; }
+  address base() const { return _base; }
+private:
+  void set_size(size_t size)  { _size = size; }
+  void set_base(address base) { _base = base; }
+};
+
+class SimpleThreadStackSite : public AllocationSite<SimpleThreadStack> {
+public:
+  SimpleThreadStackSite(address base, size_t size, const NativeCallStack& stack) :
+    AllocationSite<SimpleThreadStack>(stack, mtThreadStack) {
+    data()->set_size(size);
+    data()->set_base(base);
+  }
+
+  SimpleThreadStackSite(address base, size_t size) :
+    AllocationSite<SimpleThreadStack>(NativeCallStack::empty_stack(), mtThreadStack) {
+    data()->set_base(base);
+    data()->set_size(size);
+  }
+
+  bool equals(const SimpleThreadStackSite& mts) const {
+    bool eq = base() == mts.base();
+    assert(!eq || size() == mts.size(), "Must match");
+    return eq;
+  }
+
+  size_t  size() const { return peek()->size(); }
+  address base() const { return peek()->base(); }
+};
+
+  /*
+   * Most of platforms, that hotspot support, have their thread stacks backed by
+   * virtual memory by default. For these cases, thread stack tracker simply
+   * delegates tracking to virtual memory tracker.
+   * However, there are exceptions, (e.g. AIX), that platforms can provide stacks
+   * that are not page aligned. A hypothetical VM implementation, it can provide
+   * it own stacks. In these case, track_as_vm() should return false and manage
+   * stack tracking by this tracker internally.
+   * During memory snapshot, tracked thread stacks memory data is walked and stored
+   * along with malloc'd data inside baseline. The regions are not scanned and assumed
+   * all committed for now. Can add scanning phase when there is a need.
+   */
+class ThreadStackTracker : AllStatic {
+private:
+  static volatile size_t _thread_count;
+
+  static int compare_thread_stack_base(const SimpleThreadStackSite& s1, const SimpleThreadStackSite& s2);
+  static SortedLinkedList<SimpleThreadStackSite, compare_thread_stack_base>* _simple_thread_stacks;
+public:
+  // Late phase initialization
+  static bool late_initialize(NMT_TrackingLevel level);
+  static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to);
+
+  static void new_thread_stack(void* base, size_t size, const NativeCallStack& stack);
+  static void delete_thread_stack(void* base, size_t size);
+
+  static bool   track_as_vm()  { return AIX_ONLY(false) NOT_AIX(true); }
+  static size_t thread_count() { return _thread_count; }
+
+  // Snapshot support. Piggyback thread stack data in malloc slot, NMT always handles
+  // thread stack slot specially since beginning.
+  static bool walk_simple_thread_stack_site(MallocSiteWalker* walker);
+};
+
+#endif // INCLUDE_NMT
+#endif // SHARE_SERVICES_THREADSTACKTRACKER_HPP
--- a/src/hotspot/share/services/virtualMemoryTracker.cpp	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/hotspot/share/services/virtualMemoryTracker.cpp	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -29,6 +29,7 @@
 #include "runtime/os.hpp"
 #include "runtime/threadCritical.hpp"
 #include "services/memTracker.hpp"
+#include "services/threadStackTracker.hpp"
 #include "services/virtualMemoryTracker.hpp"
 
 size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
@@ -40,9 +41,12 @@
 }
 
 void VirtualMemorySummary::snapshot(VirtualMemorySnapshot* s) {
-  // Snapshot current thread stacks
-  VirtualMemoryTracker::snapshot_thread_stacks();
-  as_snapshot()->copy_to(s);
+  // Only if thread stack is backed by virtual memory
+  if (ThreadStackTracker::track_as_vm()) {
+    // Snapshot current thread stacks
+    VirtualMemoryTracker::snapshot_thread_stacks();
+    as_snapshot()->copy_to(s);
+  }
 }
 
 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions;
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Mar 27 08:27:58 2019 -0400
@@ -422,6 +422,10 @@
      * because the desired class member is missing, or because the
      * desired class member is not accessible to the lookup class, or
      * because the lookup object is not trusted enough to access the member.
+     * In the case of a field setter function on a {@code final} field,
+     * finality enforcement is treated as a kind of access control,
+     * and the lookup will fail, except in special cases of
+     * {@link Lookup#unreflectSetter Lookup.unreflectSetter}.
      * In any of these cases, a {@code ReflectiveOperationException} will be
      * thrown from the attempted lookup.  The exact class will be one of
      * the following:
@@ -1438,6 +1442,7 @@
          * @return a method handle which can store values into the field
          * @throws NoSuchFieldException if the field does not exist
          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+         *                                or {@code final}
          * @exception SecurityException if a security manager is present and it
          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws NullPointerException if any argument is null
@@ -1561,6 +1566,7 @@
          * @return a method handle which can store values into the field
          * @throws NoSuchFieldException if the field does not exist
          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+         *                                or is {@code final}
          * @exception SecurityException if a security manager is present and it
          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws NullPointerException if any argument is null
@@ -1840,10 +1846,10 @@
          * Produces a method handle giving read access to a reflected field.
          * The type of the method handle will have a return type of the field's
          * value type.
-         * If the field is static, the method handle will take no arguments.
+         * If the field is {@code static}, the method handle will take no arguments.
          * Otherwise, its single argument will be the instance containing
          * the field.
-         * If the field's {@code accessible} flag is not set,
+         * If the {@code Field} object's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class.
          * <p>
          * If the field is static, and
@@ -1857,8 +1863,43 @@
         public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
             return unreflectField(f, false);
         }
+
+        /**
+         * Produces a method handle giving write access to a reflected field.
+         * The type of the method handle will have a void return type.
+         * If the field is {@code static}, the method handle will take a single
+         * argument, of the field's value type, the value to be stored.
+         * Otherwise, the two arguments will be the instance containing
+         * the field, and the value to be stored.
+         * If the {@code Field} object's {@code accessible} flag is not set,
+         * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the field is {@code final}, write access will not be
+         * allowed and access checking will fail, except under certain
+         * narrow circumstances documented for {@link Field#set Field.set}.
+         * A method handle is returned only if a corresponding call to
+         * the {@code Field} object's {@code set} method could return
+         * normally.  In particular, fields which are both {@code static}
+         * and {@code final} may never be set.
+         * <p>
+         * If the field is {@code static}, and
+         * if the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
+         * @param f the reflected field
+         * @return a method handle which can store values into the reflected field
+         * @throws IllegalAccessException if access checking fails,
+         *         or if the field is {@code final} and write access
+         *         is not enabled on the {@code Field} object
+         * @throws NullPointerException if the argument is null
+         */
+        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
+            return unreflectField(f, true);
+        }
+
         private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
             MemberName field = new MemberName(f, isSetter);
+            if (isSetter && field.isStatic() && field.isFinal())
+                throw field.makeAccessException("static final field has no write access", this);
             assert(isSetter
                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
@@ -1868,28 +1909,6 @@
         }
 
         /**
-         * Produces a method handle giving write access to a reflected field.
-         * The type of the method handle will have a void return type.
-         * If the field is static, the method handle will take a single
-         * argument, of the field's value type, the value to be stored.
-         * Otherwise, the two arguments will be the instance containing
-         * the field, and the value to be stored.
-         * If the field's {@code accessible} flag is not set,
-         * access checking is performed immediately on behalf of the lookup class.
-         * <p>
-         * If the field is static, and
-         * if the returned method handle is invoked, the field's class will
-         * be initialized, if it has not already been initialized.
-         * @param f the reflected field
-         * @return a method handle which can store values into the reflected field
-         * @throws IllegalAccessException if access checking fails
-         * @throws NullPointerException if the argument is null
-         */
-        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
-            return unreflectField(f, true);
-        }
-
-        /**
          * Produces a VarHandle giving access to a reflected field {@code f}
          * of type {@code T} declared in a class of type {@code R}.
          * The VarHandle's variable type is {@code T}.
--- a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java	Wed Mar 27 08:27:58 2019 -0400
@@ -28,9 +28,11 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 /**
  * File manager based on {@linkplain File java.io.File} and {@linkplain Path java.nio.file.Path}.
@@ -199,11 +201,40 @@
      * a directory or if this file manager does not support any of the
      * given paths.
      *
-     * @since 9
+     * @since 13
      */
     default Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
+            Collection<? extends Path> paths) {
+        return getJavaFileObjectsFromFiles(asFiles(paths));
+    }
+
+    /**
+     * Returns file objects representing the given paths.
+     *
+     * @implSpec
+     * The default implementation converts each path to a file and calls
+     * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}.
+     * IllegalArgumentException will be thrown if any of the paths
+     * cannot be converted to a file.
+     *
+     * @param paths a list of paths
+     * @return a list of file objects
+     * @throws IllegalArgumentException if the list of paths includes
+     * a directory or if this file manager does not support any of the
+     * given paths.
+     *
+     * @since 9
+     * @deprecated use {@link #getJavaFileObjectsFromPaths(Collection)} instead,
+     * to prevent the possibility of accidentally calling the method with a
+     * single {@code Path} as such an argument. Although {@code Path} implements
+     * {@code Iterable<Path>}, it would almost never be correct to pass a single
+     * {@code Path} and have it be treated as an {@code Iterable} of its
+     * components.
+     */
+    @Deprecated(since = "13")
+    default Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
             Iterable<? extends Path> paths) {
-        return getJavaFileObjectsFromFiles(asFiles(paths));
+        return getJavaFileObjectsFromPaths(asCollection(paths));
     }
 
     /**
@@ -484,4 +515,13 @@
             }
         };
     }
+
+    private static <T> Collection<T> asCollection(Iterable<T> iterable) {
+        if (iterable instanceof Collection) {
+            return (Collection<T>) iterable;
+        }
+        List<T> result = new ArrayList<>();
+        for (T item : iterable) result.add(item);
+        return result;
+    }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Wed Mar 27 08:27:58 2019 -0400
@@ -437,6 +437,18 @@
         }
 
         @Override @DefinedBy(Api.COMPILER)
+        public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Collection<? extends Path> paths) {
+            try {
+                return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException | Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+
+        @Deprecated(since = "13")
+        @Override @DefinedBy(Api.COMPILER)
         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Iterable<? extends Path> paths) {
             try {
                 return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/CacheFSInfo.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/CacheFSInfo.java	Wed Mar 27 08:27:58 2019 -0400
@@ -26,9 +26,11 @@
 package com.sun.tools.javac.file;
 
 import java.io.IOException;
+import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.List;
-import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.sun.tools.javac.util.Context;
@@ -44,6 +46,12 @@
  */
 public class CacheFSInfo extends FSInfo {
 
+    protected final ConcurrentHashMap<Path, Path> canonicalPathCache = new ConcurrentHashMap<>();
+    protected final ConcurrentHashMap<Path, Optional<BasicFileAttributes>> attributeCache =
+            new ConcurrentHashMap<>();
+    protected final ConcurrentHashMap<Path, List<Path>> jarClassPathCache =
+            new ConcurrentHashMap<>();
+
     /**
      * Register a Context.Factory to create a CacheFSInfo.
      */
@@ -56,68 +64,53 @@
     }
 
     public void clearCache() {
-        cache.clear();
+        canonicalPathCache.clear();
+        attributeCache.clear();
+        jarClassPathCache.clear();
     }
 
     @Override
     public Path getCanonicalFile(Path file) {
-        Entry e = getEntry(file);
-        return e.canonicalFile;
+        return canonicalPathCache.computeIfAbsent(file, super::getCanonicalFile);
     }
 
     @Override
     public boolean exists(Path file) {
-        Entry e = getEntry(file);
-        return e.exists;
+        return getAttributes(file).isPresent();
     }
 
     @Override
     public boolean isDirectory(Path file) {
-        Entry e = getEntry(file);
-        return e.isDirectory;
+        return getAttributes(file).map(BasicFileAttributes::isDirectory).orElse(false);
     }
 
     @Override
     public boolean isFile(Path file) {
-        Entry e = getEntry(file);
-        return e.isFile;
+        return getAttributes(file).map(BasicFileAttributes::isRegularFile).orElse(false);
     }
 
     @Override
     public List<Path> getJarClassPath(Path file) throws IOException {
-        // don't bother to lock the cache, because it is thread-safe, and
-        // because the worst that can happen would be to create two identical
-        // jar class paths together and have one overwrite the other.
-        Entry e = getEntry(file);
-        if (e.jarClassPath == null)
-            e.jarClassPath = super.getJarClassPath(file);
-        return e.jarClassPath;
+        synchronized (jarClassPathCache) {
+            List<Path> jarClassPath = jarClassPathCache.get(file);
+            if (jarClassPath == null) {
+                jarClassPath = super.getJarClassPath(file);
+                jarClassPathCache.put(file, jarClassPath);
+            }
+            return jarClassPath;
+        }
     }
 
-    private Entry getEntry(Path file) {
-        // don't bother to lock the cache, because it is thread-safe, and
-        // because the worst that can happen would be to create two identical
-        // entries together and have one overwrite the other.
-        Entry e = cache.get(file);
-        if (e == null) {
-            e = new Entry();
-            e.canonicalFile = super.getCanonicalFile(file);
-            e.exists = super.exists(file);
-            e.isDirectory = super.isDirectory(file);
-            e.isFile = super.isFile(file);
-            cache.put(file, e);
-        }
-        return e;
+    protected Optional<BasicFileAttributes> getAttributes(Path file) {
+        return attributeCache.computeIfAbsent(file, this::maybeReadAttributes);
     }
 
-    // could also be a Map<File,SoftReference<Entry>> ?
-    private final Map<Path,Entry> cache = new ConcurrentHashMap<>();
-
-    private static class Entry {
-        Path canonicalFile;
-        boolean exists;
-        boolean isFile;
-        boolean isDirectory;
-        List<Path> jarClassPath;
+    protected Optional<BasicFileAttributes> maybeReadAttributes(Path file) {
+        try {
+            return Optional.of(Files.readAttributes(file, BasicFileAttributes.class));
+        } catch (IOException e) {
+            // Ignore; means file not found
+            return Optional.empty();
+        }
     }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Mar 27 08:27:58 2019 -0400
@@ -897,7 +897,7 @@
 
     @Override @DefinedBy(Api.COMPILER)
     public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
-        Iterable<? extends Path> paths)
+        Collection<? extends Path> paths)
     {
         ArrayList<PathFileObject> result;
         if (paths instanceof Collection<?>)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java	Wed Mar 27 08:27:58 2019 -0400
@@ -206,6 +206,13 @@
 
         @Override
         public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths
+                                                  (Collection<? extends Path> paths) {
+            return baseSJFM.getJavaFileObjectsFromPaths(paths);
+        }
+
+        @Deprecated(since = "13")
+        @Override
+        public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths
                                                   (Iterable<? extends Path> paths) {
             return baseSJFM.getJavaFileObjectsFromPaths(paths);
         }
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/hotspot/jtreg/ProblemList.txt	Wed Mar 27 08:27:58 2019 -0400
@@ -161,6 +161,8 @@
 vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses021/TestDescription.java 8065773 generic-all
 vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses023/TestDescription.java 8065773 generic-all
 
+vmTestbase/nsk/jdb/eval/eval001/eval001.java 8221503 generic-all
+
 vmTestbase/metaspace/gc/firstGC_10m/TestDescription.java 8208250 generic-all
 vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
 vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationApp.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationApp.java	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -28,6 +28,7 @@
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.io.File;
+import java.io.FileWriter;
 import java.security.CodeSigner;
 import java.security.CodeSource;
 import java.security.ProtectionDomain;
@@ -140,8 +141,22 @@
     }
 
     static void waitAttach(String flagFile) throws Throwable {
+        // See InstrumentationTest.java for the hand-shake protocol.
         if (!flagFile.equals("noattach")) {
             File f = new File(flagFile);
+            try (FileWriter fw = new FileWriter(f)) {
+                long pid = ProcessHandle.current().pid();
+                System.out.println("my pid = " + pid);
+                fw.write(Long.toString(pid));
+                fw.write("\n");
+                for (int i=0; i<10; i++) {
+                  // Parent process waits until we have written more than 100 bytes, so it won't
+                  // read a partial pid
+                  fw.write("==========");
+                }
+                fw.close();
+            }
+
             long start = System.currentTimeMillis();
             while (f.exists()) {
                 long elapsed = System.currentTimeMillis() - start;
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationTest.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/InstrumentationTest.java	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -29,9 +29,6 @@
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
  * @requires vm.cds
  * @requires vm.flavor != "minimal"
- * @modules java.base/jdk.internal.misc
- *          jdk.jartool/sun.tools.jar
- *          java.management
  * @build sun.hotspot.WhiteBox
  *        InstrumentationApp
  *        InstrumentationClassFileTransformer
@@ -43,10 +40,9 @@
 // Note: Util       is from /test/hotspot/jtreg/runtime/appcds/test-classes/TestCommon.java
 
 import com.sun.tools.attach.VirtualMachine;
-import com.sun.tools.attach.VirtualMachineDescriptor;
 import java.io.File;
-import java.io.FileOutputStream;
-import java.util.List;
+import java.io.FileInputStream;
+import java.util.Scanner;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.cds.CDSOptions;
 import jdk.test.lib.process.OutputAnalyzer;
@@ -179,24 +175,28 @@
             return null;
         }
 
-        // We use the flagFile to prevent the child process to make progress, until we have
-        // attached to it.
+        // Hand-shake protocol with the child process
+        // [1] Parent process (this process) launches child process (InstrumentationApp)
+        //     and then waits until child process writes its pid into the flagFile.
+        // [2] Child process process starts up, writes its pid into the flagFile,
+        //     and waits for the flagFile to be deleted.
+        // [3] When parent process gets the pid, it attaches to the child process
+        //     (if we attempt to attach to a process too early, the SIGQUIT
+        //     may cause the child to die) and deletes the flagFile.
+        // [4] Child process resumes execution.
+
         File f = new File(flagFile);
-        try (FileOutputStream o = new FileOutputStream(f)) {
-            o.write(1);
-        }
-        if (!f.exists()) {
-            throw new RuntimeException("Failed to create " + f);
+        f.delete();
+        if (f.exists()) {
+            throw new RuntimeException("Flag file should not exist: " + f);
         }
 
         // At this point, the child process is not yet launched. Note that
         // TestCommon.exec() and OutputAnalyzer.OutputAnalyzer() both block
         // until the child process has finished.
         //
-        // So, we will launch a AgentAttachThread which will poll the system
-        // until the child process is launched, and then do the attachment.
-        // The child process is uniquely identified by having flagFile in its
-        // command-line -- see AgentAttachThread.getPid().
+        // So, we will launch a AgentAttachThread which will poll the flagFile
+        // until the child process is launched.
         AgentAttachThread t = new AgentAttachThread(flagFile, agentJar);
         t.start();
         return t;
@@ -225,13 +225,17 @@
                 // reason the child process fails to launch, this test will be terminated
                 // by JTREG's time-out mechanism.
                 Thread.sleep(100);
-                List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
-                for (VirtualMachineDescriptor vmd : vmds) {
-                    if (vmd.displayName().contains(flagFile) && vmd.displayName().contains("InstrumentationApp")) {
-                        // We use flagFile (which has the PID of this process) as a unique identifier
-                        // to ident the child process, which we want to attach to.
-                        System.out.println("Process found: " + vmd.id() + " " + vmd.displayName());
-                        return vmd.id();
+                File f = new File(flagFile);
+                if (f.exists() && f.length() > 100) {
+                    try (FileInputStream in = new FileInputStream(f)) {
+                        Scanner scanner = new Scanner(in);
+                        return Long.toString(scanner.nextLong());
+                    } catch (Throwable t) {
+                        // This may happen on Windows if the child process has not
+                        // fully closed the output stream to the flagFile
+                        System.out.println("Ignored: " + t);
+                        t.printStackTrace(System.out);
+                        continue;
                     }
                 }
             }
@@ -240,6 +244,7 @@
         public void run() {
             try {
                 String pid = getPid(flagFile);
+                System.out.println("child pid = " + pid);
                 VirtualMachine vm = VirtualMachine.attach(pid);
                 System.out.println(agentJar);
                 vm.loadAgent(agentJar);
--- a/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-FROM oraclelinux:7.6
-MAINTAINER mikhailo.seledtsov@oracle.com
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-aarch64	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# Use generic ubuntu Linux on AArch64
-FROM aarch64/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-ppc64le	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-# test on x86_64 uses Oracle Linux but we do not have this for ppc64le
-# so use some other Linux where OpenJDK works 
-# FROM oraclelinux:7.2
-FROM ppc64le/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-s390x	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-FROM s390x/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/hotspot/jtreg/serviceability/sa/TestUniverse.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/TestUniverse.java	Wed Mar 27 08:27:58 2019 -0400
@@ -29,99 +29,107 @@
 import java.util.HashMap;
 import jdk.test.lib.apps.LingeredApp;
 import jtreg.SkippedException;
+import sun.hotspot.gc.GC;
 
 /**
  * @test
  * @summary Test the 'universe' command of jhsdb clhsdb.
- * @requires vm.hasSAandCanAttach & vm.gc != "Z"
+ * @requires vm.hasSAandCanAttach
  * @bug 8190307
  * @library /test/lib
  * @build jdk.test.lib.apps.*
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse withoutZ
- */
-
-/**
- * @test
- * @summary Test the 'universe' command of jhsdb clhsdb.
- * @requires vm.hasSAandCanAttach & vm.gc == "Z"
- * @bug 8190307
- * @library /test/lib
- * @build jdk.test.lib.apps.*
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse withZ
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse
  */
 
 public class TestUniverse {
 
-    private static void testClhsdbForUniverse(long lingeredAppPid,
-                                              String gc) throws Exception {
-
+    private static void testClhsdbForUniverse(long lingeredAppPid, GC gc) throws Exception {
         ClhsdbLauncher launcher = new ClhsdbLauncher();
         List<String> cmds = List.of("universe");
         Map<String, List<String>> expStrMap = new HashMap<>();
         List<String> expStrings = new ArrayList<String>();
         expStrings.add("Heap Parameters");
 
-        if (gc.contains("UseZGC")) {
-            expStrings.add("ZHeap");
-        }
-        if (gc.contains("G1GC")) {
+        switch (gc) {
+        case Serial:
+            expStrings.add("Gen 1:   old");
+            break;
+
+        case Parallel:
+            expStrings.add("ParallelScavengeHeap");
+            expStrings.add("PSYoungGen");
+            expStrings.add("eden");
+            break;
+
+        case ConcMarkSweep:
+            expStrings.add("Gen 1: concurrent mark-sweep generation");
+            break;
+
+        case G1:
             expStrings.add("garbage-first heap");
             expStrings.add("region size");
             expStrings.add("G1 Young Generation:");
             expStrings.add("regions  =");
-        }
-        if (gc.contains("UseConcMarkSweepGC")) {
-            expStrings.add("Gen 1: concurrent mark-sweep generation");
-        }
-        if (gc.contains("UseSerialGC")) {
-            expStrings.add("Gen 1:   old");
-        }
-        if (gc.contains("UseParallelGC")) {
-            expStrings.add("ParallelScavengeHeap");
-            expStrings.add("PSYoungGen");
-            expStrings.add("eden");
-        }
-        if (gc.contains("UseEpsilonGC")) {
+            break;
+
+        case Epsilon:
             expStrings.add("Epsilon heap");
             expStrings.add("reserved");
             expStrings.add("committed");
             expStrings.add("used");
+            break;
+
+        case Z:
+            expStrings.add("ZHeap");
+            break;
+
+        case Shenandoah:
+            expStrings.add("Shenandoah Heap");
+            break;
         }
+
         expStrMap.put("universe", expStrings);
         launcher.run(lingeredAppPid, cmds, expStrMap, null);
     }
 
-    public static void test(String gc) throws Exception {
+    private static void test(GC gc) throws Exception {
         LingeredApp app = null;
         try {
-            List<String> vmArgs = new ArrayList<String>();
-            vmArgs.add("-XX:+UnlockExperimentalVMOptions"); // unlock experimental GCs
-            vmArgs.add(gc);
-            app = LingeredApp.startApp(vmArgs);
-            System.out.println ("Started LingeredApp with the GC option " + gc +
-                                " and pid " + app.getPid());
+            app = LingeredApp.startApp(List.of("-XX:+UnlockExperimentalVMOptions", "-XX:+Use" + gc + "GC"));
+            System.out.println ("Started LingeredApp with " + gc + "GC and pid " + app.getPid());
             testClhsdbForUniverse(app.getPid(), gc);
         } finally {
             LingeredApp.stopApp(app);
         }
     }
 
+    private static boolean isSelectedAndSupported(GC gc) {
+        if (!gc.isSelected()) {
+            // Not selected
+            return false;
+        }
+
+        if (Compiler.isGraalEnabled()) {
+            if (gc == GC.ConcMarkSweep || gc == GC.Epsilon || gc == GC.Z || gc == GC.Shenandoah) {
+                // Not supported
+                System.out.println ("Skipped testing of " + gc + "GC, not supported by Graal");
+                return false;
+            }
+        }
+
+        // Selected and supported
+        return true;
+    }
+
     public static void main (String... args) throws Exception {
-        System.out.println("Starting TestUniverse test");
+        System.out.println("Starting TestUniverse");
         try {
-            test("-XX:+UseG1GC");
-            test("-XX:+UseParallelGC");
-            test("-XX:+UseSerialGC");
-            if (!Compiler.isGraalEnabled()) { // Graal does not support all GCs
-                test("-XX:+UseConcMarkSweepGC");
-                if (args[0].equals("withZ")) {
-                    test("-XX:+UseZGC");
+            for (GC gc: GC.values()) {
+                if (isSelectedAndSupported(gc)) {
+                    test(gc);
                 }
-                test("-XX:+UseEpsilonGC");
             }
         } catch (SkippedException se) {
             throw se;
--- a/test/jdk/java/lang/String/StringRepeat.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/lang/String/StringRepeat.java	Wed Mar 27 08:27:58 2019 -0400
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary This exercises String#repeat patterns and limits.
- * @run main/othervm -Xmx4G StringRepeat
+ * @run main/othervm -Xmx2g StringRepeat
  */
 
 import java.nio.CharBuffer;
--- a/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java	Wed Mar 27 08:27:58 2019 -0400
@@ -22,6 +22,7 @@
  */
 
 /* @test
+ * @bug 8216558
  * @summary unit tests for java.lang.invoke.MethodHandles
  * @library /test/lib /java/lang/invoke/common
  * @compile MethodHandlesTest.java MethodHandlesGeneralTest.java remote/RemoteExample.java
@@ -664,6 +665,7 @@
         boolean testNPE  = ((testMode0 & TEST_NPE) != 0);
         int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
         boolean positive = positive0 && !testNPE;
+        boolean isFinal;
         boolean isStatic;
         Class<?> fclass;
         String   fname;
@@ -671,12 +673,14 @@
         Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
         if (f != null) {
             isStatic = Modifier.isStatic(f.getModifiers());
+            isFinal  = Modifier.isFinal(f.getModifiers());
             fclass   = f.getDeclaringClass();
             fname    = f.getName();
             ftype    = f.getType();
         } else {
             Object[] scnt = (Object[]) fieldRef;
             isStatic = (Boolean)  scnt[0];
+            isFinal  = false;
             fclass   = (Class<?>) scnt[1];
             fname    = (String)   scnt[2];
             ftype    = (Class<?>) scnt[3];
@@ -720,18 +724,21 @@
                 ?   NoSuchFieldException.class
                 :   IllegalAccessException.class,
                 noAccess);
+            if (((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic)) return; // Final static field setter test failed as intended.
             if (verbosity >= 5)  ex.printStackTrace(System.out);
         }
         if (verbosity >= 3)
-            System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
-                               +" => "+mh
-                               +(noAccess == null ? "" : " !! "+noAccess));
+            System.out.println((((testMode0 & TEST_UNREFLECT) != 0)?"unreflect":"find")
+                              +(((testMode0 & TEST_FIND_STATIC) != 0)?"Static":"")
+                              +(isGetter?"Getter":"Setter")
+                              +" "+fclass.getName()+"."+fname+"/"+ftype
+                              +" => "+mh
+                              +(noAccess == null ? "" : " !! "+noAccess));
         if (positive && !testNPE && noAccess != null)  throw new RuntimeException(noAccess);
         assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
+        assertFalse("Setter methods should throw an exception if passed a final static field.", ((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic));
         if (!positive && !testNPE)  return; // negative access test failed as expected
         assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
-
-
         assertSame(mh.type(), expType);
         //assertNameStringContains(mh, fname);  // This does not hold anymore with LFs
         HasFields fields = new HasFields();
@@ -778,8 +785,7 @@
                     }
                 }
                 assertEquals(sawValue, expValue);
-                if (f != null && f.getDeclaringClass() == HasFields.class
-                    && !Modifier.isFinal(f.getModifiers())) {
+                if (f != null && f.getDeclaringClass() == HasFields.class && !isFinal) {
                     Object random = randomArg(ftype);
                     f.set(fields, random);
                     expValue = random;
@@ -813,8 +819,8 @@
                 }
             }
         }
-        if (f != null && f.getDeclaringClass() == HasFields.class) {
-            f.set(fields, value);  // put it back
+        if ((f != null) && (f.getDeclaringClass() == HasFields.class) && !isFinal) {
+            f.set(fields, value);  // put it back if we changed it.
         }
         if (testNPE) {
             if (caughtEx == null || !(caughtEx instanceof NullPointerException))
@@ -862,7 +868,6 @@
 
     public void testSetter(int testMode) throws Throwable {
         Lookup lookup = PRIVATE;  // FIXME: test more lookups than this one
-        startTest("unreflectSetter");
         for (Object[] c : HasFields.CASES) {
             boolean positive = (c[1] != Error.class);
             testSetter(positive, lookup, c[0], c[1], testMode);
--- a/test/jdk/java/lang/invoke/MethodHandlesTest.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/lang/invoke/MethodHandlesTest.java	Wed Mar 27 08:27:58 2019 -0400
@@ -545,14 +545,14 @@
     }
 
     public static class HasFields {
-        boolean fZ = false;
-        byte fB = (byte)'B';
-        short fS = (short)'S';
-        char fC = 'C';
-        int fI = 'I';
-        long fJ = 'J';
-        float fF = 'F';
-        double fD = 'D';
+        boolean iZ = false;
+        byte iB = (byte)'B';
+        short iS = (short)'S';
+        char iC = 'C';
+        int iI = 'I';
+        long iJ = 'J';
+        float iF = 'F';
+        double iD = 'D';
         static boolean sZ = true;
         static byte sB = 1+(byte)'B';
         static short sS = 1+(short)'S';
@@ -561,11 +561,21 @@
         static long sJ = 1+'J';
         static float sF = 1+'F';
         static double sD = 1+'D';
+        final static boolean fsZ = false;
+        final static byte fsB = 2+(byte)'B';
+        final static short fsS = 2+(short)'S';
+        final static char fsC = 2+'C';
+        final static int fsI = 2+'I';
+        final static long fsJ = 2+'J';
+        final static float fsF = 2+'F';
+        final static double fsD = 2+'D';
 
-        Object fL = 'L';
-        String fR = "R";
+        Object iL = 'L';
+        String iR = "R";
         static Object sL = 'M';
         static String sR = "S";
+        final static Object fsL = 'N';
+        final static String fsR = "T";
 
         static final Object[][] CASES;
         static {
@@ -579,14 +589,16 @@
             };
             HasFields fields = new HasFields();
             for (Object[] t : types) {
-                for (int kind = 0; kind <= 1; kind++) {
+                for (int kind = 0; kind <= 2; kind++) {
                     boolean isStatic = (kind != 0);
+                    boolean isFinal  = (kind == 2);
                     char btc = (Character)t[0];
-                    String name = (isStatic ? "s" : "f") + btc;
+                    String name = (isStatic ? "s" : "i") + btc;
+                    if (isFinal) name = "f" + name;
                     Class<?> type = (Class<?>) t[1];
                     Object value;
                     Field field;
-                        try {
+                    try {
                         field = HasFields.class.getDeclaredField(name);
                     } catch (NoSuchFieldException | SecurityException ex) {
                         throw new InternalError("no field HasFields."+name);
@@ -599,11 +611,14 @@
                     if (type == float.class) {
                         float v = 'F';
                         if (isStatic)  v++;
+                        if (isFinal)   v++;
                         assertTrue(value.equals(v));
                     }
+                    if (isFinal && isStatic) field.setAccessible(true);
                     assertTrue(name.equals(field.getName()));
                     assertTrue(type.equals(field.getType()));
                     assertTrue(isStatic == (Modifier.isStatic(field.getModifiers())));
+                    assertTrue(isFinal  == (Modifier.isFinal(field.getModifiers())));
                     cases.add(new Object[]{ field, value });
                 }
             }
--- a/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java	Wed Mar 27 08:27:58 2019 -0400
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8152645
+ * @bug 8152645 8216558
  * @summary test field lookup accessibility of MethodHandles and VarHandles
  * @compile TestFieldLookupAccessibility.java
  *          pkg/A.java pkg/B_extends_A.java pkg/C.java
@@ -96,6 +96,12 @@
             Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
                 return l.unreflectGetter(cloneAndSetAccessible(f));
             }
+
+            // Setting the accessibility bit of a Field grants access under
+            // all conditions for MethodHandle getters.
+            Set<String> inaccessibleFields(Set<String> inaccessibleFields) {
+                return new HashSet<>();
+            }
         },
         MH_UNREFLECT_SETTER() {
             Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
@@ -103,13 +109,27 @@
             }
 
             boolean isAccessible(Field f) {
-                return f.isAccessible() || !Modifier.isFinal(f.getModifiers());
+                return f.isAccessible() && !Modifier.isStatic(f.getModifiers()) || !Modifier.isFinal(f.getModifiers());
             }
         },
         MH_UNREFLECT_SETTER_ACCESSIBLE() {
             Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
                 return l.unreflectSetter(cloneAndSetAccessible(f));
             }
+
+            boolean isAccessible(Field f) {
+                return !(Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers()));
+            }
+
+            // Setting the accessibility bit of a Field grants access to non-static
+            // final fields for MethodHandle setters.
+            Set<String> inaccessibleFields(Set<String>inaccessibleFields) {
+                Set<String> result = new HashSet<>();
+                inaccessibleFields.stream()
+                                  .filter(f -> (f.contains("static") && f.contains("final")))
+                                  .forEach(result::add);
+                return result;
+            }
         },
         VH() {
             Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
@@ -142,6 +162,10 @@
             return true;
         }
 
+        Set<String> inaccessibleFields(Set<String> inaccessibleFields) {
+            return new HashSet<>(inaccessibleFields);
+        }
+
         static Field cloneAndSetAccessible(Field f) throws Exception {
             // Clone to avoid mutating source field
             f = f.getDeclaringClass().getDeclaredField(f.getName());
@@ -180,7 +204,7 @@
     @Test(dataProvider = "lookupProvider")
     public void test(FieldLookup fl, Class<?> src, MethodHandles.Lookup l, Set<String> inaccessibleFields) {
         // Add to the expected failures all inaccessible fields due to accessibility modifiers
-        Set<String> expected = new HashSet<>(inaccessibleFields);
+        Set<String> expected = fl.inaccessibleFields(inaccessibleFields);
         Map<Field, Throwable> actual = new HashMap<>();
 
         for (Field f : fields(src)) {
@@ -202,12 +226,7 @@
                 collect(Collectors.toSet());
         if (!actualFieldNames.equals(expected)) {
             if (actualFieldNames.isEmpty()) {
-                // Setting the accessibility bit of a Field grants access under
-                // all conditions for MethodHander getters and setters
-                if (fl != FieldLookup.MH_UNREFLECT_GETTER_ACCESSIBLE &&
-                    fl != FieldLookup.MH_UNREFLECT_SETTER_ACCESSIBLE) {
-                    Assert.assertEquals(actualFieldNames, expected, "No accessibility failures:");
-                }
+                Assert.assertEquals(actualFieldNames, expected, "No accessibility failures:");
             }
             else {
                 Assert.assertEquals(actualFieldNames, expected, "Accessibility failures differ:");
--- a/test/jdk/java/math/BigInteger/LargeValueExceptions.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/math/BigInteger/LargeValueExceptions.java	Wed Mar 27 08:27:58 2019 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 8200698
  * @summary Tests that exceptions are thrown for ops which would overflow
- * @requires os.maxMemory >= 4g
+ * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)
  * @run testng/othervm -Xmx4g LargeValueExceptions
  */
 import java.math.BigInteger;
--- a/test/jdk/java/util/Base64/TestEncodingDecodingLength.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/jdk/java/util/Base64/TestEncodingDecodingLength.java	Wed Mar 27 08:27:58 2019 -0400
@@ -30,7 +30,7 @@
  * @bug 8210583 8217969 8218265
  * @summary Tests Base64.Encoder.encode and Base64.Decoder.decode
  *          with the large size of input array/buffer
- * @requires os.maxMemory >= 10g
+ * @requires (sun.arch.data.model == "64" & os.maxMemory >= 10g)
  * @run main/othervm -Xms6g -Xmx8g TestEncodingDecodingLength
  *
  */
--- a/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-FROM oraclelinux:7.6
-MAINTAINER mikhailo.seledtsov@oracle.com
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-aarch64	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# Use generic ubuntu Linux on AArch64
-FROM aarch64/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-ppc64le	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-# test on x86_64 uses Oracle Linux but we do not have this for ppc64le
-# so use some other Linux where OpenJDK works 
-# FROM oraclelinux:7.2
-FROM ppc64le/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest-s390x	Wed Mar 27 07:45:21 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-FROM s390x/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/langtools/tools/javac/api/file/SJFM_GetFileObjects.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/langtools/tools/javac/api/file/SJFM_GetFileObjects.java	Wed Mar 27 08:27:58 2019 -0400
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8059977
+ * @bug 8059977 8220687
  * @summary StandardJavaFileManager should support java.nio.file.Path.
  *          Test getFileObject methods.
  * @modules java.compiler
@@ -117,6 +117,40 @@
 
     //----------------------------------------------------------------------------------------------
 
+    @Test
+    void test_getJavaFileObjectsFromPaths_Iterable(StandardJavaFileManager fm) throws IOException {
+        test_getJavaFileObjectsFromPaths_Iterable(fm, getTestFilePaths());
+        test_getJavaFileObjectsFromPaths_Iterable(fm, getTestZipPaths());
+    }
+
+    /**
+     * Tests the {@code getJavaFileObjectsFromPaths(Iterable)} method for a specific file
+     * manager and a series of paths.
+     *
+     * Note: instances of MyStandardJavaFileManager only support
+     * encapsulating paths for files in the default file system.
+     *
+     * @param fm  the file manager to be tested
+     * @param paths  the paths to be tested
+     * @throws IOException
+     */
+    void test_getJavaFileObjectsFromPaths_Iterable(StandardJavaFileManager fm, List<Path> paths)
+            throws IOException {
+        boolean expectException = !isGetFileObjectsSupported(fm, paths);
+        try {
+            compile(fm.getJavaFileObjectsFromPaths((Iterable<Path>) paths));
+            if (expectException)
+                error("expected exception not thrown: " + IllegalArgumentException.class.getName());
+        } catch (RuntimeException e) {
+            if (expectException && e instanceof IllegalArgumentException)
+                return;
+            error("unexpected exception thrown: " + e);
+        }
+    }
+
+
+    //----------------------------------------------------------------------------------------------
+
     /**
      * Compiles a set of files.
      *
--- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java	Wed Mar 27 07:45:21 2019 -0400
+++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java	Wed Mar 27 08:27:58 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -35,7 +35,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import jdk.test.lib.Platform;
 import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
@@ -126,11 +125,6 @@
         if (Files.exists(buildDir)) {
             throw new RuntimeException("The docker build directory already exists: " + buildDir);
         }
-        // check for the existance of a platform specific docker file as well
-        String platformSpecificDockerfile = dockerfile + "-" + Platform.getOsArch();
-        if (Files.exists(Paths.get(Utils.TEST_SRC, platformSpecificDockerfile))) {
-          dockerfile = platformSpecificDockerfile;
-        }
 
         Path jdkSrcDir = Paths.get(Utils.TEST_JDK);
         Path jdkDstDir = buildDir.resolve("jdk");
@@ -158,8 +152,9 @@
     public static void
         buildDockerImage(String imageName, Path dockerfile, Path buildDir) throws Exception {
 
-        // Copy docker file to the build dir
-        Files.copy(dockerfile, buildDir.resolve("Dockerfile"));
+        generateDockerFile(buildDir.resolve("Dockerfile"),
+                           DockerfileConfig.getBaseImageName(),
+                           DockerfileConfig.getBaseImageVersion());
 
         // Build the docker
         execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
@@ -250,6 +245,18 @@
     }
 
 
+    private static void generateDockerFile(Path dockerfile, String baseImage,
+                                           String baseImageVersion) throws Exception {
+        String template =
+            "FROM %s:%s\n" +
+            "COPY /jdk /jdk\n" +
+            "ENV JAVA_HOME=/jdk\n" +
+            "CMD [\"/bin/bash\"]\n";
+        String dockerFileStr = String.format(template, baseImage, baseImageVersion);
+        Files.writeString(dockerfile, dockerFileStr);
+    }
+
+
     private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
         private final Path src;
         private final Path dst;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/containers/docker/DockerfileConfig.java	Wed Mar 27 08:27:58 2019 -0400
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.containers.docker;
+
+import jdk.test.lib.Platform;
+
+// Use the following properties to specify docker base image at test execution time:
+// Image name: jdk.test.docker.image.name
+// Image version: jdk.test.docker.image.version
+// Usage:
+//     jtreg -Djdk.test.docker.image.name=<BASE_IMAGE_NAME> -Djdk.test.docker.image.version=<BASE_IMAGE_VERSION> test/hotspot/jtreg/runtime/containers/docker/
+// E.g.:
+//     jtreg -Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest test/hotspot/jtreg/runtime/containers/docker/
+// Using make:
+//     make test TEST="test/hotspot/jtreg/runtime/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest"
+// Note: base image version should not be an empty string. Use "latest" to get the latest version.
+
+public class DockerfileConfig {
+    static String getBaseImageName() {
+        String name = System.getProperty("jdk.test.docker.image.name");
+        if (name != null) {
+            System.out.println("DockerfileConfig: using custom image name: " + name);
+            return name;
+        }
+
+        switch (Platform.getOsArch()) {
+            case "aarch64":
+                return "aarch64/ubuntu";
+            case "ppc64le":
+                return "ppc64le/ubuntu";
+            case "s390x":
+                return "s390x/ubuntu";
+            default:
+                return "oraclelinux";
+        }
+    }
+
+    static String getBaseImageVersion() {
+        String version = System.getProperty("jdk.test.docker.image.version");
+        if (version != null) {
+            System.out.println("DockerfileConfig: using custom image version: " + version);
+            return version;
+        }
+
+        switch (Platform.getOsArch()) {
+            case "aarch64":
+            case "ppc64le":
+            case "s390x":
+                return "latest";
+            default:
+                return "7.6";
+        }
+    }
+}