Mercurial > hg > graal-jvmci-8
comparison src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp @ 22963:f79d8e8caecb
8076968: PICL based initialization of L2 cache line size on some SPARC systems is incorrect
Summary: Chcek both l2-dcache-line-size and l2-cache-line-size properties to determine the size of the line
Reviewed-by: kvn
author | iveresov |
---|---|
date | Fri, 10 Apr 2015 15:27:05 -0700 |
parents | 2ac41ee91b06 |
children | a0622494f6b2 |
comparison
equal
deleted
inserted
replaced
22962:2ac41ee91b06 | 22963:f79d8e8caecb |
---|---|
125 bool is_initial() { return _state == INITIAL; } | 125 bool is_initial() { return _state == INITIAL; } |
126 bool is_assigned() { return _state == ASSIGNED; } | 126 bool is_assigned() { return _state == ASSIGNED; } |
127 bool is_inconsistent() { return _state == INCONSISTENT; } | 127 bool is_inconsistent() { return _state == INCONSISTENT; } |
128 void set_inconsistent() { _state = INCONSISTENT; } | 128 void set_inconsistent() { _state = INCONSISTENT; } |
129 | 129 |
130 void visit(picl_nodehdl_t nodeh, const char* name) { | 130 bool visit(picl_nodehdl_t nodeh, const char* name) { |
131 assert(!is_inconsistent(), "Precondition"); | 131 assert(!is_inconsistent(), "Precondition"); |
132 int curr; | 132 int curr; |
133 if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { | 133 if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { |
134 if (!is_assigned()) { // first iteration | 134 if (!is_assigned()) { // first iteration |
135 set_value(curr); | 135 set_value(curr); |
136 } else if (curr != value()) { // following iterations | 136 } else if (curr != value()) { // following iterations |
137 set_inconsistent(); | 137 set_inconsistent(); |
138 } | 138 } |
139 } | 139 return true; |
140 } | |
141 return false; | |
140 } | 142 } |
141 }; | 143 }; |
142 | 144 |
143 class CPUVisitor { | 145 class CPUVisitor { |
144 UniqueValueVisitor _l1_visitor; | 146 UniqueValueVisitor _l1_visitor; |
151 UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor(); | 153 UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor(); |
152 UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor(); | 154 UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor(); |
153 if (!l1_visitor->is_inconsistent()) { | 155 if (!l1_visitor->is_inconsistent()) { |
154 l1_visitor->visit(nodeh, "l1-dcache-line-size"); | 156 l1_visitor->visit(nodeh, "l1-dcache-line-size"); |
155 } | 157 } |
156 if (!l2_visitor->is_inconsistent()) { | 158 static const char* l2_data_cache_line_property_name = NULL; |
157 l2_visitor->visit(nodeh, "l2-cache-line-size"); | 159 // On the first visit determine the name of the l2 cache line size property and memoize it. |
160 if (l2_data_cache_line_property_name == NULL) { | |
161 assert(!l2_visitor->is_inconsistent(), "First iteration cannot be inconsistent"); | |
162 l2_data_cache_line_property_name = "l2-cache-line-size"; | |
163 if (!l2_visitor->visit(nodeh, l2_data_cache_line_property_name)) { | |
164 l2_data_cache_line_property_name = "l2-dcache-line-size"; | |
165 l2_visitor->visit(nodeh, l2_data_cache_line_property_name); | |
166 } | |
167 } else { | |
168 if (!l2_visitor->is_inconsistent()) { | |
169 l2_visitor->visit(nodeh, l2_data_cache_line_property_name); | |
170 } | |
158 } | 171 } |
159 | 172 |
160 if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) { | 173 if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) { |
161 return PICL_WALK_TERMINATE; | 174 return PICL_WALK_TERMINATE; |
162 } | 175 } |
168 } | 181 } |
169 UniqueValueVisitor* l1_visitor() { return &_l1_visitor; } | 182 UniqueValueVisitor* l1_visitor() { return &_l1_visitor; } |
170 UniqueValueVisitor* l2_visitor() { return &_l2_visitor; } | 183 UniqueValueVisitor* l2_visitor() { return &_l2_visitor; } |
171 }; | 184 }; |
172 int _L1_data_cache_line_size; | 185 int _L1_data_cache_line_size; |
173 int _L2_cache_line_size; | 186 int _L2_data_cache_line_size; |
174 public: | 187 public: |
175 static int visit_cpu(picl_nodehdl_t nodeh, void *state) { | 188 static int visit_cpu(picl_nodehdl_t nodeh, void *state) { |
176 return CPUVisitor::visit(nodeh, state); | 189 return CPUVisitor::visit(nodeh, state); |
177 } | 190 } |
178 | 191 |
179 PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) { | 192 PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) { |
180 if (!open_library()) { | 193 if (!open_library()) { |
181 return; | 194 return; |
182 } | 195 } |
183 if (_picl_initialize() == PICL_SUCCESS) { | 196 if (_picl_initialize() == PICL_SUCCESS) { |
184 picl_nodehdl_t rooth; | 197 picl_nodehdl_t rooth; |
192 _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper); | 205 _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper); |
193 if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value? | 206 if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value? |
194 _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value(); | 207 _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value(); |
195 } | 208 } |
196 if (cpu_visitor.l2_visitor()->is_assigned()) { | 209 if (cpu_visitor.l2_visitor()->is_assigned()) { |
197 _L2_cache_line_size = cpu_visitor.l2_visitor()->value(); | 210 _L2_data_cache_line_size = cpu_visitor.l2_visitor()->value(); |
198 } | 211 } |
199 } | 212 } |
200 _picl_shutdown(); | 213 _picl_shutdown(); |
201 } | 214 } |
202 close_library(); | 215 close_library(); |
203 } | 216 } |
204 | 217 |
205 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } | 218 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } |
206 unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } | 219 unsigned int L2_data_cache_line_size() const { return _L2_data_cache_line_size; } |
207 }; | 220 }; |
208 | 221 |
209 | 222 |
210 extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) { | 223 extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) { |
211 return PICL::visit_cpu(nodeh, result); | 224 return PICL::visit_cpu(nodeh, result); |
480 kstat_close(kc); | 493 kstat_close(kc); |
481 } | 494 } |
482 | 495 |
483 // Figure out cache line sizes using PICL | 496 // Figure out cache line sizes using PICL |
484 PICL picl((features & sparc64_family_m) != 0); | 497 PICL picl((features & sparc64_family_m) != 0); |
485 _L2_cache_line_size = picl.L2_cache_line_size(); | 498 _L2_data_cache_line_size = picl.L2_data_cache_line_size(); |
486 | 499 |
487 return features; | 500 return features; |
488 } | 501 } |