-typedef struct {
- const char* key;
- U32 klen;
- U32 hash;
-} sysinfo_key;
-
-#define SYSINFO_KEY_SET_HASH(S) PERL_HASH((S).hash, (S).key, (S).klen)
-#define SYSINFO_KEY_STORE(H,S,V) hv_store((H), (S).key, (S).klen, (V), (S).hash)
-
-static sysinfo_key key_uptime = { "uptime", 6, 0 };
-static sysinfo_key key_load1 = { "load1", 5, 0 };
-static sysinfo_key key_load5 = { "load5", 5, 0 };
-static sysinfo_key key_load15 = { "load15", 6, 0 };
-static sysinfo_key key_totalram = { "totalram", 8, 0 };
-static sysinfo_key key_freeram = { "freeram", 7, 0 };
-static sysinfo_key key_sharedram = { "sharedram", 9, 0 };
-static sysinfo_key key_bufferram = { "bufferram", 9, 0 };
-static sysinfo_key key_totalswap = { "totalswap", 9, 0 };
-static sysinfo_key key_freeswap = { "freeswap", 8, 0 };
-static sysinfo_key key_procs = { "procs", 5, 0 };
-#if SYSINFO_EXTENDED
-static sysinfo_key key_totalhigh = { "totalhigh", 9, 0 };
-static sysinfo_key key_freehigh = { "freehigh", 8, 0 };
-static sysinfo_key key_mem_unit = { "mem_unit", 8, 0 };
-#endif /* SYSINFO_EXTENDED */
+/* --- Keys ---------------------------------------------------------------- */
+
+#define LS_KEY(K) (ls_key_##K##_sv)
+#if PERL_REVISION <= 4 || (PERL_REVISION == 5 && PERL_VERSION <= 6)
+/* newSVpvn_share doesn't exist in perl-5.6.x */
+# define LS_HASH(K) (ls_key_##K##_hash)
+# define LS_KEY_DECLARE(K) STATIC const char LS_KEY(K)[] = #K; \
+ STATIC U32 LS_HASH(K) = 0
+# define LS_KEY_DEFINE(K) PERL_HASH(LS_HASH(K), LS_KEY(K), sizeof(#K)-1)
+# define LS_KEY_STORE(H,K,V) hv_store((H), LS_KEY(K), sizeof(#K)-1, \
+ (V), LS_HASH(K))
+#else
+# if PERL_REVISION >= 5 && PERL_VERSION >= 9 && PERL_SUBVERSION >= 3
+/* From perl-5.9.3 (#24802), the key is only a SVt_PV and one can get the hash
+ * value with the SvSHARED_HASH() macro. */
+# define LS_HASH(K) SvSHARED_HASH(LS_KEY(K))
+# else
+/* Before, the key was a SVt_PVIV and the hash was stored in the UV field. */
+# define LS_HASH(K) SvUVX(LS_KEY(K))
+# endif
+# define LS_KEY_DECLARE(K) STATIC SV *LS_KEY(K) = NULL
+# define LS_KEY_DEFINE(K) LS_KEY(K) = newSVpvn_share(#K, sizeof(#K)-1, 0)
+# define LS_KEY_STORE(H,K,V) hv_store_ent((H), LS_KEY(K), (V), LS_HASH(K))
+#endif
+
+LS_KEY_DECLARE(uptime);
+LS_KEY_DECLARE(load1);
+LS_KEY_DECLARE(load5);
+LS_KEY_DECLARE(load15);
+LS_KEY_DECLARE(totalram);
+LS_KEY_DECLARE(freeram);
+LS_KEY_DECLARE(sharedram);
+LS_KEY_DECLARE(bufferram);
+LS_KEY_DECLARE(totalswap);
+LS_KEY_DECLARE(freeswap);
+LS_KEY_DECLARE(procs);
+#if LS_HAS_EXTENDED
+LS_KEY_DECLARE(totalhigh);
+LS_KEY_DECLARE(freehigh);
+LS_KEY_DECLARE(mem_unit);
+#endif /* LS_HAS_EXTENDED */
+
+/* --- XS ------------------------------------------------------------------ */