Mercurial > hg > truffle
comparison src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp @ 20582:c49cd31b6da6
8059200: Promoted JDK9 b31 for Solaris-amd64 fails (Error: dl failure on line 744, no picl library) on Solaris 11.1
Summary: Manually load libpicl.so (used on SPARC only)
Reviewed-by: kvn
author | iveresov |
---|---|
date | Sat, 25 Oct 2014 21:02:29 -1000 |
parents | d635fd1ac81c |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
20581:b8e2e616c1e9 | 20582:c49cd31b6da6 |
---|---|
29 #include <sys/auxv.h> | 29 #include <sys/auxv.h> |
30 #include <sys/auxv_SPARC.h> | 30 #include <sys/auxv_SPARC.h> |
31 #include <sys/systeminfo.h> | 31 #include <sys/systeminfo.h> |
32 #include <kstat.h> | 32 #include <kstat.h> |
33 #include <picl.h> | 33 #include <picl.h> |
34 #include <dlfcn.h> | |
35 #include <link.h> | |
34 | 36 |
35 extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); | 37 extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); |
36 extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); | 38 extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); |
37 | 39 |
40 // Functions from the library we need (signatures should match those in picl.h) | |
41 extern "C" { | |
42 typedef int (*picl_initialize_func_t)(void); | |
43 typedef int (*picl_shutdown_func_t)(void); | |
44 typedef int (*picl_get_root_func_t)(picl_nodehdl_t *nodehandle); | |
45 typedef int (*picl_walk_tree_by_class_func_t)(picl_nodehdl_t rooth, | |
46 const char *classname, void *c_args, | |
47 int (*callback_fn)(picl_nodehdl_t hdl, void *args)); | |
48 typedef int (*picl_get_prop_by_name_func_t)(picl_nodehdl_t nodeh, const char *nm, | |
49 picl_prophdl_t *ph); | |
50 typedef int (*picl_get_propval_func_t)(picl_prophdl_t proph, void *valbuf, size_t sz); | |
51 typedef int (*picl_get_propinfo_func_t)(picl_prophdl_t proph, picl_propinfo_t *pi); | |
52 } | |
53 | |
38 class PICL { | 54 class PICL { |
55 // Pointers to functions in the library | |
56 picl_initialize_func_t _picl_initialize; | |
57 picl_shutdown_func_t _picl_shutdown; | |
58 picl_get_root_func_t _picl_get_root; | |
59 picl_walk_tree_by_class_func_t _picl_walk_tree_by_class; | |
60 picl_get_prop_by_name_func_t _picl_get_prop_by_name; | |
61 picl_get_propval_func_t _picl_get_propval; | |
62 picl_get_propinfo_func_t _picl_get_propinfo; | |
63 // Handle to the library that is returned by dlopen | |
64 void *_dl_handle; | |
65 | |
66 bool open_library(); | |
67 void close_library(); | |
68 | |
69 template<typename FuncType> bool bind(FuncType& func, const char* name); | |
70 bool bind_library_functions(); | |
71 | |
39 // Get a value of the integer property. The value in the tree can be either 32 or 64 bit | 72 // Get a value of the integer property. The value in the tree can be either 32 or 64 bit |
40 // depending on the platform. The result is converted to int. | 73 // depending on the platform. The result is converted to int. |
41 static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { | 74 int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { |
42 picl_propinfo_t pinfo; | 75 picl_propinfo_t pinfo; |
43 picl_prophdl_t proph; | 76 picl_prophdl_t proph; |
44 if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || | 77 if (_picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || |
45 picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { | 78 _picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { |
46 return PICL_FAILURE; | 79 return PICL_FAILURE; |
47 } | 80 } |
48 | 81 |
49 if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) { | 82 if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) { |
50 assert(false, "Invalid property type"); | 83 assert(false, "Invalid property type"); |
51 return PICL_FAILURE; | 84 return PICL_FAILURE; |
52 } | 85 } |
53 if (pinfo.size == sizeof(int64_t)) { | 86 if (pinfo.size == sizeof(int64_t)) { |
54 int64_t val; | 87 int64_t val; |
55 if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { | 88 if (_picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { |
56 return PICL_FAILURE; | 89 return PICL_FAILURE; |
57 } | 90 } |
58 *result = static_cast<int>(val); | 91 *result = static_cast<int>(val); |
59 } else if (pinfo.size == sizeof(int32_t)) { | 92 } else if (pinfo.size == sizeof(int32_t)) { |
60 int32_t val; | 93 int32_t val; |
61 if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { | 94 if (_picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { |
62 return PICL_FAILURE; | 95 return PICL_FAILURE; |
63 } | 96 } |
64 *result = static_cast<int>(val); | 97 *result = static_cast<int>(val); |
65 } else { | 98 } else { |
66 assert(false, "Unexpected integer property size"); | 99 assert(false, "Unexpected integer property size"); |
70 } | 103 } |
71 | 104 |
72 // Visitor and a state machine that visits integer properties and verifies that the | 105 // Visitor and a state machine that visits integer properties and verifies that the |
73 // values are the same. Stores the unique value observed. | 106 // values are the same. Stores the unique value observed. |
74 class UniqueValueVisitor { | 107 class UniqueValueVisitor { |
108 PICL *_picl; | |
75 enum { | 109 enum { |
76 INITIAL, // Start state, no assignments happened | 110 INITIAL, // Start state, no assignments happened |
77 ASSIGNED, // Assigned a value | 111 ASSIGNED, // Assigned a value |
78 INCONSISTENT // Inconsistent value seen | 112 INCONSISTENT // Inconsistent value seen |
79 } _state; | 113 } _state; |
80 int _value; | 114 int _value; |
81 public: | 115 public: |
82 UniqueValueVisitor() : _state(INITIAL) { } | 116 UniqueValueVisitor(PICL* picl) : _picl(picl), _state(INITIAL) { } |
83 int value() { | 117 int value() { |
84 assert(_state == ASSIGNED, "Precondition"); | 118 assert(_state == ASSIGNED, "Precondition"); |
85 return _value; | 119 return _value; |
86 } | 120 } |
87 void set_value(int value) { | 121 void set_value(int value) { |
94 bool is_inconsistent() { return _state == INCONSISTENT; } | 128 bool is_inconsistent() { return _state == INCONSISTENT; } |
95 void set_inconsistent() { _state = INCONSISTENT; } | 129 void set_inconsistent() { _state = INCONSISTENT; } |
96 | 130 |
97 static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) { | 131 static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) { |
98 UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg); | 132 UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg); |
133 PICL* picl = state->_picl; | |
99 assert(!state->is_inconsistent(), "Precondition"); | 134 assert(!state->is_inconsistent(), "Precondition"); |
100 int curr; | 135 int curr; |
101 if (PICL::get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { | 136 if (picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { |
102 if (!state->is_assigned()) { // first iteration | 137 if (!state->is_assigned()) { // first iteration |
103 state->set_value(curr); | 138 state->set_value(curr); |
104 } else if (curr != state->value()) { // following iterations | 139 } else if (curr != state->value()) { // following iterations |
105 state->set_inconsistent(); | 140 state->set_inconsistent(); |
106 } | 141 } |
120 } | 155 } |
121 static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) { | 156 static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) { |
122 return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state); | 157 return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state); |
123 } | 158 } |
124 | 159 |
125 PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) { | 160 PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) { |
126 if (picl_initialize() == PICL_SUCCESS) { | 161 if (!open_library()) { |
162 return; | |
163 } | |
164 if (_picl_initialize() == PICL_SUCCESS) { | |
127 picl_nodehdl_t rooth; | 165 picl_nodehdl_t rooth; |
128 if (picl_get_root(&rooth) == PICL_SUCCESS) { | 166 if (_picl_get_root(&rooth) == PICL_SUCCESS) { |
129 UniqueValueVisitor L1_state; | 167 UniqueValueVisitor L1_state(this); |
130 // Visit all "cpu" class instances | 168 // Visit all "cpu" class instances |
131 picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper); | 169 _picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper); |
132 if (L1_state.is_initial()) { // Still initial, iteration found no values | 170 if (L1_state.is_initial()) { // Still initial, iteration found no values |
133 // Try walk all "core" class instances, it might be a Fujitsu machine | 171 // Try walk all "core" class instances, it might be a Fujitsu machine |
134 picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper); | 172 _picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper); |
135 } | 173 } |
136 if (L1_state.is_assigned()) { // Is there a value? | 174 if (L1_state.is_assigned()) { // Is there a value? |
137 _L1_data_cache_line_size = L1_state.value(); | 175 _L1_data_cache_line_size = L1_state.value(); |
138 } | 176 } |
139 | 177 |
140 UniqueValueVisitor L2_state; | 178 UniqueValueVisitor L2_state(this); |
141 picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper); | 179 _picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper); |
142 if (L2_state.is_initial()) { | 180 if (L2_state.is_initial()) { |
143 picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper); | 181 _picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper); |
144 } | 182 } |
145 if (L2_state.is_assigned()) { | 183 if (L2_state.is_assigned()) { |
146 _L2_cache_line_size = L2_state.value(); | 184 _L2_cache_line_size = L2_state.value(); |
147 } | 185 } |
148 } | 186 } |
149 picl_shutdown(); | 187 _picl_shutdown(); |
150 } | 188 } |
189 close_library(); | |
151 } | 190 } |
152 | 191 |
153 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } | 192 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } |
154 unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } | 193 unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } |
155 }; | 194 }; |
157 extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { | 196 extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { |
158 return PICL::get_l1_data_cache_line_size(nodeh, result); | 197 return PICL::get_l1_data_cache_line_size(nodeh, result); |
159 } | 198 } |
160 extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { | 199 extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { |
161 return PICL::get_l2_cache_line_size(nodeh, result); | 200 return PICL::get_l2_cache_line_size(nodeh, result); |
201 } | |
202 | |
203 template<typename FuncType> | |
204 bool PICL::bind(FuncType& func, const char* name) { | |
205 func = reinterpret_cast<FuncType>(dlsym(_dl_handle, name)); | |
206 return func != NULL; | |
207 } | |
208 | |
209 bool PICL::bind_library_functions() { | |
210 assert(_dl_handle != NULL, "library should be open"); | |
211 return bind(_picl_initialize, "picl_initialize" ) && | |
212 bind(_picl_shutdown, "picl_shutdown" ) && | |
213 bind(_picl_get_root, "picl_get_root" ) && | |
214 bind(_picl_walk_tree_by_class, "picl_walk_tree_by_class") && | |
215 bind(_picl_get_prop_by_name, "picl_get_prop_by_name" ) && | |
216 bind(_picl_get_propval, "picl_get_propval" ) && | |
217 bind(_picl_get_propinfo, "picl_get_propinfo" ); | |
218 } | |
219 | |
220 bool PICL::open_library() { | |
221 _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY); | |
222 if (_dl_handle == NULL) { | |
223 warning("PICL (libpicl.so.1) is missing. Performance will not be optimal."); | |
224 return false; | |
225 } | |
226 if (!bind_library_functions()) { | |
227 assert(false, "unexpected PICL API change"); | |
228 close_library(); | |
229 return false; | |
230 } | |
231 return true; | |
232 } | |
233 | |
234 void PICL::close_library() { | |
235 assert(_dl_handle != NULL, "library should be open"); | |
236 dlclose(_dl_handle); | |
237 _dl_handle = NULL; | |
162 } | 238 } |
163 | 239 |
164 // We need to keep these here as long as we have to build on Solaris | 240 // We need to keep these here as long as we have to build on Solaris |
165 // versions before 10. | 241 // versions before 10. |
166 #ifndef SI_ARCHITECTURE_32 | 242 #ifndef SI_ARCHITECTURE_32 |