diff src/share/vm/graal/graalCompilerToVM.cpp @ 4220:5c80ccb80036

Renaming of VMExits and VMEntries part 1.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 04 Jan 2012 20:59:11 +0100
parents src/share/vm/graal/graalVMEntries.cpp@aaac4894175c
children 8e2985cdaaa5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jan 04 20:59:11 2012 +0100
@@ -0,0 +1,1043 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/fieldDescriptor.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "ci/ciMethodData.hpp"
+#include "compiler/compileBroker.hpp"
+#include "graal/graalVMEntries.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalVMExits.hpp"
+#include "graal/graalVmIds.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/generateOopMap.hpp"
+
+methodOop getMethodFromHotSpotMethod(jobject hotspot_method) {
+  return getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method));
+}
+
+methodOop getMethodFromHotSpotMethod(oop hotspot_method) {
+  return (methodOop)HotSpotMethodResolved::javaMirror(hotspot_method);
+}
+
+// public byte[] RiMethod_code(HotSpotResolvedMethod method);
+JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1code(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_code");
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  int code_size = method->code_size();
+  jbyteArray result = env->NewByteArray(code_size);
+  env->SetByteArrayRegion(result, 0, code_size, (const jbyte *) method->code_base());
+  return result;
+}
+
+// public String RiMethod_signature(HotSpotResolvedMethod method);
+JNIEXPORT jstring JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1signature(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_signature");
+  VM_ENTRY_MARK
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+  assert(method != NULL && method->signature() != NULL, "signature required");
+  return VmIds::toString<jstring>(method->signature(), THREAD);
+}
+
+// public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
+JNIEXPORT jobjectArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_exceptionHandlers");
+  VM_ENTRY_MARK
+  ResourceMark rm;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  typeArrayHandle handlers = method->exception_table();
+  int handler_count = handlers.is_null() ? 0 : handlers->length() / 4;
+
+  instanceKlass::cast(HotSpotExceptionHandler::klass())->initialize(CHECK_NULL);
+  objArrayHandle array = oopFactory::new_objArray(SystemDictionary::RiExceptionHandler_klass(), handler_count, CHECK_NULL);
+
+  for (int i = 0; i < handler_count; i++) {
+    // exception handlers are stored as four integers: start bci, end bci, handler bci, catch class constant pool index
+    int base = i * 4;
+    Handle entry = instanceKlass::cast(HotSpotExceptionHandler::klass())->allocate_instance(CHECK_NULL);
+    HotSpotExceptionHandler::set_startBci(entry, handlers->int_at(base + 0));
+    HotSpotExceptionHandler::set_endBci(entry, handlers->int_at(base + 1));
+    HotSpotExceptionHandler::set_handlerBci(entry, handlers->int_at(base + 2));
+    int catch_class_index = handlers->int_at(base + 3);
+    HotSpotExceptionHandler::set_catchClassIndex(entry, catch_class_index);
+
+    if (catch_class_index == 0) {
+      HotSpotExceptionHandler::set_catchClass(entry, NULL);
+    } else {
+      constantPoolOop cp = instanceKlass::cast(method->method_holder())->constants();
+      KlassHandle loading_klass = method->method_holder();
+      Handle catch_class = GraalCompiler::get_RiType(cp, catch_class_index, loading_klass, CHECK_NULL);
+      if (catch_class->klass() == HotSpotTypeResolved::klass() && java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+        HotSpotExceptionHandler::set_catchClass(entry, NULL);
+        HotSpotExceptionHandler::set_catchClassIndex(entry, 0);
+      } else {
+        HotSpotExceptionHandler::set_catchClass(entry, catch_class());
+      }
+    }
+    array->obj_at_put(i, entry());
+  }
+
+  return (jobjectArray) JNIHandles::make_local(array());
+}
+
+// public boolean RiMethod_hasBalancedMonitors(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_hasBalancedMonitors");
+
+  VM_ENTRY_MARK;
+
+  // Analyze the method to see if monitors are used properly.
+  methodHandle method(THREAD, getMethodFromHotSpotMethod(hotspot_method));
+  assert(method->has_monitor_bytecodes(), "should have checked this");
+
+  // Check to see if a previous compilation computed the monitor-matching analysis.
+  if (method->guaranteed_monitor_matching()) {
+    return true;
+  }
+
+  {
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    GeneratePairingInfo gpi(method);
+    gpi.compute_map(CATCH);
+    if (!gpi.monitor_safe()) {
+      return false;
+    }
+    method->set_guaranteed_monitor_matching();
+  }
+  return true;
+}
+
+// public RiMethod getRiMethod(java.lang.reflect.Method reflectionMethod);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getRiMethod(JNIEnv *, jobject, jobject reflection_method_handle) {
+  TRACE_graal_3("CompilerToVM::getRiMethod");
+  VM_ENTRY_MARK;
+  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
+  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
+  int slot = java_lang_reflect_Method::slot(reflection_method);
+  klassOop holder = java_lang_Class::as_klassOop(reflection_holder);
+  methodOop method = instanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+// public boolean RiMethod_uniqueConcreteMethod(long vmId);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_uniqueConcreteMethod");
+
+  VM_ENTRY_MARK;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  KlassHandle holder = method->method_holder();
+  if (holder->is_interface()) {
+    // Cannot trust interfaces. Because of:
+    // interface I { void foo(); }
+    // class A { public void foo() {} }
+    // class B extends A implements I { }
+    // class C extends B { public void foo() { } }
+    // class D extends B { }
+    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
+    return false;
+  }
+  methodHandle unique_concrete;
+  {
+    ResourceMark rm;
+    MutexLocker locker(Compile_lock);
+    unique_concrete = Dependencies::find_unique_concrete_method(holder(), method());
+  }
+  if (unique_concrete.is_null()) {
+    return NULL;
+  } else {
+    Handle method_resolved = GraalCompiler::createHotSpotMethodResolved(unique_concrete, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, method_resolved());
+  }
+}
+
+// public native int RiMethod_invocationCount(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1invocationCount(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_invocationCount");
+  return getMethodFromHotSpotMethod(hotspot_method)->invocation_count();
+}
+
+// public native int RiMethod_exceptionProbability(long vmId, int bci);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_2exceptionProbability(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
+  TRACE_graal_3("CompilerToVM::RiMethod_exceptionProbability");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  methodDataHandle method_data = method->method_data();
+  if (method_data == NULL || !method_data->is_mature()) {
+    return -1;
+  }
+  ProfileData* data = method_data->bci_to_data(bci);
+  if (data == NULL) {
+    return 0;
+  }
+  uint trap = Deoptimization::trap_state_is_recompiled(data->trap_state())? 1: 0;
+  if (trap > 0) {
+    return 100;
+  } else {
+    return trap;
+  }
+}
+
+// ------------------------------------------------------------------
+// Adjust a CounterData count to be commensurate with
+// interpreter_invocation_count.  If the MDO exists for
+// only 25% of the time the method exists, then the
+// counts in the MDO should be scaled by 4X, so that
+// they can be usefully and stably compared against the
+// invocation counts in methods.
+int scale_count(methodDataOop method_data, int count) {
+  if (count > 0) {
+    int counter_life;
+    int method_life = method_data->method()->interpreter_invocation_count();
+    int current_mileage = methodDataOopDesc::mileage_of(method_data->method());
+    int creation_mileage = method_data->creation_mileage();
+    counter_life = current_mileage - creation_mileage;
+
+    // counter_life due to backedge_counter could be > method_life
+    if (counter_life > method_life)
+      counter_life = method_life;
+    if (0 < counter_life && counter_life <= method_life) {
+      count = (int)((double)count * method_life / counter_life + 0.5);
+      count = (count > 0) ? count : 1;
+    }
+  }
+  return count;
+}
+
+// public native RiTypeProfile RiMethod_typeProfile(long vmId, int bci);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_2typeProfile(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
+  TRACE_graal_3("CompilerToVM::RiMethod_typeProfile");
+  VM_ENTRY_MARK;
+  Handle obj;
+  
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  methodDataHandle method_data = method->method_data();
+  if (method_data == NULL || !method_data->is_mature()) {
+    return NULL;
+  }
+  ResourceMark rm;
+  ProfileData* data = method_data->bci_to_data(bci);
+  if (data != NULL && data->is_ReceiverTypeData()) {
+    ReceiverTypeData* recv = data->as_ReceiverTypeData();
+    GrowableArray<KlassHandle> receivers;
+    GrowableArray<int> counts;
+    // determine morphism
+    uint total_count = 0;
+    for (uint i = 0; i < recv->row_limit(); i++) {
+      klassOop receiver = recv->receiver(i);
+      if (receiver == NULL)  continue;
+      uint count = recv->receiver_count(i);
+      total_count += count;
+      receivers.append(receiver);
+      counts.append(count);
+    }
+
+    instanceKlass::cast(RiTypeProfile::klass())->initialize(CHECK_NULL);
+    obj = instanceKlass::cast(RiTypeProfile::klass())->allocate_instance(CHECK_NULL);
+    assert(obj() != NULL, "must succeed in allocating instance");
+
+    int count = MAX2(total_count, recv->count());
+    RiTypeProfile::set_count(obj, scale_count(method_data(), count));
+    RiTypeProfile::set_morphism(obj, receivers.length());
+
+    if (receivers.length() > 0) {
+      typeArrayHandle probabilities = oopFactory::new_typeArray(T_FLOAT, receivers.length(), CHECK_NULL);
+      objArrayHandle types = oopFactory::new_objArray(SystemDictionary::RiType_klass(), receivers.length(), CHECK_NULL);
+      for (int i = 0; i < receivers.length(); i++) {
+        KlassHandle receiver = receivers.at(i);
+
+        float prob = counts.at(i) / (float) total_count;
+        Handle type = GraalCompiler::get_RiType(receiver, CHECK_NULL);
+
+        probabilities->float_at_put(i, prob);
+        types->obj_at_put(i, type());
+
+      }
+
+      RiTypeProfile::set_probabilities(obj, probabilities());
+      RiTypeProfile::set_types(obj, types());
+    } else {
+      RiTypeProfile::set_probabilities(obj, NULL);
+      RiTypeProfile::set_types(obj, NULL);
+    }
+  }
+  return JNIHandles::make_local(obj());
+}
+
+JNIEXPORT jdouble JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_2branchProbability(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
+  TRACE_graal_3("CompilerToVM::RiMethod_typeProfile");
+  ResourceMark rm;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  methodDataHandle method_data = method->method_data();
+
+  if (method_data == NULL || !method_data->is_mature()) return -1;
+  method_data->bci_to_data(bci);
+  
+  ProfileData* data = method_data->bci_to_data(bci);
+  if (data == NULL || !data->is_JumpData())  return -1;
+
+  // get taken and not taken values
+  int     taken = data->as_JumpData()->taken();
+  int not_taken = 0;
+  if (data->is_BranchData()) {
+    not_taken = data->as_BranchData()->not_taken();
+  }
+
+  // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful.
+  // We also check that individual counters are positive first, otherwise the sum can become positive.
+  if (taken < 0 || not_taken < 0 || taken + not_taken < 40) return -1;
+
+  // Pin probability to sane limits
+  if (taken == 0)
+    return 0;
+  else if (not_taken == 0)
+    return 1;
+  else {                         // Compute probability of true path
+    return (jdouble)(taken) / (taken + not_taken);
+  }
+}
+
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_2switchProbability(JNIEnv *, jobject, jobject hotspot_method, jint bci) {
+  TRACE_graal_3("CompilerToVM::RiMethod_typeProfile");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  methodDataHandle method_data = method->method_data();
+
+  if (method_data == NULL || !method_data->is_mature()) return NULL;
+
+  ProfileData* data = method_data->bci_to_data(bci);
+  if (data == NULL || !data->is_MultiBranchData())  return NULL;
+
+  MultiBranchData* branch_data = data->as_MultiBranchData();
+
+  long sum = 0;
+  int cases = branch_data->number_of_cases();
+  GrowableArray<uint>* counts = new GrowableArray<uint>(cases + 1);
+
+  for (int i = 0; i < cases; i++) {
+    uint value = branch_data->count_at(i);
+    sum += value;
+    counts->append(value);
+  }
+  uint value = branch_data->default_count();
+  sum += value;
+  counts->append(value);
+
+  // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful.
+  // We also check that individual counters are positive first, otherwise the sum can become positive.
+  if (sum < 10 * (cases + 3)) return NULL;
+
+  typeArrayOop probability = oopFactory::new_typeArray(T_DOUBLE, cases + 1, CHECK_NULL);
+  for (int i = 0; i < cases + 1; i++) {
+    probability->double_at_put(i, counts->at(i) / (double) sum);
+  }
+  return JNIHandles::make_local(probability);
+}
+
+// public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasCompiledCode(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_hasCompiledCode");
+  return getMethodFromHotSpotMethod(hotspot_method)->has_compiled_code();
+}
+
+// public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass) {
+  TRACE_graal_3("CompilerToVM::RiSignature_lookupType");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  Symbol* nameSymbol = VmIds::toSymbol(jname);
+  Handle name = JNIHandles::resolve(jname);
+
+  oop result;
+  if (nameSymbol == vmSymbols::int_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_INT, THREAD);
+  } else if (nameSymbol == vmSymbols::long_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_LONG, THREAD);
+  } else if (nameSymbol == vmSymbols::bool_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_BOOLEAN, THREAD);
+  } else if (nameSymbol == vmSymbols::char_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_CHAR, THREAD);
+  } else if (nameSymbol == vmSymbols::short_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_SHORT, THREAD);
+  } else if (nameSymbol == vmSymbols::byte_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_BYTE, THREAD);
+  } else if (nameSymbol == vmSymbols::double_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_DOUBLE, THREAD);
+  } else if (nameSymbol == vmSymbols::float_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_FLOAT, THREAD);
+  } else {
+    klassOop resolved_type = NULL;
+    // if the name isn't in the symbol table then the class isn't loaded anyway...
+    if (nameSymbol != NULL) {
+      Handle classloader;
+      Handle protectionDomain;
+      if (JNIHandles::resolve(accessingClass) != NULL) {
+        classloader = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader();
+        protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain();
+      }
+      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        resolved_type = NULL;
+      }
+    }
+    if (resolved_type != NULL) {
+      Handle type = GraalCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL);
+      result = type();
+    } else {
+      Handle type = VMToCompiler::createRiTypeUnresolved(name, THREAD);
+      result = type();
+    }
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+}
+
+// public Object RiConstantPool_lookupConstant(HotSpotTypeResolved type, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupConstant");
+  VM_ENTRY_MARK;
+
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+
+  oop result = NULL;
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_int()) {
+    result = VMToCompiler::createCiConstant(CiKind::Int(), cp->int_at(index), CHECK_0);
+  } else if (tag.is_long()) {
+    result = VMToCompiler::createCiConstant(CiKind::Long(), cp->long_at(index), CHECK_0);
+  } else if (tag.is_float()) {
+    result = VMToCompiler::createCiConstantFloat(cp->float_at(index), CHECK_0);
+  } else if (tag.is_double()) {
+    result = VMToCompiler::createCiConstantDouble(cp->double_at(index), CHECK_0);
+  } else if (tag.is_string() || tag.is_unresolved_string()) {
+    oop string = NULL;
+    if (cp->is_pseudo_string_at(index)) {
+      string = cp->pseudo_string_at(index);
+    } else {
+      string = cp->string_at(index, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        // TODO: Gracefully exit compilation.
+        fatal("out of memory during compilation!");
+        return NULL;
+      }
+    }
+    result = VMToCompiler::createCiConstantObject(string, CHECK_0);
+  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
+    Handle type = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+    result = type();
+  } else if (tag.is_object()) {
+    oop obj = cp->object_at(index);
+    assert(obj->is_instance(), "must be an instance");
+    result = VMToCompiler::createCiConstantObject(obj, CHECK_NULL);
+  } else {
+    ShouldNotReachHere();
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+}
+
+// public RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jobject type, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupMethod");
+  VM_ENTRY_MARK;
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  instanceKlassHandle pool_holder(cp->pool_holder());
+
+  Bytecodes::Code bc = (Bytecodes::Code) (((int) byteCode) & 0xFF);
+  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
+  if (!method.is_null()) {
+    Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, ret());
+  } else {
+    // Get the method's name and signature.
+    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
+    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
+    int holder_index = cp->klass_ref_index_at(index);
+    Handle type = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createRiMethodUnresolved(name, signature, type, THREAD));
+  }
+}
+
+// public RiType RiConstantPool_lookupType(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupType(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupType");
+  VM_ENTRY_MARK;
+
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  Handle result = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+}
+
+// public void RiConstantPool_loadReferencedType(long vmId, int cpi);
+JNIEXPORT void JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1loadReferencedType(JNIEnv *env, jobject, jobject type, jint index, jbyte op) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_loadReferencedType");
+  VM_ENTRY_MARK;
+  
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  int byteCode = (op & 0xFF);
+  if (byteCode != Bytecodes::_checkcast && byteCode != Bytecodes::_instanceof && byteCode != Bytecodes::_new && byteCode != Bytecodes::_anewarray && byteCode != Bytecodes::_multianewarray) {
+    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
+  }
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_field_or_method()) {
+    index = cp->uncached_klass_ref_index_at(index);
+    tag = cp->tag_at(index);
+  }
+
+  if (tag.is_unresolved_klass() || tag.is_klass()) {
+    klassOop klass = cp->klass_at(index, CHECK);
+    if (klass->klass_part()->oop_is_instance()) {
+      instanceKlass::cast(klass)->initialize(CHECK);
+    }
+  }
+}
+
+// public RiField RiConstantPool_lookupField(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupField");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(constantPoolHolder)))->constants();
+
+  int nt_index = cp->name_and_type_ref_index_at(index);
+  int sig_index = cp->signature_ref_index_at(nt_index);
+  Symbol* signature = cp->symbol_at(sig_index);
+  int name_index = cp->name_ref_index_at(nt_index);
+  Symbol* name = cp->symbol_at(name_index);
+  int holder_index = cp->klass_ref_index_at(index);
+  Handle holder = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+  instanceKlassHandle holder_klass;
+  
+  Bytecodes::Code code = (Bytecodes::Code)(((int) byteCode) & 0xFF);
+  int offset = -1;
+  AccessFlags flags;
+  BasicType basic_type;
+  if (holder->klass() == SystemDictionary::HotSpotTypeResolved_klass()) {
+    FieldAccessInfo result;
+    LinkResolver::resolve_field(result, cp, index,
+                                Bytecodes::java_code(code),
+                                true, false, Thread::current());
+    if (HAS_PENDING_EXCEPTION) {
+      CLEAR_PENDING_EXCEPTION;
+    } else {
+      offset = result.field_offset();
+      flags = result.access_flags();
+      holder_klass = result.klass()->as_klassOop();
+      basic_type = result.field_type();
+      holder = GraalCompiler::get_RiType(holder_klass, CHECK_NULL);
+    }
+  }
+  
+  Handle type = GraalCompiler::get_RiTypeFromSignature(cp, sig_index, cp->pool_holder(), CHECK_NULL);
+  Handle field_handle = GraalCompiler::get_RiField(offset, flags.as_int(), name, holder, type, code, THREAD);
+
+  oop constant_object = NULL;
+    // Check to see if the field is constant.
+  if (!holder_klass.is_null() && holder_klass->is_initialized() && flags.is_final() && flags.is_static()) {
+    // This field just may be constant.  The only cases where it will
+    // not be constant are:
+    //
+    // 1. The field holds a non-perm-space oop.  The field is, strictly
+    //    speaking, constant but we cannot embed non-perm-space oops into
+    //    generated code.  For the time being we need to consider the
+    //    field to be not constant.
+    // 2. The field is a *special* static&final field whose value
+    //    may change.  The three examples are java.lang.System.in,
+    //    java.lang.System.out, and java.lang.System.err.
+
+    bool ok = true;
+    assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
+    if( holder_klass->as_klassOop() == SystemDictionary::System_klass() ) {
+      // Check offsets for case 2: System.in, System.out, or System.err
+      if( offset == java_lang_System::in_offset_in_bytes()  ||
+          offset == java_lang_System::out_offset_in_bytes() ||
+          offset == java_lang_System::err_offset_in_bytes() ) {
+        ok = false;
+      }
+    }
+
+    if (ok) {
+      Handle mirror = holder_klass->java_mirror();
+      switch(basic_type) {
+        case T_OBJECT:
+        case T_ARRAY:
+          constant_object = VMToCompiler::createCiConstantObject(mirror->obj_field(offset), CHECK_0);
+          break;
+        case T_DOUBLE:
+          constant_object = VMToCompiler::createCiConstantDouble(mirror->double_field(offset), CHECK_0);
+          break;
+        case T_FLOAT:
+          constant_object = VMToCompiler::createCiConstantFloat(mirror->float_field(offset), CHECK_0);
+          break;
+        case T_LONG:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Long(), mirror->long_field(offset), CHECK_0);
+          break;
+        case T_INT:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Int(), mirror->int_field(offset), CHECK_0);
+          break;
+        case T_SHORT:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Short(), mirror->short_field(offset), CHECK_0);
+          break;
+        case T_CHAR:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Char(), mirror->char_field(offset), CHECK_0);
+          break;
+        case T_BYTE:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Byte(), mirror->byte_field(offset), CHECK_0);
+          break;
+        case T_BOOLEAN:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Boolean(), mirror->bool_field(offset), CHECK_0);
+          break;
+        default:
+          fatal("Unhandled constant");
+          break;
+      }
+    }
+  }
+  if (constant_object != NULL) {
+    HotSpotField::set_constant(field_handle, constant_object);
+  }
+  return JNIHandles::make_local(THREAD, field_handle());
+}
+
+// public RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) {
+  TRACE_graal_3("CompilerToVM::RiType_resolveMethodImpl");
+  VM_ENTRY_MARK;
+
+  assert(JNIHandles::resolve(resolved_type) != NULL, "");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(resolved_type));
+  Symbol* name_symbol = VmIds::toSymbol(name);
+  Symbol* signature_symbol = VmIds::toSymbol(signature);
+  methodHandle method = klass->klass_part()->lookup_method(name_symbol, signature_symbol);
+  if (method == NULL) {
+    if (TraceGraal >= 3) {
+      ResourceMark rm;
+      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->klass_part()->name()->as_C_string());
+    }
+    return NULL;
+  }
+  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+// public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) {
+  TRACE_graal_3("CompilerToVM::RiType_isSubtypeOf");
+  oop other = JNIHandles::resolve(jother);
+  assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected");
+  assert(JNIHandles::resolve(klass) != NULL, "");
+  klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other));
+  if (thisKlass->klass_part()->oop_is_instance_slow()) {
+    return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass);
+  } else if (thisKlass->klass_part()->oop_is_array()) {
+    return arrayKlass::cast(thisKlass)->is_subtype_of(otherKlass);
+  } else {
+    fatal("unexpected class type");
+    return false;
+  }
+}
+
+// public RiType RiType_componentType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1componentType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_componentType");
+  VM_ENTRY_MARK;
+  KlassHandle array_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  if(array_klass->oop_is_typeArray()) {
+    BasicType t = typeArrayKlass::cast(array_klass())->element_type();
+    oop primitive_type = VMToCompiler::createRiTypePrimitive((int) t, CHECK_NULL);
+    return JNIHandles::make_local(primitive_type);
+  }
+  assert(array_klass->oop_is_objArray(), "just checking");
+  klassOop element_type = objArrayKlass::cast(array_klass())->element_klass();
+  assert(JNIHandles::resolve(klass) != NULL, "");
+  return JNIHandles::make_local(GraalCompiler::get_RiType(element_type, THREAD)());
+}
+
+// public RiType RiType_superType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1superType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_superType");
+  VM_ENTRY_MARK;
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  klassOop k;
+
+  if (klass_handle->oop_is_array()) {
+    k = SystemDictionary::Object_klass();
+  } else {
+    guarantee(klass_handle->oop_is_instance(), "must be instance klass");  
+    k = klass_handle->super();
+  }
+
+  if (k != NULL) {
+    return JNIHandles::make_local(GraalCompiler::get_RiType(k, THREAD)());
+  } else {
+    return NULL;
+  }
+}
+
+// public RiType RiType_uniqueConcreteSubtype(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_uniqueConcreteSubtype");
+  VM_ENTRY_MARK;
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  Klass *up_cast = klass_handle->up_cast_abstract();
+  if (up_cast->is_leaf_class()) {
+    return JNIHandles::make_local(GraalCompiler::get_RiType(up_cast, THREAD)());
+  }
+  return NULL;
+}
+
+// public bool RiType_isInitialized(HotSpotResolvedType klass);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1isInitialized(JNIEnv *, jobject, jobject hotspot_klass) {
+  TRACE_graal_3("CompilerToVM::RiType_isInitialized");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  return instanceKlass::cast(klass)->is_initialized();
+}
+
+// public RiType RiType_arrayOf(HotSpotTypeResolved klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1arrayOf(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_arrayOf");
+  VM_ENTRY_MARK;
+
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  KlassHandle arr = klass_handle->array_klass(THREAD);
+  Handle name = VmIds::toString<Handle>(arr->name(), CHECK_NULL);
+  assert(arr->oop_is_array(), "");
+  return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotTypeResolved(arr, name, THREAD)());
+}
+
+// public RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1fields(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_fields");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  instanceKlassHandle k = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  class MyFieldClosure : public FieldClosure {
+   public:
+    instanceKlassHandle _holder;
+    Handle _resolved_type_holder;
+    GrowableArray<Handle> _field_array;
+
+    MyFieldClosure(instanceKlassHandle& holder, Handle resolved_type_holder) : _holder(holder), _resolved_type_holder(resolved_type_holder) { }
+    
+    virtual void do_field(fieldDescriptor* fd) {
+      if (!Thread::current()->has_pending_exception()) {
+        if (fd->field_holder() == _holder()) {
+          Handle type = GraalCompiler::get_RiTypeFromSignature(fd->constants(), fd->signature_index(), fd->field_holder(), Thread::current());
+          Handle field = VMToCompiler::createRiField(_resolved_type_holder, VmIds::toString<Handle>(fd->name(), Thread::current()), type, fd->offset(), fd->access_flags().as_int(), Thread::current());
+          _field_array.append(field());
+        }
+      }
+    }
+  };
+  MyFieldClosure closure(k, JNIHandles::resolve(klass));
+  k->do_nonstatic_fields(&closure);
+  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::RiResolvedField_klass(), closure._field_array.length(), CHECK_NULL);
+  for (int i=0; i<closure._field_array.length(); ++i) {
+    field_array->obj_at_put(i, closure._field_array.at(i)());
+  }
+  return JNIHandles::make_local(field_array());
+}
+
+// public RiType getPrimitiveArrayType(CiKind kind);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) {
+  TRACE_graal_3("CompilerToVM::getPrimitiveArrayType");
+  VM_ENTRY_MARK;
+  BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(kind));
+  assert(type != T_OBJECT, "primitive type expecteds");
+  Handle result = GraalCompiler::get_RiType(Universe::typeArrayKlassObj(type), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+}
+
+// public long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getMaxCallTargetOffset(JNIEnv *env, jobject, jobject rtcall) {
+  TRACE_graal_3("CompilerToVM::getMaxCallTargetOffset");
+  VM_ENTRY_MARK;
+  oop call = JNIHandles::resolve(rtcall);
+  address target_addr = CodeInstaller::runtime_call_target_address(call);
+  if (target_addr != 0x0) {
+    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
+    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
+    return MAX2(ABS(off_low), ABS(off_high));
+  }
+  return -1;
+}
+
+// public RiType getType(Class<?> javaClass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getType(JNIEnv *env, jobject, jobject javaClass) {
+  TRACE_graal_3("CompilerToVM::getType");
+  VM_ENTRY_MARK;
+  oop javaClassOop = JNIHandles::resolve(javaClass);
+  if (javaClassOop == NULL) {
+    fatal("argument to CompilerToVM.getType must not be NULL");
+    return NULL;
+  } else if (java_lang_Class::is_primitive(javaClassOop)) {
+    BasicType basicType = java_lang_Class::primitive_type(javaClassOop);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createRiTypePrimitive((int) basicType, THREAD));
+  } else {
+    KlassHandle klass = java_lang_Class::as_klassOop(javaClassOop);
+    Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL);
+
+    Handle type = GraalCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, type());
+  }
+}
+
+
+// helpers used to set fields in the HotSpotVMConfig object
+jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
+  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
+  if (id == NULL) {
+    fatal(err_msg("field not found: %s (%s)", name, sig));
+  }
+  return id;
+}
+
+void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); }
+void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); }
+void set_long(JNIEnv* env, jobject obj, const char* name, jlong value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); }
+void set_object(JNIEnv* env, jobject obj, const char* name, jobject value) { env->SetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;"), value); }
+void set_int_array(JNIEnv* env, jobject obj, const char* name, jarray value) { env->SetObjectField(obj, getFieldID(env, obj, name, "[I"), value); }
+
+jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); }
+jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); }
+jlong get_long(JNIEnv* env, jobject obj, const char* name) { return env->GetLongField(obj, getFieldID(env, obj, name, "J")); }
+jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); }
+jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); }
+
+
+BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
+int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
+
+// public HotSpotVMConfig getConfiguration();
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getConfiguration(JNIEnv *env, jobject) {
+  jclass klass = env->FindClass("com/oracle/max/graal/hotspot/HotSpotVMConfig");
+  assert(klass != NULL, "HotSpot vm config class not found");
+  jobject config = env->AllocObject(klass);
+#ifdef _WIN64
+  set_boolean(env, config, "windowsOs", true);
+#else
+  set_boolean(env, config, "windowsOs", false);
+#endif
+  set_boolean(env, config, "verifyPointers", VerifyOops);
+  set_boolean(env, config, "useFastLocking", UseFastLocking);
+  set_boolean(env, config, "useFastNewObjectArray", UseFastNewObjectArray);
+  set_boolean(env, config, "useFastNewTypeArray", UseFastNewTypeArray);
+  set_int(env, config, "codeEntryAlignment", CodeEntryAlignment);
+  set_int(env, config, "vmPageSize", os::vm_page_size());
+  set_int(env, config, "stackShadowPages", StackShadowPages);
+  set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
+  set_int(env, config, "klassStateOffset", instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc));
+  set_int(env, config, "klassStateFullyInitialized", (int)instanceKlass::fully_initialized);
+  set_int(env, config, "threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
+  set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
+  set_int(env, config, "threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
+  set_int(env, config, "instanceHeaderPrototypeOffset", Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes());
+  set_int(env, config, "threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
+  set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+  set_int(env, config, "threadMultiNewArrayStorage", in_bytes(JavaThread::graal_multinewarray_storage_offset()));
+  set_int(env, config, "classMirrorOffset", klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes());
+
+  set_long(env, config, "debugStub", VmIds::addStub((address)warning));
+  set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
+  set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_pointer_id)));
+  set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id)));
+  set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id)));
+  set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id)));
+  set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id)));
+  set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id)));
+  set_long(env, config, "loadKlassStub", VmIds::addStub(Runtime1::entry_for(Runtime1::load_klass_patching_id)));
+  set_long(env, config, "accessFieldStub", VmIds::addStub(Runtime1::entry_for(Runtime1::access_field_patching_id)));
+  set_long(env, config, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub()));
+  set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
+  set_long(env, config, "unwindExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_unwind_exception_call_id)));
+  set_long(env, config, "handleExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
+  set_long(env, config, "handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
+  set_long(env, config, "monitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorenter_id)));
+  set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorexit_id)));
+  set_long(env, config, "fastMonitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_monitorenter_id)));
+  set_long(env, config, "fastMonitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_monitorexit_id)));
+  set_long(env, config, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
+  set_int(env, config, "runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+  set_int(env, config, "klassModifierFlagsOffset", Klass::modifier_flags_offset_in_bytes() + sizeof(oopDesc));
+  set_int(env, config, "klassOopOffset", java_lang_Class::klass_offset_in_bytes());
+  set_boolean(env, config, "isPollingPageFar", Assembler::is_polling_page_far());
+
+  set_int(env, config, "nmethodEntryOffset", nmethod::verified_entry_point_offset());
+
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  switch (bs->kind()) {
+    case BarrierSet::CardTableModRef:
+    case BarrierSet::CardTableExtension: {
+      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
+      assert(base != 0, "unexpected byte_map_base");
+      set_long(env, config, "cardtableStartAddress", base);
+      set_int(env, config, "cardtableShift", CardTableModRefBS::card_shift);
+      break;
+    }
+    case BarrierSet::ModRef:
+    case BarrierSet::Other:
+      set_long(env, config, "cardtableStartAddress", 0);
+      set_int(env, config, "cardtableShift", 0);
+      // No post barriers
+      break;
+#ifndef SERIALGC
+    case BarrierSet::G1SATBCT:
+    case BarrierSet::G1SATBCTLogging:
+#endif // SERIALGC
+    default:
+      ShouldNotReachHere();
+      break;
+    }
+
+  jintArray arrayOffsets = env->NewIntArray(basicTypeCount);
+  for (int i=0; i<basicTypeCount; i++) {
+    jint offset = arrayOopDesc::base_offset_in_bytes(basicTypes[i]);
+    env->SetIntArrayRegion(arrayOffsets, i, 1, &offset);
+  }
+  set_int_array(env, config, "arrayOffsets", arrayOffsets);
+  set_int(env, config, "arrayClassElementOffset", objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc));
+  return config;
+}
+
+// public HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod, jboolean install_code) {
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  HandleMark hm;
+  Handle targetMethodHandle = JNIHandles::resolve(targetMethod);
+  nmethod* nm = NULL;
+  Arena arena;
+  ciEnv env(&arena);
+  CodeInstaller installer(targetMethodHandle, nm, install_code != 0);
+
+  // if install_code is true then we installed the code into the given method, no need to return an RiCompiledMethod
+  if (!install_code && nm != NULL) {
+    instanceKlass::cast(HotSpotCompiledMethod::klass())->initialize(CHECK_NULL);
+    Handle obj = instanceKlass::cast(HotSpotCompiledMethod::klass())->allocate_permanent_instance(CHECK_NULL);
+    assert(obj() != NULL, "must succeed in allocating instance");
+    HotSpotCompiledMethod::set_nmethod(obj, (jlong) nm);
+    HotSpotCompiledMethod::set_method(obj, HotSpotTargetMethod::method(targetMethod));
+    nm->set_graal_compiled_method(obj());
+    return JNIHandles::make_local(obj());
+  } else {
+    return NULL;
+  }
+}
+
+// public long installStub(HotSpotTargetMethod targetMethod, String name);
+JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod) {
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  HandleMark hm;
+  Handle targetMethodHandle = JNIHandles::resolve(targetMethod);
+  jlong id;
+  Arena arena;
+  ciEnv env(&arena);
+  CodeInstaller installer(targetMethodHandle, id);
+  return id;
+}
+
+
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_##f))
+
+#define PROXY           "J"
+#define TYPE            "Lcom/oracle/max/cri/ri/RiType;"
+#define RESOLVED_TYPE   "Lcom/oracle/max/graal/hotspot/ri/HotSpotTypeResolved;"
+#define METHOD          "Lcom/oracle/max/cri/ri/RiMethod;"
+#define RESOLVED_METHOD "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodResolved;"
+#define REFLECT_METHOD  "Ljava/lang/reflect/Method;"
+#define TYPE_PROFILE    "Lcom/oracle/max/cri/ri/RiTypeProfile;"
+#define SIGNATURE       "Lcom/oracle/max/cri/ri/RiSignature;"
+#define FIELD           "Lcom/oracle/max/cri/ri/RiField;"
+#define RESOLVED_FIELD  "Lcom/oracle/max/cri/ri/RiResolvedField;"
+#define CONSTANT_POOL   "Lcom/oracle/max/cri/ri/RiConstantPool;"
+#define EXCEPTION_HANDLERS "[Lcom/oracle/max/cri/ri/RiExceptionHandler;"
+#define TARGET_METHOD   "Lcom/oracle/max/graal/hotspot/HotSpotTargetMethod;"
+#define CONFIG          "Lcom/oracle/max/graal/hotspot/HotSpotVMConfig;"
+#define HS_METHOD       "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethod;"
+#define HS_COMP_METHOD  "Lcom/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod;"
+#define CI_CONSTANT     "Lcom/oracle/max/cri/ci/CiConstant;"
+#define CI_KIND         "Lcom/oracle/max/cri/ci/CiKind;"
+#define CI_RUNTIME_CALL "Lcom/oracle/max/cri/ci/CiRuntimeCall;"
+#define STRING          "Ljava/lang/String;"
+#define OBJECT          "Ljava/lang/Object;"
+#define CLASS           "Ljava/lang/Class;"
+
+JNINativeMethod CompilerToVM_methods[] = {
+  {CC"RiMethod_code",                     CC"("RESOLVED_METHOD")[B",                  FN_PTR(RiMethod_1code)},
+  {CC"RiMethod_signature",                CC"("RESOLVED_METHOD")"STRING,              FN_PTR(RiMethod_1signature)},
+  {CC"RiMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,  FN_PTR(RiMethod_1exceptionHandlers)},
+  {CC"RiMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                   FN_PTR(RiMethod_1hasBalancedMonitors)},
+  {CC"RiMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,              FN_PTR(RiMethod_1uniqueConcreteMethod)},
+  {CC"getRiMethod",                       CC"("REFLECT_METHOD")"METHOD,               FN_PTR(getRiMethod)},
+  {CC"RiMethod_typeProfile",              CC"("RESOLVED_METHOD"I)"TYPE_PROFILE,       FN_PTR(RiMethod_2typeProfile)},
+  {CC"RiMethod_branchProbability",        CC"("RESOLVED_METHOD"I)D",                  FN_PTR(RiMethod_2branchProbability)},
+  {CC"RiMethod_switchProbability",        CC"("RESOLVED_METHOD"I)[D",                 FN_PTR(RiMethod_2switchProbability)},
+  {CC"RiMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                   FN_PTR(RiMethod_1invocationCount)},
+  {CC"RiMethod_exceptionProbability",     CC"("RESOLVED_METHOD"I)I",                  FN_PTR(RiMethod_2exceptionProbability)},
+  {CC"RiMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                   FN_PTR(RiMethod_1hasCompiledCode)},
+  {CC"RiSignature_lookupType",            CC"("STRING RESOLVED_TYPE")"TYPE,           FN_PTR(RiSignature_1lookupType)},
+  {CC"RiConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,               FN_PTR(RiConstantPool_1lookupConstant)},
+  {CC"RiConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,              FN_PTR(RiConstantPool_1lookupMethod)},
+  {CC"RiConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                 FN_PTR(RiConstantPool_1lookupType)},
+  {CC"RiConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                   FN_PTR(RiConstantPool_1loadReferencedType)},
+  {CC"RiConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,               FN_PTR(RiConstantPool_1lookupField)},
+  {CC"RiType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,  FN_PTR(RiType_3resolveMethodImpl)},
+  {CC"RiType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                FN_PTR(RiType_2isSubtypeOf)},
+  {CC"RiType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1componentType)},
+  {CC"RiType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1uniqueConcreteSubtype)},
+  {CC"RiType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1superType)},
+  {CC"RiType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1arrayOf)},
+  {CC"RiType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,       FN_PTR(RiType_1fields)},
+  {CC"RiType_isInitialized",              CC"("RESOLVED_TYPE")Z",                     FN_PTR(RiType_1isInitialized)},
+  {CC"getPrimitiveArrayType",             CC"("CI_KIND")"TYPE,                        FN_PTR(getPrimitiveArrayType)},
+  {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                   FN_PTR(getMaxCallTargetOffset)},
+  {CC"getType",                           CC"("CLASS")"TYPE,                          FN_PTR(getType)},
+  {CC"getConfiguration",                  CC"()"CONFIG,                               FN_PTR(getConfiguration)},
+  {CC"installMethod",                     CC"("TARGET_METHOD"Z)"HS_COMP_METHOD,       FN_PTR(installMethod)},
+  {CC"installStub",                       CC"("TARGET_METHOD")"PROXY,                 FN_PTR(installStub)}
+};
+
+int CompilerToVM_methods_count() {
+  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
+}
+