hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
changeset 26579 522d6486f410
parent 26175 d8a4e0741439
child 27426 66fc2ab37003
equal deleted inserted replaced
26578:1cb9e59a06ab 26579:522d6486f410
    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 */
   209     assert(strcmp(implementation, "UNKNOWN") != 0,
   339     assert(strcmp(implementation, "UNKNOWN") != 0,
   210            "unknown cpu info (changed kstat interface?)");
   340            "unknown cpu info (changed kstat interface?)");
   211     kstat_close(kc);
   341     kstat_close(kc);
   212   }
   342   }
   213 
   343 
       
   344   // Figure out cache line sizes using PICL
       
   345   PICL picl;
       
   346   _L1_data_cache_line_size = picl.L1_data_cache_line_size();
       
   347   _L2_cache_line_size      = picl.L2_cache_line_size();
       
   348 
   214   return features;
   349   return features;
   215 }
   350 }