Merge ihse-jdk-library-branch
authorihse
Thu, 07 Jun 2018 21:58:17 +0200
branchihse-jdk-library-branch
changeset 56699 ba8d1fc9ab9a
parent 56698 044a8f56e940 (current diff)
parent 50448 db8036093504 (diff)
child 56720 aabf65daa015
Merge
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -37,6 +37,7 @@
 #include "compiler/disassembler.hpp"
 #include "memory/resourceArea.hpp"
 #include "nativeInst_aarch64.hpp"
+#include "oops/accessDecorators.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/oop.hpp"
@@ -2127,7 +2128,7 @@
 
   bind(not_weak);
   // Resolve (untagged) jobject.
-  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
+  bs->load_at(this, IN_CONCURRENT_ROOT, T_OBJECT,
                     value, Address(value, 0), tmp, thread);
   verify_oop(value);
   bind(done);
@@ -3664,7 +3665,7 @@
 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
+  bs->load_at(this, IN_CONCURRENT_ROOT, T_OBJECT,
                     result, Address(result, 0), tmp, rthread);
 }
 
@@ -3983,6 +3984,7 @@
                                     Register dst, Address src,
                                     Register tmp1, Register thread_tmp) {
   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
@@ -3995,6 +3997,7 @@
                                      Address dst, Register src,
                                      Register tmp1, Register thread_tmp) {
   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type, dst, src, tmp1, thread_tmp);
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -813,7 +813,7 @@
   do_oop_load(_masm,
               Address(r1, arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
               r0,
-              IN_HEAP | IN_HEAP_ARRAY);
+              IN_HEAP_ARRAY);
 }
 
 void TemplateTable::baload()
@@ -1141,7 +1141,7 @@
   // Get the value we will store
   __ ldr(r0, at_tos());
   // Now store using the appropriate barrier
-  do_oop_store(_masm, element_address, r0, IN_HEAP | IN_HEAP_ARRAY);
+  do_oop_store(_masm, element_address, r0, IN_HEAP_ARRAY);
   __ b(done);
 
   // Have a NULL in r0, r3=array, r2=index.  Store NULL at ary[idx]
@@ -1149,7 +1149,7 @@
   __ profile_null_seen(r2);
 
   // Store a NULL
-  do_oop_store(_masm, element_address, noreg, IN_HEAP | IN_HEAP_ARRAY);
+  do_oop_store(_masm, element_address, noreg, IN_HEAP_ARRAY);
 
   // Pop stack arguments
   __ bind(done);
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -36,6 +36,7 @@
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/accessDecorators.hpp"
 #include "oops/klass.inline.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -2133,7 +2134,7 @@
   b(done);
   bind(not_weak);
   // Resolve (untagged) jobject.
-  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+  access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
                  Address(value, 0), value, tmp1, tmp2, noreg);
   verify_oop(value);
   bind(done);
@@ -2700,6 +2701,7 @@
 void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
                                     Address src, Register dst, Register tmp1, Register tmp2, Register tmp3) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, tmp2, tmp3);
@@ -2711,6 +2713,7 @@
 void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
                                      Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null);
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp	Thu Jun 07 21:58:17 2018 +0200
@@ -32,6 +32,7 @@
 #include "code/codeCache.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/barrierSetAssembler.hpp"
+#include "oops/accessDecorators.hpp"
 #include "runtime/safepointMechanism.hpp"
 
 inline bool MacroAssembler::is_ld_largeoffset(address a) {
@@ -332,6 +333,7 @@
                          ON_UNKNOWN_OOP_REF)) == 0, "unsupported decorator");
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
   bool as_raw = (decorators & AS_RAW) != 0;
+  decorators = AccessInternal::decorator_fixup(decorators);
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type,
                                       base, ind_or_offs, val,
@@ -349,6 +351,7 @@
   assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
                          ON_PHANTOM_OOP_REF | ON_WEAK_OOP_REF)) == 0, "unsupported decorator");
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type,
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -688,7 +688,7 @@
                  Rtemp2     = R31;
   __ index_check(Rarray, R17_tos /* index */, UseCompressedOops ? 2 : LogBytesPerWord, Rtemp, Rload_addr);
   do_oop_load(_masm, Rload_addr, arrayOopDesc::base_offset_in_bytes(T_OBJECT), R17_tos, Rtemp, Rtemp2,
-              IN_HEAP | IN_HEAP_ARRAY);
+              IN_HEAP_ARRAY);
   __ verify_oop(R17_tos);
   //__ dcbt(R17_tos); // prefetch
 }
@@ -1015,14 +1015,14 @@
 
   __ bind(Lis_null);
   do_oop_store(_masm, Rstore_addr, arrayOopDesc::base_offset_in_bytes(T_OBJECT), noreg /* 0 */,
-               Rscratch, Rscratch2, Rscratch3, IN_HEAP | IN_HEAP_ARRAY);
+               Rscratch, Rscratch2, Rscratch3, IN_HEAP_ARRAY);
   __ profile_null_seen(Rscratch, Rscratch2);
   __ b(Ldone);
 
   // Store is OK.
   __ bind(Lstore_ok);
   do_oop_store(_masm, Rstore_addr, arrayOopDesc::base_offset_in_bytes(T_OBJECT), R17_tos /* value */,
-               Rscratch, Rscratch2, Rscratch3, IN_HEAP | IN_HEAP_ARRAY | OOP_NOT_NULL);
+               Rscratch, Rscratch2, Rscratch3, IN_HEAP_ARRAY | OOP_NOT_NULL);
 
   __ bind(Ldone);
   // Adjust sp (pops array, index and value).
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -34,6 +34,7 @@
 #include "gc/shared/cardTableBarrierSet.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
+#include "oops/accessDecorators.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/klass.inline.hpp"
 #include "opto/compile.hpp"
@@ -4053,6 +4054,7 @@
   assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
                          ON_UNKNOWN_OOP_REF)) == 0, "unsupported decorator");
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type,
@@ -4071,6 +4073,7 @@
   assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
                          ON_PHANTOM_OOP_REF | ON_WEAK_OOP_REF)) == 0, "unsupported decorator");
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type,
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -853,7 +853,7 @@
   index_check(Z_tmp_1, index, shift);
   // Now load array element.
   do_oop_load(_masm, Address(Z_tmp_1, index, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), Z_tos,
-              Z_tmp_2, Z_tmp_3, IN_HEAP | IN_HEAP_ARRAY);
+              Z_tmp_2, Z_tmp_3, IN_HEAP_ARRAY);
   __ verify_oop(Z_tos);
 }
 
@@ -1197,7 +1197,7 @@
 
   // Store a NULL.
   do_oop_store(_masm, Address(Rstore_addr, (intptr_t)0), noreg,
-               tmp3, tmp2, tmp1, IN_HEAP | IN_HEAP_ARRAY);
+               tmp3, tmp2, tmp1, IN_HEAP_ARRAY);
   __ z_bru(done);
 
   // Come here on success.
@@ -1205,7 +1205,7 @@
 
   // Now store using the appropriate barrier.
   do_oop_store(_masm, Address(Rstore_addr, (intptr_t)0), Rvalue,
-               tmp3, tmp2, tmp1, IN_HEAP | IN_HEAP_ARRAY | OOP_NOT_NULL);
+               tmp3, tmp2, tmp1, IN_HEAP_ARRAY | OOP_NOT_NULL);
 
   // Pop stack arguments.
   __ bind(done);
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -32,6 +32,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
+#include "oops/accessDecorators.hpp"
 #include "oops/klass.inline.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -181,7 +182,7 @@
   br (Assembler::always, true, Assembler::pt, done);
   delayed()->nop();
   bind(not_weak);
-  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+  access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
                  Address(value, 0), value, tmp);
   verify_oop(value);
   bind(done);
@@ -3401,7 +3402,7 @@
 // ((OopHandle)result).resolve();
 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
-  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+  access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
                  Address(result, 0), result, tmp);
 }
 
@@ -3446,6 +3447,7 @@
 void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
                                      Register src, Address dst, Register tmp) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type, src, dst, tmp);
@@ -3457,6 +3459,7 @@
 void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
                                     Address src, Register dst, Register tmp) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type, src, dst, tmp);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -33,7 +33,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/access.hpp"
+#include "oops/accessDecorators.hpp"
 #include "oops/klass.inline.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -5259,7 +5259,7 @@
   jmp(done);
   bind(not_weak);
   // Resolve (untagged) jobject.
-  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+  access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
                  value, Address(value, 0), tmp, thread);
   verify_oop(value);
   bind(done);
@@ -6281,7 +6281,7 @@
   // Only 64 bit platforms support GCs that require a tmp register
   // Only IN_HEAP loads require a thread_tmp register
   // OopHandle::resolve is an indirection like jobject.
-  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+  access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
                  result, Address(result, 0), tmp, /*tmp_thread*/noreg);
 }
 
@@ -6323,6 +6323,7 @@
 void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
                                     Register tmp1, Register thread_tmp) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
@@ -6334,6 +6335,7 @@
 void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
                                      Register tmp1, Register tmp2) {
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  decorators = AccessInternal::decorator_fixup(decorators);
   bool as_raw = (decorators & AS_RAW) != 0;
   if (as_raw) {
     bs->BarrierSetAssembler::store_at(this, decorators, type, dst, src, tmp1, tmp2);
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Jun 07 21:58:17 2018 +0200
@@ -373,7 +373,8 @@
       return result;
     }
   }
-  return Universe::heap()->mem_allocate(size, gc_overhead_limit_was_exceeded);
+
+  return allocate_outside_tlab(klass, size, gc_overhead_limit_was_exceeded, THREAD);
 }
 
 HeapWord* CollectedHeap::allocate_from_tlab_slow(Klass* klass, size_t size, TRAPS) {
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Jun 07 21:58:17 2018 +0200
@@ -144,6 +144,9 @@
   inline static HeapWord* allocate_from_tlab(Klass* klass, size_t size, TRAPS);
   static HeapWord* allocate_from_tlab_slow(Klass* klass, size_t size, TRAPS);
 
+  inline static HeapWord* allocate_outside_tlab(Klass* klass, size_t size,
+                                                bool* gc_overhead_limit_was_exceeded, TRAPS);
+
   // Raw memory allocation facilities
   // The obj and array allocate methods are covers for these methods.
   // mem_allocate() should never be
--- a/src/hotspot/share/gc/shared/collectedHeap.inline.hpp	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/hotspot/share/gc/shared/collectedHeap.inline.hpp	Thu Jun 07 21:58:17 2018 +0200
@@ -142,14 +142,6 @@
   HeapWord* result = heap->obj_allocate_raw(klass, size, &gc_overhead_limit_was_exceeded, THREAD);
 
   if (result != NULL) {
-    NOT_PRODUCT(Universe::heap()->
-      check_for_non_bad_heap_word_value(result, size));
-    assert(!HAS_PENDING_EXCEPTION,
-           "Unexpected exception, will result in uninitialized storage");
-    THREAD->incr_allocated_bytes(size * HeapWordSize);
-
-    AllocTracer::send_allocation_outside_tlab(klass, result, size * HeapWordSize, THREAD);
-
     return result;
   }
 
@@ -198,6 +190,22 @@
   return obj;
 }
 
+HeapWord* CollectedHeap::allocate_outside_tlab(Klass* klass, size_t size,
+                                               bool* gc_overhead_limit_was_exceeded, TRAPS) {
+  HeapWord* result = Universe::heap()->mem_allocate(size, gc_overhead_limit_was_exceeded);
+  if (result == NULL) {
+    return result;
+  }
+
+  NOT_PRODUCT(Universe::heap()->check_for_non_bad_heap_word_value(result, size));
+  assert(!HAS_PENDING_EXCEPTION,
+         "Unexpected exception, will result in uninitialized storage");
+  THREAD->incr_allocated_bytes(size * HeapWordSize);
+
+  AllocTracer::send_allocation_outside_tlab(klass, result, size * HeapWordSize, THREAD);
+  return result;
+}
+
 void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
   assert(obj != NULL, "cannot initialize NULL object");
   const size_t hs = oopDesc::header_size();
--- a/src/java.base/share/classes/java/nio/file/Files.java	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/java.base/share/classes/java/nio/file/Files.java	Thu Jun 07 21:58:17 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -1391,8 +1391,9 @@
      *          specific exception)</i>
      * @throws  DirectoryNotEmptyException
      *          the {@code REPLACE_EXISTING} option is specified but the file
-     *          cannot be replaced because it is a non-empty directory
-     *          <i>(optional specific exception)</i>
+     *          cannot be replaced because it is a non-empty directory, or the
+     *          source is a non-empty directory containing entries that would
+     *          be required to be moved <i>(optional specific exceptions)</i>
      * @throws  AtomicMoveNotSupportedException
      *          if the options array contains the {@code ATOMIC_MOVE} option but
      *          the file cannot be moved as an atomic file system operation.
--- a/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java	Thu Jun 07 21:58:17 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -373,6 +373,22 @@
         }
     }
 
+    // throw a DirectoryNotEmpty exception if appropriate
+    static void ensureEmptyDir(UnixPath dir) throws IOException {
+        try {
+            long ptr = opendir(dir);
+            try (UnixDirectoryStream stream =
+                new UnixDirectoryStream(dir, ptr, e -> true)) {
+                if (stream.iterator().hasNext()) {
+                    throw new DirectoryNotEmptyException(
+                        dir.getPathForExceptionMessage());
+                }
+            }
+        } catch (UnixException e) {
+            e.rethrowAsIOException(dir);
+        }
+    }
+
     // move file from source to target
     static void move(UnixPath source, UnixPath target, CopyOption... options)
         throws IOException
@@ -465,6 +481,7 @@
 
         // copy source to target
         if (sourceAttrs.isDirectory()) {
+            ensureEmptyDir(source);
             copyDirectory(source, sourceAttrs, target, flags);
         } else {
             if (sourceAttrs.isSymbolicLink()) {
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java	Thu Jun 07 21:57:43 2018 +0200
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java	Thu Jun 07 21:58:17 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -249,6 +249,17 @@
         }
     }
 
+    // throw a DirectoryNotEmpty exception if not empty
+    static void ensureEmptyDir(WindowsPath dir) throws IOException {
+        try (WindowsDirectoryStream dirStream =
+            new WindowsDirectoryStream(dir, (e) -> true)) {
+            if (dirStream.iterator().hasNext()) {
+                throw new DirectoryNotEmptyException(
+                    dir.getPathForExceptionMessage());
+            }
+        }
+    }
+
     /**
      * Move file from source to target
      */
@@ -407,6 +418,7 @@
         // create new directory or directory junction
         try {
             if (sourceAttrs.isDirectory()) {
+                ensureEmptyDir(source);
                 CreateDirectory(targetPath, 0L);
             } else {
                 String linkTarget = WindowsLinkSupport.readLink(source);
--- a/test/jdk/java/nio/file/Files/CopyAndMove.java	Thu Jun 07 21:57:43 2018 +0200
+++ b/test/jdk/java/nio/file/Files/CopyAndMove.java	Thu Jun 07 21:58:17 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, 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
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4313887 6838333 6917021 7006126 6950237 8006645
+ * @bug 4313887 6838333 6917021 7006126 6950237 8006645 8201407
  * @summary Unit test for java.nio.file.Files copy and move methods (use -Dseed=X to set PRNG seed)
  * @library .. /test/lib
  * @build jdk.test.lib.RandomFactory
@@ -448,6 +448,10 @@
                 moveAndVerify(source, target);
                 throw new RuntimeException("IOException expected");
             } catch (IOException x) {
+                if (!(x instanceof DirectoryNotEmptyException)) {
+                    throw new RuntimeException
+                        ("DirectoryNotEmptyException expected", x);
+                }
             }
             delete(source.resolve("foo"));
             delete(source);