53 54 // Register mark stack space start 55 ZMarkStackSpaceStart = _start; 56 } 57 58 bool ZMarkStackSpace::is_initialized() const { 59 return _start != 0; 60 } 61 62 uintptr_t ZMarkStackSpace::alloc_space(size_t size) { 63 uintptr_t top = Atomic::load(&_top); 64 65 for (;;) { 66 const uintptr_t end = Atomic::load(&_end); 67 const uintptr_t new_top = top + size; 68 if (new_top > end) { 69 // Not enough space left 70 return 0; 71 } 72 73 const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, top); 74 if (prev_top == top) { 75 // Success 76 return top; 77 } 78 79 // Retry 80 top = prev_top; 81 } 82 } 83 84 uintptr_t ZMarkStackSpace::expand_and_alloc_space(size_t size) { 85 ZLocker<ZLock> locker(&_expand_lock); 86 87 // Retry allocation before expanding 88 uintptr_t addr = alloc_space(size); 89 if (addr != 0) { 90 return addr; 91 } 92 93 // Check expansion limit 94 const size_t expand_size = ZMarkStackSpaceExpandSize; 95 const size_t old_size = _end - _start; 96 const size_t new_size = old_size + expand_size; 97 if (new_size > ZMarkStackSpaceLimit) { 98 // Expansion limit reached. This is a fatal error since we 99 // currently can't recover from running out of mark stack space. 100 fatal("Mark stack space exhausted. Use -XX:ZMarkStackSpaceLimit=<size> to increase the " 101 "maximum number of bytes allocated for mark stacks. Current limit is " SIZE_FORMAT "M.", 102 ZMarkStackSpaceLimit / M); 103 } 104 105 log_debug(gc, marking)("Expanding mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M", 106 old_size / M, new_size / M); 107 108 // Expand 109 os::commit_memory_or_exit((char*)_end, expand_size, false /* executable */, "Mark stack space"); 110 111 // Increment top before end to make sure another 112 // thread can't steal out newly expanded space. 113 addr = Atomic::add(size, &_top) - size; 114 Atomic::add(expand_size, &_end); 115 116 return addr; 117 } 118 119 uintptr_t ZMarkStackSpace::alloc(size_t size) { 120 const uintptr_t addr = alloc_space(size); 121 if (addr != 0) { 122 return addr; 123 } 124 125 return expand_and_alloc_space(size); 126 } 127 128 ZMarkStackAllocator::ZMarkStackAllocator() : 129 _freelist(), 130 _space() { 131 guarantee(sizeof(ZMarkStack) == ZMarkStackSize, "Size mismatch"); 132 guarantee(sizeof(ZMarkStackMagazine) <= ZMarkStackSize, "Size mismatch"); 133 134 // Prime free list to avoid an immediate space | 53 54 // Register mark stack space start 55 ZMarkStackSpaceStart = _start; 56 } 57 58 bool ZMarkStackSpace::is_initialized() const { 59 return _start != 0; 60 } 61 62 uintptr_t ZMarkStackSpace::alloc_space(size_t size) { 63 uintptr_t top = Atomic::load(&_top); 64 65 for (;;) { 66 const uintptr_t end = Atomic::load(&_end); 67 const uintptr_t new_top = top + size; 68 if (new_top > end) { 69 // Not enough space left 70 return 0; 71 } 72 73 const uintptr_t prev_top = Atomic::cmpxchg(&_top, top, new_top); 74 if (prev_top == top) { 75 // Success 76 return top; 77 } 78 79 // Retry 80 top = prev_top; 81 } 82 } 83 84 uintptr_t ZMarkStackSpace::expand_and_alloc_space(size_t size) { 85 ZLocker<ZLock> locker(&_expand_lock); 86 87 // Retry allocation before expanding 88 uintptr_t addr = alloc_space(size); 89 if (addr != 0) { 90 return addr; 91 } 92 93 // Check expansion limit 94 const size_t expand_size = ZMarkStackSpaceExpandSize; 95 const size_t old_size = _end - _start; 96 const size_t new_size = old_size + expand_size; 97 if (new_size > ZMarkStackSpaceLimit) { 98 // Expansion limit reached. This is a fatal error since we 99 // currently can't recover from running out of mark stack space. 100 fatal("Mark stack space exhausted. Use -XX:ZMarkStackSpaceLimit=<size> to increase the " 101 "maximum number of bytes allocated for mark stacks. Current limit is " SIZE_FORMAT "M.", 102 ZMarkStackSpaceLimit / M); 103 } 104 105 log_debug(gc, marking)("Expanding mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M", 106 old_size / M, new_size / M); 107 108 // Expand 109 os::commit_memory_or_exit((char*)_end, expand_size, false /* executable */, "Mark stack space"); 110 111 // Increment top before end to make sure another 112 // thread can't steal out newly expanded space. 113 addr = Atomic::add(&_top, size) - size; 114 Atomic::add(&_end, expand_size); 115 116 return addr; 117 } 118 119 uintptr_t ZMarkStackSpace::alloc(size_t size) { 120 const uintptr_t addr = alloc_space(size); 121 if (addr != 0) { 122 return addr; 123 } 124 125 return expand_and_alloc_space(size); 126 } 127 128 ZMarkStackAllocator::ZMarkStackAllocator() : 129 _freelist(), 130 _space() { 131 guarantee(sizeof(ZMarkStack) == ZMarkStackSize, "Size mismatch"); 132 guarantee(sizeof(ZMarkStackMagazine) <= ZMarkStackSize, "Size mismatch"); 133 134 // Prime free list to avoid an immediate space |