blob: 59ab34e8c13e1e47cfb5b918f551b4175855409a [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* more patents listed at http://www.pivotal.io/patents.
*========================================================================
*/
package com.gemstone.gemfire.internal;
import com.gemstone.gemfire.InternalGemFireError;
import com.gemstone.gemfire.pdx.internal.unsafe.UnsafeWrapper;
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
/**
* The class puts in one place the code that will determine the
* name of the GemFire shared library.
* This aids debugging.
*/
public class SharedLibrary {
/** A suffix added on to distinguish between the Linux and Solaris library
* names since they reside in the same directory.
*/
private final static String SOLARIS_LIBRARY_SUFFIX = "_sol";
private static final boolean is64Bit;
private static final int referenceSize;
private static final int objectHeaderSize;
private static final UnsafeWrapper unsafe;
static {
UnsafeWrapper tmp = null;
try {
tmp = new UnsafeWrapper();
} catch (RuntimeException ignore) {
} catch (Error ignore) {
}
unsafe = tmp;
}
static {
int sunbits = Integer.getInteger("sun.arch.data.model", 0).intValue(); // also used by JRockit
if (sunbits == 64) {
is64Bit = true;
} else if (sunbits == 32) {
is64Bit = false;
} else {
int ibmbits = Integer.getInteger("com.ibm.vm.bitmode", 0).intValue();
if (ibmbits == 64) {
is64Bit = true;
} else if (ibmbits == 32) {
is64Bit = false;
} else {
if (unsafe != null) {
is64Bit = unsafe.getAddressSize() == 8;
} else {
is64Bit = false;
}
}
}
if (!is64Bit) {
referenceSize = 4;
objectHeaderSize = 8;
} else {
int scaleIndex = 0;
int tmpReferenceSize = 0;
int tmpObjectHeaderSize = 0;
if (unsafe != null) {
// Use unsafe to figure out the size of an object reference since we might
// be using compressed oops.
scaleIndex = unsafe.arrayScaleIndex(Object[].class);
if (scaleIndex == 4) {
// compressed oops
tmpReferenceSize = 4;
tmpObjectHeaderSize = 12;
} else if (scaleIndex == 8) {
tmpReferenceSize = 8;
tmpObjectHeaderSize = 16;
} else {
System.out.println("Unexpected arrayScaleIndex " + scaleIndex + ". Using max heap size to estimate reference size.");
scaleIndex = 0;
}
}
if (scaleIndex == 0) {
// If our heap is > 32G then assume large oops. Otherwise assume compressed oops.
if (Runtime.getRuntime().maxMemory() > (32L*1024*1024*1024)) {
tmpReferenceSize = 8;
tmpObjectHeaderSize = 16;
} else {
tmpReferenceSize = 4;
tmpObjectHeaderSize = 12;
}
}
referenceSize = tmpReferenceSize;
objectHeaderSize = tmpObjectHeaderSize;
}
}
/**
* @return true if this process is 64bit
* @throws RuntimeException if sun.arch.data.model doesn't fit expectations
*/
public static boolean is64Bit() {
return is64Bit;
}
/**
* @return true if this process is running on Solaris, no effort is made to
* distinguish between sparc and x86, the library will simply fail to load.
* @throws RuntimeException if sun.arch.data.model doesn't fit expectations
*/
public static boolean isSolaris() {
String osName = System.getProperty("os.name");
return osName.equals("SunOS");
}
/**
* Returns the os specific name of the GemFire shared library.
*/
public static String getName() {
StringBuffer result = new StringBuffer("gemfire");
if (isSolaris()) {
result.append(SOLARIS_LIBRARY_SUFFIX);
}
if (is64Bit()) {
result.append("64");
}
if (Boolean.getBoolean("gemfire.debug")) {
result.append("_g");
}
return result.toString();
}
public static void loadLibrary(boolean debug) throws UnsatisfiedLinkError {
String library = getName();
try {
URL gemfireJarURL = GemFireVersion.getJarURL();
if (gemfireJarURL == null) {
throw new InternalGemFireError("Unable to locate jar file.");
}
String gemfireJar = null;
try {
gemfireJar = URLDecoder.decode(gemfireJarURL.getFile(), "UTF-8");
} catch ( java.io.UnsupportedEncodingException uee ) {
//This should never happen because UTF-8 is required to be implemented
throw new RuntimeException(uee);
}
int index = gemfireJar.lastIndexOf("/");
if ( index == -1 ) {
throw new InternalGemFireError("Unable to parse gemfire jar path.");
}
String libDir = gemfireJar.substring(0, index+1);
File libraryPath = new File(libDir, System.mapLibraryName(library));
if (libraryPath.exists()) {
System.load(libraryPath.getPath());
return;
}
} catch (InternalGemFireError ige) {
/** Unable to make a guess as to where the gemfire native library
is based on its position relative to gemfire jar. */
if (debug) {
System.out.println("Problem loading library from URL path: " + ige);
}
} catch (UnsatisfiedLinkError ule) {
/** Unable to load the gemfire native library in the product tree,
This is very unexpected and should not happen.
Reattempting using System.loadLibrary */
if (debug) {
System.out.println("Problem loading library from URL path: " + ule);
}
}
System.loadLibrary(library);
}
/**
* Returns the size in bytes of a C pointer in this
* shared library, returns 4 for a 32 bit shared library,
* and 8 for a 64 bit shared library .
* This method makes a native call, so you can't use it to
* determine which library to load .
*
*/
public static int pointerSizeBytes() { return SmHelper.pointerSizeBytes();}
/**
* Accessor method for the is64Bit flag
* @return returns a boolean indicating if the 64bit native library was loaded.
* @since 5.1
*/
public final static boolean getIs64Bit() { return PureJavaMode.is64Bit(); }
public static int getReferenceSize() {
return referenceSize;
}
public static int getObjectHeaderSize() {
return objectHeaderSize;
}
}