< 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 >