1 /*
2  * Copyright (c) 2018, 2020, 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_ZTHREADLOCALDATA_HPP
25 #define SHARE_GC_Z_ZTHREADLOCALDATA_HPP
26 
27 #include "gc/z/zMarkStack.hpp"
28 #include "gc/z/zGlobals.hpp"
29 #include "runtime/thread.hpp"
30 #include "utilities/debug.hpp"
31 #include "utilities/sizes.hpp"
32 
33 class ZThreadLocalData {
34 private:
35   uintptr_t              _address_bad_mask;
36   ZMarkThreadLocalStacks _stacks;
37   oop*                   _invisible_root;
38 
ZThreadLocalData()39   ZThreadLocalData() :
40       _address_bad_mask(0),
41       _stacks(),
42       _invisible_root(NULL) {}
43 
data(Thread * thread)44   static ZThreadLocalData* data(Thread* thread) {
45     return thread->gc_data<ZThreadLocalData>();
46   }
47 
48 public:
create(Thread * thread)49   static void create(Thread* thread) {
50     new (data(thread)) ZThreadLocalData();
51   }
52 
destroy(Thread * thread)53   static void destroy(Thread* thread) {
54     data(thread)->~ZThreadLocalData();
55   }
56 
set_address_bad_mask(Thread * thread,uintptr_t mask)57   static void set_address_bad_mask(Thread* thread, uintptr_t mask) {
58     data(thread)->_address_bad_mask = mask;
59   }
60 
stacks(Thread * thread)61   static ZMarkThreadLocalStacks* stacks(Thread* thread) {
62     return &data(thread)->_stacks;
63   }
64 
set_invisible_root(Thread * thread,oop * root)65   static void set_invisible_root(Thread* thread, oop* root) {
66     assert(data(thread)->_invisible_root == NULL, "Already set");
67     data(thread)->_invisible_root = root;
68   }
69 
clear_invisible_root(Thread * thread)70   static void clear_invisible_root(Thread* thread) {
71     assert(data(thread)->_invisible_root != NULL, "Should be set");
72     data(thread)->_invisible_root = NULL;
73   }
74 
75   template <typename T>
do_invisible_root(Thread * thread,T f)76   static void do_invisible_root(Thread* thread, T f) {
77     if (data(thread)->_invisible_root != NULL) {
78       f(data(thread)->_invisible_root);
79     }
80   }
81 
address_bad_mask_offset()82   static ByteSize address_bad_mask_offset() {
83     return Thread::gc_data_offset() + byte_offset_of(ZThreadLocalData, _address_bad_mask);
84   }
85 
nmethod_disarmed_offset()86   static ByteSize nmethod_disarmed_offset() {
87     return address_bad_mask_offset() + in_ByteSize(ZAddressBadMaskHighOrderBitsOffset);
88   }
89 };
90 
91 #endif // SHARE_GC_Z_ZTHREADLOCALDATA_HPP
92