src/hotspot/share/gc/z/zMarkStack.hpp
changeset 50525 767cdb97f103
child 51346 d98f2adf09c9
equal deleted inserted replaced
50524:04f4e983c2f7 50525:767cdb97f103
       
     1 /*
       
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #ifndef SHARE_GC_Z_ZMARKSTACK_HPP
       
    25 #define SHARE_GC_Z_ZMARKSTACK_HPP
       
    26 
       
    27 #include "gc/z/zGlobals.hpp"
       
    28 #include "gc/z/zLock.hpp"
       
    29 #include "gc/z/zMarkStackEntry.hpp"
       
    30 #include "memory/allocation.hpp"
       
    31 #include "utilities/globalDefinitions.hpp"
       
    32 
       
    33 template <typename T, size_t S>
       
    34 class ZStack {
       
    35 private:
       
    36   size_t        _top;
       
    37   ZStack<T, S>* _next;
       
    38   T             _slots[S];
       
    39 
       
    40   bool is_full() const;
       
    41 
       
    42 public:
       
    43   ZStack();
       
    44 
       
    45   bool is_empty() const;
       
    46 
       
    47   bool push(T value);
       
    48   bool pop(T& value);
       
    49 
       
    50   ZStack<T, S>* next() const;
       
    51   ZStack<T, S>** next_addr();
       
    52 };
       
    53 
       
    54 template <typename T>
       
    55 class ZStackList {
       
    56 private:
       
    57   T* volatile _head;
       
    58 
       
    59   T* encode_versioned_pointer(const T* stack, uint32_t version) const;
       
    60   void decode_versioned_pointer(const T* vstack, T** stack, uint32_t* version) const;
       
    61 
       
    62 public:
       
    63   ZStackList();
       
    64 
       
    65   bool is_empty() const;
       
    66 
       
    67   void push_atomic(T* stack);
       
    68   T* pop_atomic();
       
    69 };
       
    70 
       
    71 typedef ZStack<ZMarkStackEntry, ZMarkStackSlots>     ZMarkStack;
       
    72 typedef ZStackList<ZMarkStack>                       ZMarkStackList;
       
    73 typedef ZStack<ZMarkStack*, ZMarkStackMagazineSlots> ZMarkStackMagazine;
       
    74 typedef ZStackList<ZMarkStackMagazine>               ZMarkStackMagazineList;
       
    75 
       
    76 class ZMarkStackSpace {
       
    77 private:
       
    78   ZLock              _expand_lock;
       
    79   volatile uintptr_t _top;
       
    80   volatile uintptr_t _end;
       
    81 
       
    82   bool expand();
       
    83 
       
    84   uintptr_t alloc_space(size_t size);
       
    85   uintptr_t expand_and_alloc_space(size_t size);
       
    86 
       
    87 public:
       
    88   ZMarkStackSpace();
       
    89 
       
    90   bool is_initialized() const;
       
    91 
       
    92   uintptr_t alloc(size_t size);
       
    93 };
       
    94 
       
    95 class ZMarkStackAllocator {
       
    96 private:
       
    97   ZMarkStackMagazineList _freelist ATTRIBUTE_ALIGNED(ZCacheLineSize);
       
    98   ZMarkStackSpace        _space    ATTRIBUTE_ALIGNED(ZCacheLineSize);
       
    99 
       
   100   void prime_freelist();
       
   101   ZMarkStackMagazine* create_magazine_from_space(uintptr_t addr, size_t size);
       
   102 
       
   103 public:
       
   104   ZMarkStackAllocator();
       
   105 
       
   106   bool is_initialized() const;
       
   107 
       
   108   ZMarkStackMagazine* alloc_magazine();
       
   109   void free_magazine(ZMarkStackMagazine* magazine);
       
   110 };
       
   111 
       
   112 class ZMarkStripe {
       
   113 private:
       
   114   ZMarkStackList _published  ATTRIBUTE_ALIGNED(ZCacheLineSize);
       
   115   ZMarkStackList _overflowed ATTRIBUTE_ALIGNED(ZCacheLineSize);
       
   116 
       
   117 public:
       
   118   ZMarkStripe();
       
   119 
       
   120   bool is_empty() const;
       
   121 
       
   122   void publish_stack(ZMarkStack* stack, bool publish = true);
       
   123   ZMarkStack* steal_stack();
       
   124 };
       
   125 
       
   126 class ZMarkStripeSet {
       
   127 private:
       
   128   size_t      _nstripes;
       
   129   size_t      _nstripes_mask;
       
   130   ZMarkStripe _stripes[ZMarkStripesMax];
       
   131 
       
   132 public:
       
   133   ZMarkStripeSet();
       
   134 
       
   135   size_t nstripes() const;
       
   136   void set_nstripes(size_t nstripes);
       
   137 
       
   138   bool is_empty() const;
       
   139 
       
   140   size_t stripe_id(const ZMarkStripe* stripe) const;
       
   141   ZMarkStripe* stripe_at(size_t index);
       
   142   ZMarkStripe* stripe_next(ZMarkStripe* stripe);
       
   143   ZMarkStripe* stripe_for_worker(uint nworkers, uint worker_id);
       
   144   ZMarkStripe* stripe_for_addr(uintptr_t addr);
       
   145 };
       
   146 
       
   147 class ZMarkThreadLocalStacks {
       
   148 private:
       
   149   ZMarkStackMagazine* _magazine;
       
   150   ZMarkStack*         _stacks[ZMarkStripesMax];
       
   151 
       
   152   ZMarkStack* allocate_stack(ZMarkStackAllocator* allocator);
       
   153   void free_stack(ZMarkStackAllocator* allocator, ZMarkStack* stack);
       
   154 
       
   155   bool push_slow(ZMarkStackAllocator* allocator,
       
   156                  ZMarkStripe* stripe,
       
   157                  ZMarkStack** stackp,
       
   158                  ZMarkStackEntry entry,
       
   159                  bool publish);
       
   160 
       
   161   bool pop_slow(ZMarkStackAllocator* allocator,
       
   162                 ZMarkStripe* stripe,
       
   163                 ZMarkStack** stackp,
       
   164                 ZMarkStackEntry& entry);
       
   165 
       
   166 public:
       
   167   ZMarkThreadLocalStacks();
       
   168 
       
   169   bool is_empty(const ZMarkStripeSet* stripes) const;
       
   170 
       
   171   void install(ZMarkStripeSet* stripes,
       
   172                ZMarkStripe* stripe,
       
   173                ZMarkStack* stack);
       
   174 
       
   175   bool push(ZMarkStackAllocator* allocator,
       
   176             ZMarkStripeSet* stripes,
       
   177             ZMarkStripe* stripe,
       
   178             ZMarkStackEntry entry,
       
   179             bool publish);
       
   180 
       
   181   bool pop(ZMarkStackAllocator* allocator,
       
   182            ZMarkStripeSet* stripes,
       
   183            ZMarkStripe* stripe,
       
   184            ZMarkStackEntry& entry);
       
   185 
       
   186   bool flush(ZMarkStackAllocator* allocator,
       
   187              ZMarkStripeSet* stripes);
       
   188 
       
   189   void free(ZMarkStackAllocator* allocator);
       
   190 };
       
   191 
       
   192 #endif // SHARE_GC_Z_ZMARKSTACK_HPP