26 #include "memory/allocation.hpp" |
26 #include "memory/allocation.hpp" |
27 #include "memory/allocation.inline.hpp" |
27 #include "memory/allocation.inline.hpp" |
28 #include "runtime/os.hpp" |
28 #include "runtime/os.hpp" |
29 #include "vm_version_sparc.hpp" |
29 #include "vm_version_sparc.hpp" |
30 |
30 |
31 # include <sys/auxv.h> |
31 #include <sys/auxv.h> |
32 # include <sys/auxv_SPARC.h> |
32 #include <sys/auxv_SPARC.h> |
33 # include <sys/systeminfo.h> |
33 #include <sys/systeminfo.h> |
34 # include <kstat.h> |
34 #include <kstat.h> |
|
35 #include <picl.h> |
|
36 |
|
37 extern "C" static int PICL_get_l1_data_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); |
|
39 |
|
40 class PICL { |
|
41 // Get a value of the integer property. The value in the tree can be either 32 or 64 bit |
|
42 // depending on the platform. The result is converted to int. |
|
43 static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { |
|
44 picl_propinfo_t pinfo; |
|
45 picl_prophdl_t proph; |
|
46 if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || |
|
47 picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { |
|
48 return PICL_FAILURE; |
|
49 } |
|
50 |
|
51 if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) { |
|
52 assert(false, "Invalid property type"); |
|
53 return PICL_FAILURE; |
|
54 } |
|
55 if (pinfo.size == sizeof(int64_t)) { |
|
56 int64_t val; |
|
57 if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { |
|
58 return PICL_FAILURE; |
|
59 } |
|
60 *result = static_cast<int>(val); |
|
61 } else if (pinfo.size == sizeof(int32_t)) { |
|
62 int32_t val; |
|
63 if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { |
|
64 return PICL_FAILURE; |
|
65 } |
|
66 *result = static_cast<int>(val); |
|
67 } else { |
|
68 assert(false, "Unexpected integer property size"); |
|
69 return PICL_FAILURE; |
|
70 } |
|
71 return PICL_SUCCESS; |
|
72 } |
|
73 |
|
74 // Visitor and a state machine that visits integer properties and verifies that the |
|
75 // values are the same. Stores the unique value observed. |
|
76 class UniqueValueVisitor { |
|
77 enum { |
|
78 INITIAL, // Start state, no assignments happened |
|
79 ASSIGNED, // Assigned a value |
|
80 INCONSISTENT // Inconsistent value seen |
|
81 } _state; |
|
82 int _value; |
|
83 public: |
|
84 UniqueValueVisitor() : _state(INITIAL) { } |
|
85 int value() { |
|
86 assert(_state == ASSIGNED, "Precondition"); |
|
87 return _value; |
|
88 } |
|
89 void set_value(int value) { |
|
90 assert(_state == INITIAL, "Precondition"); |
|
91 _value = value; |
|
92 _state = ASSIGNED; |
|
93 } |
|
94 bool is_initial() { return _state == INITIAL; } |
|
95 bool is_assigned() { return _state == ASSIGNED; } |
|
96 bool is_inconsistent() { return _state == INCONSISTENT; } |
|
97 void set_inconsistent() { _state = INCONSISTENT; } |
|
98 |
|
99 static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) { |
|
100 UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg); |
|
101 assert(!state->is_inconsistent(), "Precondition"); |
|
102 int curr; |
|
103 if (PICL::get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { |
|
104 if (!state->is_assigned()) { // first iteration |
|
105 state->set_value(curr); |
|
106 } else if (curr != state->value()) { // following iterations |
|
107 state->set_inconsistent(); |
|
108 } |
|
109 } |
|
110 if (state->is_inconsistent()) { |
|
111 return PICL_WALK_TERMINATE; |
|
112 } |
|
113 return PICL_WALK_CONTINUE; |
|
114 } |
|
115 }; |
|
116 |
|
117 int _L1_data_cache_line_size; |
|
118 int _L2_cache_line_size; |
|
119 public: |
|
120 static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) { |
|
121 return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state); |
|
122 } |
|
123 static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) { |
|
124 return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state); |
|
125 } |
|
126 |
|
127 PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) { |
|
128 if (picl_initialize() == PICL_SUCCESS) { |
|
129 picl_nodehdl_t rooth; |
|
130 if (picl_get_root(&rooth) == PICL_SUCCESS) { |
|
131 UniqueValueVisitor L1_state; |
|
132 // Visit all "cpu" class instances |
|
133 picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper); |
|
134 if (L1_state.is_initial()) { // Still initial, iteration found no values |
|
135 // Try walk all "core" class instances, it might be a Fujitsu machine |
|
136 picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper); |
|
137 } |
|
138 if (L1_state.is_assigned()) { // Is there a value? |
|
139 _L1_data_cache_line_size = L1_state.value(); |
|
140 } |
|
141 |
|
142 UniqueValueVisitor L2_state; |
|
143 picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper); |
|
144 if (L2_state.is_initial()) { |
|
145 picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper); |
|
146 } |
|
147 if (L2_state.is_assigned()) { |
|
148 _L2_cache_line_size = L2_state.value(); |
|
149 } |
|
150 } |
|
151 picl_shutdown(); |
|
152 } |
|
153 } |
|
154 |
|
155 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } |
|
156 unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } |
|
157 }; |
|
158 |
|
159 extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { |
|
160 return PICL::get_l1_data_cache_line_size(nodeh, result); |
|
161 } |
|
162 extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { |
|
163 return PICL::get_l2_cache_line_size(nodeh, result); |
|
164 } |
35 |
165 |
36 // We need to keep these here as long as we have to build on Solaris |
166 // We need to keep these here as long as we have to build on Solaris |
37 // versions before 10. |
167 // versions before 10. |
38 #ifndef SI_ARCHITECTURE_32 |
168 #ifndef SI_ARCHITECTURE_32 |
39 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ |
169 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ |