# HG changeset patch # User Doug Simon # Date 1354131583 -3600 # Node ID af30115c9d0eb02e402280cb8882d6452df1cf20 # Parent 97d0eae99568c1ff8544ec713f0501d53b5c0932 added metering of code installation failure rate to detect excessive failure caused by overly optimistic assumptions diff -r 97d0eae99568 -r af30115c9d0e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Nov 28 19:18:39 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Nov 28 20:39:43 2012 +0100 @@ -134,7 +134,8 @@ * @param code if not null, then the code is installed as the non-default compiled code for the associated method * and the details of the installation are written to this object * @param info additional information about the installation are written to this object if it is not null - * @return the value of {@code code} if installation was successful, null otherwise + * @return the value of {@code code} if installation was successful, null if dependency validation failed or the + * code cache is full */ HotSpotInstalledCode installCode(HotSpotCompilationResult compResult, HotSpotInstalledCode code, HotSpotCodeInfo info); diff -r 97d0eae99568 -r af30115c9d0e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Nov 28 19:18:39 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Nov 28 20:39:43 2012 +0100 @@ -23,6 +23,8 @@ package com.oracle.graal.hotspot.bridge; +import static com.oracle.graal.hotspot.bridge.CompilerToVMImpl.CodeInstallResult.*; + import java.lang.reflect.*; import com.oracle.graal.api.meta.*; @@ -34,6 +36,42 @@ */ public class CompilerToVMImpl implements CompilerToVM { + // Must be kept in sync with enum in graalEnv.hpp + enum CodeInstallResult { + OK, + DEPENDENCIES_FAILED, + CACHE_FULL + } + + /** + * Number of successive successful installations. + */ + private long successfulInstallations; + + /** + * The minimum expected number of successful code installations between each code + * installation failure. Warning messages are printed when the failure rate goes + * above this threshold. This usually indicates use of some overly optimistic + * assumptions during compilation. + */ + private static final int MINIMUM_SUCCESSFUL_INSTALLATIONS_PER_FAILURE = 2000; + + private native int installCode0(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info); + + @Override + public HotSpotInstalledCode installCode(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info) { + int result = installCode0(comp, code, info); + if (result != OK.ordinal()) { + if (successfulInstallations < MINIMUM_SUCCESSFUL_INSTALLATIONS_PER_FAILURE) { + System.err.println("Failed to install compiled code for " + comp.method + " [reason: " + CodeInstallResult.values()[result] + "]"); + } + successfulInstallations = 0L; + } else { + successfulInstallations++; + } + return code; + } + @Override public native long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedObjectType[] resultHolder); @@ -83,9 +121,6 @@ public native JavaField lookupFieldInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); @Override - public native HotSpotInstalledCode installCode(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info); - - @Override public native void initializeConfiguration(HotSpotVMConfig config); @Override diff -r 97d0eae99568 -r af30115c9d0e src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 28 19:18:39 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 28 20:39:43 2012 +0100 @@ -23,12 +23,12 @@ #include "precompiled.hpp" #include "runtime/javaCalls.hpp" +#include "graal/graalEnv.hpp" #include "graal/graalCompiler.hpp" #include "graal/graalCodeInstaller.hpp" #include "graal/graalJavaAccess.hpp" #include "graal/graalCompilerToVM.hpp" #include "graal/graalVmIds.hpp" -#include "graal/graalEnv.hpp" #include "c1/c1_Runtime1.hpp" #include "classfile/vmSymbols.hpp" #include "vmreg_x86.inline.hpp" @@ -291,7 +291,7 @@ } // constructor used to create a method -CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, Handle installed_code) { +CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, nmethod*& nm, Handle installed_code) { _env = CURRENT_ENV; GraalCompiler::initialize_buffer_blob(); CodeBuffer buffer(JavaThread::current()->get_buffer_blob()); @@ -308,7 +308,7 @@ int stack_slots = _total_frame_size / HeapWordSize; // conversion to words - nm = GraalEnv::register_method(method, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, + result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, installed_code); method->clear_queued_for_compilation(); diff -r 97d0eae99568 -r af30115c9d0e src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Wed Nov 28 19:18:39 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Wed Nov 28 20:39:43 2012 +0100 @@ -85,7 +85,7 @@ public: // constructor used to create a method - CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, Handle installed_code); + CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, nmethod*& nm, Handle installed_code); // constructor used to create a stub CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id); diff -r 97d0eae99568 -r af30115c9d0e src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 28 19:18:39 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 28 20:39:43 2012 +0100 @@ -735,7 +735,7 @@ set_int(env, config, "arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset())); C2V_END -C2V_VMENTRY(jobject, installCode, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info)) +C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info)) ResourceMark rm; HandleMark hm; Handle compResultHandle = JNIHandles::resolve(compResult); @@ -744,29 +744,27 @@ Arena arena; ciEnv env(&arena); Handle installed_code_handle = JNIHandles::resolve(installed_code); - CodeInstaller installer(compResultHandle, method, nm, installed_code_handle); - - if (nm == NULL) { - // dependency (re)checking failed - return NULL; - } + GraalEnv::CodeInstallResult result; + CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle); - if (info != NULL) { - arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0); - memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size()); - HotSpotCodeInfo::set_code(info, codeCopy); - HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin()); - } + if (result != GraalEnv::ok) { + assert(nm == NULL, "should be"); + } else { + if (info != NULL) { + arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0); + memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size()); + HotSpotCodeInfo::set_code(info, codeCopy); + HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin()); + } - if (!installed_code_handle.is_null()) { - assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); - HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm); - HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult)); - assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable"); - return installed_code; - } else { - return NULL; + if (!installed_code_handle.is_null()) { + assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); + HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm); + HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult)); + assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable"); + } } + return result; C2V_END C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address)) @@ -952,7 +950,7 @@ {CC"getMetaspaceConstructor", CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceConstructor)}, {CC"getJavaField", CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD, FN_PTR(getJavaField)}, {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, - {CC"installCode", CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")"HS_INSTALLED_CODE, FN_PTR(installCode)}, + {CC"installCode0", CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I", FN_PTR(installCode0)}, {CC"disassembleNative", CC"([BJ)"STRING, FN_PTR(disassembleNative)}, {CC"executeCompiledMethod", CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, diff -r 97d0eae99568 -r af30115c9d0e src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Wed Nov 28 19:18:39 2012 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Wed Nov 28 20:39:43 2012 +0100 @@ -428,7 +428,9 @@ // ------------------------------------------------------------------ // ciEnv::register_method -nmethod* GraalEnv::register_method(methodHandle& method, +GraalEnv::CodeInstallResult GraalEnv::register_method( + methodHandle& method, + nmethod*& nm, int entry_bci, CodeOffsets* offsets, int orig_pc_offset, @@ -447,7 +449,7 @@ Handle installed_code) { EXCEPTION_CONTEXT; NMethodSweeper::possibly_sweep(); - nmethod* nm = NULL; + nm = NULL; int comp_level = CompLevel_simple; { // To prevent compile queue updates. @@ -472,7 +474,7 @@ // If the code buffer is created on each compile attempt // as in C2, then it must be freed. //code_buffer->free_blob(); - return NULL; + return GraalEnv::dependencies_failed; } nm = nmethod::new_nmethod(method, @@ -555,8 +557,9 @@ // JVMTI -- compiled method notification (must be done outside lock) if (nm != NULL) { nm->post_compiled_method_load_event(); + return GraalEnv::ok; } - return nm; + return GraalEnv::cache_full; } diff -r 97d0eae99568 -r af30115c9d0e src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Wed Nov 28 19:18:39 2012 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Wed Nov 28 20:39:43 2012 +0100 @@ -46,6 +46,13 @@ public: + // Must be kept in sync with the enum in the HotSpot implementation of CompilerToVM + enum CodeInstallResult { + ok, + dependencies_failed, + cache_full + }; + // Look up a klass by name from a particular class loader (the accessor's). // If require_local, result must be defined in that class loader, or NULL. // If !require_local, a result from remote class loader may be reported, @@ -109,7 +116,9 @@ public: // Register the result of a compilation. - static nmethod* register_method(methodHandle& target, + static GraalEnv::CodeInstallResult register_method( + methodHandle& target, + nmethod*& nm, int entry_bci, CodeOffsets* offsets, int orig_pc_offset,