< prev index next >

src/hotspot/share/code/dependencies.cpp

Print this page

        

*** 28,37 **** --- 28,39 ---- #include "ci/ciKlass.hpp" #include "ci/ciMethod.hpp" #include "classfile/javaClasses.inline.hpp" #include "code/dependencies.hpp" #include "compiler/compileLog.hpp" + #include "compiler/compileBroker.hpp" + #include "compiler/compileTask.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "oops/objArrayKlass.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp"
*** 618,627 **** --- 620,695 ---- void Dependencies::check_valid_dependency_type(DepType dept) { guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, "invalid dependency type: %d", (int) dept); } + Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail) { + // First, check non-klass dependencies as we might return early and + // not check klass dependencies if the system dictionary + // modification counter hasn't changed (see below). + for (Dependencies::DepStream deps(this); deps.next(); ) { + if (deps.is_klass_type()) continue; // skip klass dependencies + Klass* witness = deps.check_dependency(); + if (witness != NULL) { + return deps.type(); + } + } + + // Klass dependencies must be checked when the system dictionary + // changes. If logging is enabled all violated dependences will be + // recorded in the log. In debug mode check dependencies even if + // the system dictionary hasn't changed to verify that no invalid + // dependencies were inserted. Any violated dependences in this + // case are dumped to the tty. + if (!counter_changed && !trueInDebug) { + return end_marker; + } + + int klass_violations = 0; + DepType result = end_marker; + for (Dependencies::DepStream deps(this); deps.next(); ) { + if (!deps.is_klass_type()) continue; // skip non-klass dependencies + Klass* witness = deps.check_dependency(); + if (witness != NULL) { + if (klass_violations == 0) { + result = deps.type(); + if (failure_detail != NULL && klass_violations == 0) { + // Use a fixed size buffer to prevent the string stream from + // resizing in the context of an inner resource mark. + char* buffer = NEW_RESOURCE_ARRAY(char, O_BUFLEN); + stringStream st(buffer, O_BUFLEN); + deps.print_dependency(witness, true, &st); + *failure_detail = st.as_string(); + } + } + klass_violations++; + if (!counter_changed) { + // Dependence failed but counter didn't change. Log a message + // describing what failed and allow the assert at the end to + // trigger. + deps.print_dependency(witness); + } else if (xtty == NULL) { + // If we're not logging then a single violation is sufficient, + // otherwise we want to log all the dependences which were + // violated. + break; + } + } + } + + if (klass_violations != 0) { + #ifdef ASSERT + if (task != NULL && !counter_changed && !PrintCompilation) { + // Print out the compile task that failed + task->print_tty(); + } + #endif + assert(counter_changed, "failed dependencies, but counter didn't change"); + } + return result; + } + // for the sake of the compiler log, print out current dependencies: void Dependencies::log_all_dependencies() { if (log() == NULL) return; ResourceMark rm; for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
< prev index next >