src/share/vm/code/dependencies.cpp
Print this page
*** 28,37 ****
--- 28,38 ----
#include "ci/ciKlass.hpp"
#include "ci/ciMethod.hpp"
#include "code/dependencies.hpp"
#include "compiler/compileLog.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/objArrayKlass.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/copy.hpp"
*** 50,173 ****
_oop_recorder = env->oop_recorder();
_log = env->log();
_dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
DEBUG_ONLY(_deps[end_marker] = NULL);
for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
! _deps[i] = new(arena) GrowableArray<ciBaseObject*>(arena, 10, 0, 0);
}
_content_bytes = NULL;
_size_in_bytes = (size_t)-1;
assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT), "sanity");
}
! void Dependencies::assert_evol_method(ciMethod* m) {
! assert_common_1(evol_method, m);
}
! void Dependencies::assert_leaf_type(ciKlass* ctxk) {
! if (ctxk->is_array_klass()) {
// As a special case, support this assertion on an array type,
// which reduces to an assertion on its element type.
// Note that this cannot be done with assertions that
// relate to concreteness or abstractness.
! ciType* elemt = ctxk->as_array_klass()->base_element_type();
! if (!elemt->is_instance_klass()) return; // Ex: int[][]
! ctxk = elemt->as_instance_klass();
//if (ctxk->is_final()) return; // Ex: String[][]
}
check_ctxk(ctxk);
! assert_common_1(leaf_type, ctxk);
}
! void Dependencies::assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck) {
check_ctxk_abstract(ctxk);
! assert_common_2(abstract_with_unique_concrete_subtype, ctxk, conck);
}
! void Dependencies::assert_abstract_with_no_concrete_subtype(ciKlass* ctxk) {
check_ctxk_abstract(ctxk);
! assert_common_1(abstract_with_no_concrete_subtype, ctxk);
}
! void Dependencies::assert_concrete_with_no_concrete_subtype(ciKlass* ctxk) {
check_ctxk_concrete(ctxk);
! assert_common_1(concrete_with_no_concrete_subtype, ctxk);
}
! void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm) {
check_ctxk(ctxk);
! assert_common_2(unique_concrete_method, ctxk, uniqm);
}
! void Dependencies::assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2) {
check_ctxk(ctxk);
! assert_common_3(abstract_with_exclusive_concrete_subtypes_2, ctxk, k1, k2);
}
! void Dependencies::assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2) {
check_ctxk(ctxk);
! assert_common_3(exclusive_concrete_methods_2, ctxk, m1, m2);
}
! void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
check_ctxk(ctxk);
! assert_common_1(no_finalizable_subclasses, ctxk);
}
! void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
! check_ctxk(call_site->klass());
! assert_common_2(call_site_target_value, call_site, method_handle);
}
// Helper function. If we are adding a new dep. under ctxk2,
// try to find an old dep. under a broader* ctxk1. If there is
//
! bool Dependencies::maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps,
! int ctxk_i, ciKlass* ctxk2) {
! ciKlass* ctxk1 = deps->at(ctxk_i)->as_metadata()->as_klass();
if (ctxk2->is_subtype_of(ctxk1)) {
return true; // success, and no need to change
} else if (ctxk1->is_subtype_of(ctxk2)) {
// new context class fully subsumes previous one
! deps->at_put(ctxk_i, ctxk2);
return true;
} else {
return false;
}
}
! void Dependencies::assert_common_1(DepType dept, ciBaseObject* x) {
assert(dep_args(dept) == 1, "sanity");
log_dependency(dept, x);
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
// see if the same (or a similar) dep is already recorded
if (note_dep_seen(dept, x)) {
assert(deps->find(x) >= 0, "sanity");
} else {
deps->append(x);
}
}
void Dependencies::assert_common_2(DepType dept,
! ciBaseObject* x0, ciBaseObject* x1) {
assert(dep_args(dept) == 2, "sanity");
log_dependency(dept, x0, x1);
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
// see if the same (or a similar) dep is already recorded
bool has_ctxk = has_explicit_context_arg(dept);
if (has_ctxk) {
assert(dep_context_arg(dept) == 0, "sanity");
if (note_dep_seen(dept, x1)) {
// look in this bucket for redundant assertions
const int stride = 2;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! ciBaseObject* y1 = deps->at(i+1);
if (x1 == y1) { // same subject; check the context
! if (maybe_merge_ctxk(deps, i+0, x0->as_metadata()->as_klass())) {
return;
}
}
}
}
--- 51,178 ----
_oop_recorder = env->oop_recorder();
_log = env->log();
_dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
DEBUG_ONLY(_deps[end_marker] = NULL);
for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
! _deps[i] = new(arena) GrowableArray<DepValue>(arena, 10, 0, DepValue());
}
_content_bytes = NULL;
_size_in_bytes = (size_t)-1;
assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT), "sanity");
}
! void Dependencies::assert_evol_method(Method* m) {
! assert_common_1(evol_method, DepValue(_oop_recorder, m));
}
! void Dependencies::assert_leaf_type(Klass* ctxk) {
! if (ctxk->oop_is_array()) {
// As a special case, support this assertion on an array type,
// which reduces to an assertion on its element type.
// Note that this cannot be done with assertions that
// relate to concreteness or abstractness.
! BasicType elemt = ArrayKlass::cast(ctxk)->element_type();
! if (is_java_primitive(elemt)) return; // Ex: int[][]
! ctxk = ObjArrayKlass::cast(ctxk)->bottom_klass();
//if (ctxk->is_final()) return; // Ex: String[][]
}
check_ctxk(ctxk);
! assert_common_1(leaf_type, DepValue(_oop_recorder, ctxk));
}
! void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck) {
check_ctxk_abstract(ctxk);
! DepValue ctxk_dv(_oop_recorder, ctxk);
! assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, DepValue(_oop_recorder, conck, &ctxk_dv));
}
! void Dependencies::assert_abstract_with_no_concrete_subtype(Klass* ctxk) {
check_ctxk_abstract(ctxk);
! assert_common_1(abstract_with_no_concrete_subtype, DepValue(_oop_recorder, ctxk));
}
! void Dependencies::assert_concrete_with_no_concrete_subtype(Klass* ctxk) {
check_ctxk_concrete(ctxk);
! assert_common_1(concrete_with_no_concrete_subtype, DepValue(_oop_recorder, ctxk));
}
! void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
check_ctxk(ctxk);
! assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
}
! void Dependencies::assert_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2) {
check_ctxk(ctxk);
! DepValue k1_dv(_oop_recorder, k1);
! assert_common_3(abstract_with_exclusive_concrete_subtypes_2, ctxk, k1_dv, DepValue(_oop_recorder, k2, &k1_dv));
}
! void Dependencies::assert_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2) {
check_ctxk(ctxk);
! DepValue m1_dv(_oop_recorder, m1);
! assert_common_3(exclusive_concrete_methods_2, ctxk, m1_dv, DepValue(_oop_recorder, m2, &m1_dv));
}
! void Dependencies::assert_has_no_finalizable_subclasses(Klass* ctxk) {
check_ctxk(ctxk);
! assert_common_1(no_finalizable_subclasses, DepValue(_oop_recorder, ctxk));
}
! void Dependencies::assert_call_site_target_value(jobject call_site, jobject method_handle) {
! Klass* ctxk = JNIHandles::resolve(call_site)->klass();
! check_ctxk(ctxk);
! assert_common_2(call_site_target_value, DepValue(_oop_recorder, call_site), DepValue(_oop_recorder, method_handle));
}
// Helper function. If we are adding a new dep. under ctxk2,
// try to find an old dep. under a broader* ctxk1. If there is
//
! bool Dependencies::maybe_merge_ctxk(GrowableArray<DepValue>* deps,
! int ctxk_i, Klass* ctxk2) {
! Klass* ctxk1 = deps->at(ctxk_i).as_klass(_oop_recorder);
if (ctxk2->is_subtype_of(ctxk1)) {
return true; // success, and no need to change
} else if (ctxk1->is_subtype_of(ctxk2)) {
// new context class fully subsumes previous one
! deps->at_put(ctxk_i, DepValue(_oop_recorder, ctxk2));
return true;
} else {
return false;
}
}
! void Dependencies::assert_common_1(DepType dept, DepValue x) {
assert(dep_args(dept) == 1, "sanity");
log_dependency(dept, x);
! GrowableArray<DepValue>* deps = _deps[dept];
// see if the same (or a similar) dep is already recorded
if (note_dep_seen(dept, x)) {
assert(deps->find(x) >= 0, "sanity");
} else {
deps->append(x);
}
}
void Dependencies::assert_common_2(DepType dept,
! DepValue x0, DepValue x1) {
assert(dep_args(dept) == 2, "sanity");
log_dependency(dept, x0, x1);
! GrowableArray<DepValue>* deps = _deps[dept];
// see if the same (or a similar) dep is already recorded
bool has_ctxk = has_explicit_context_arg(dept);
if (has_ctxk) {
assert(dep_context_arg(dept) == 0, "sanity");
if (note_dep_seen(dept, x1)) {
// look in this bucket for redundant assertions
const int stride = 2;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! DepValue y1 = deps->at(i+1);
if (x1 == y1) { // same subject; check the context
! if (maybe_merge_ctxk(deps, i+0, x0.as_klass(_oop_recorder))) {
return;
}
}
}
}
*** 175,186 ****
assert(dep_implicit_context_arg(dept) == 0, "sanity");
if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
// look in this bucket for redundant assertions
const int stride = 2;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! ciBaseObject* y0 = deps->at(i+0);
! ciBaseObject* y1 = deps->at(i+1);
if (x0 == y0 && x1 == y1) {
return;
}
}
}
--- 180,191 ----
assert(dep_implicit_context_arg(dept) == 0, "sanity");
if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
// look in this bucket for redundant assertions
const int stride = 2;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! DepValue y0 = deps->at(i+0);
! DepValue y1 = deps->at(i+1);
if (x0 == y0 && x1 == y1) {
return;
}
}
}
*** 190,233 ****
deps->append(x0);
deps->append(x1);
}
void Dependencies::assert_common_3(DepType dept,
! ciKlass* ctxk, ciBaseObject* x, ciBaseObject* x2) {
assert(dep_context_arg(dept) == 0, "sanity");
assert(dep_args(dept) == 3, "sanity");
! log_dependency(dept, ctxk, x, x2);
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
// try to normalize an unordered pair:
bool swap = false;
switch (dept) {
case abstract_with_exclusive_concrete_subtypes_2:
! swap = (x->ident() > x2->ident() && x->as_metadata()->as_klass() != ctxk);
break;
case exclusive_concrete_methods_2:
! swap = (x->ident() > x2->ident() && x->as_metadata()->as_method()->holder() != ctxk);
break;
}
! if (swap) { ciBaseObject* t = x; x = x2; x2 = t; }
// see if the same (or a similar) dep is already recorded
if (note_dep_seen(dept, x) && note_dep_seen(dept, x2)) {
// look in this bucket for redundant assertions
const int stride = 3;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! ciBaseObject* y = deps->at(i+1);
! ciBaseObject* y2 = deps->at(i+2);
if (x == y && x2 == y2) { // same subjects; check the context
if (maybe_merge_ctxk(deps, i+0, ctxk)) {
return;
}
}
}
}
// append the assertion in the correct bucket:
! deps->append(ctxk);
deps->append(x);
deps->append(x2);
}
/// Support for encoding dependencies into an nmethod:
--- 195,238 ----
deps->append(x0);
deps->append(x1);
}
void Dependencies::assert_common_3(DepType dept,
! Klass* ctxk, DepValue x, DepValue x2) {
assert(dep_context_arg(dept) == 0, "sanity");
assert(dep_args(dept) == 3, "sanity");
! log_dependency(dept, DepValue(_oop_recorder, ctxk), x, x2);
! GrowableArray<DepValue>* deps = _deps[dept];
// try to normalize an unordered pair:
bool swap = false;
switch (dept) {
case abstract_with_exclusive_concrete_subtypes_2:
! swap = (x.index() > x2.index() && x.as_klass(_oop_recorder) != ctxk);
break;
case exclusive_concrete_methods_2:
! swap = (x.index() > x2.index() && x.as_method(_oop_recorder)->method_holder() != ctxk);
break;
}
! if (swap) { DepValue t = x; x = x2; x2 = t; }
// see if the same (or a similar) dep is already recorded
if (note_dep_seen(dept, x) && note_dep_seen(dept, x2)) {
// look in this bucket for redundant assertions
const int stride = 3;
for (int i = deps->length(); (i -= stride) >= 0; ) {
! DepValue y = deps->at(i+1);
! DepValue y2 = deps->at(i+2);
if (x == y && x2 == y2) { // same subjects; check the context
if (maybe_merge_ctxk(deps, i+0, ctxk)) {
return;
}
}
}
}
// append the assertion in the correct bucket:
! deps->append(DepValue(_oop_recorder, ctxk));
deps->append(x);
deps->append(x2);
}
/// Support for encoding dependencies into an nmethod:
*** 240,267 ****
(HeapWord*) beg,
size_in_bytes() / sizeof(HeapWord));
assert(size_in_bytes() % sizeof(HeapWord) == 0, "copy by words");
}
! static int sort_dep(ciBaseObject** p1, ciBaseObject** p2, int narg) {
for (int i = 0; i < narg; i++) {
! int diff = p1[i]->ident() - p2[i]->ident();
if (diff != 0) return diff;
}
return 0;
}
! static int sort_dep_arg_1(ciBaseObject** p1, ciBaseObject** p2)
{ return sort_dep(p1, p2, 1); }
! static int sort_dep_arg_2(ciBaseObject** p1, ciBaseObject** p2)
{ return sort_dep(p1, p2, 2); }
! static int sort_dep_arg_3(ciBaseObject** p1, ciBaseObject** p2)
{ return sort_dep(p1, p2, 3); }
void Dependencies::sort_all_deps() {
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
if (deps->length() <= 1) continue;
switch (dep_args(dept)) {
case 1: deps->sort(sort_dep_arg_1, 1); break;
case 2: deps->sort(sort_dep_arg_2, 2); break;
case 3: deps->sort(sort_dep_arg_3, 3); break;
--- 245,272 ----
(HeapWord*) beg,
size_in_bytes() / sizeof(HeapWord));
assert(size_in_bytes() % sizeof(HeapWord) == 0, "copy by words");
}
! static int sort_dep(Dependencies::DepValue* p1, Dependencies::DepValue* p2, int narg) {
for (int i = 0; i < narg; i++) {
! int diff = p1[i].sort_key() - p2[i].sort_key();
if (diff != 0) return diff;
}
return 0;
}
! static int sort_dep_arg_1(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
{ return sort_dep(p1, p2, 1); }
! static int sort_dep_arg_2(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
{ return sort_dep(p1, p2, 2); }
! static int sort_dep_arg_3(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
{ return sort_dep(p1, p2, 3); }
void Dependencies::sort_all_deps() {
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<DepValue>* deps = _deps[dept];
if (deps->length() <= 1) continue;
switch (dep_args(dept)) {
case 1: deps->sort(sort_dep_arg_1, 1); break;
case 2: deps->sort(sort_dep_arg_2, 2); break;
case 3: deps->sort(sort_dep_arg_3, 3); break;
*** 272,294 ****
size_t Dependencies::estimate_size_in_bytes() {
size_t est_size = 100;
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
est_size += deps->length()*2; // tags and argument(s)
}
return est_size;
}
! ciKlass* Dependencies::ctxk_encoded_as_null(DepType dept, ciBaseObject* x) {
switch (dept) {
case abstract_with_exclusive_concrete_subtypes_2:
! return x->as_metadata()->as_klass();
case unique_concrete_method:
case exclusive_concrete_methods_2:
! return x->as_metadata()->as_method()->holder();
}
return NULL; // let NULL be NULL
}
Klass* Dependencies::ctxk_encoded_as_null(DepType dept, Metadata* x) {
--- 277,299 ----
size_t Dependencies::estimate_size_in_bytes() {
size_t est_size = 100;
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<DepValue>* deps = _deps[dept];
est_size += deps->length()*2; // tags and argument(s)
}
return est_size;
}
! Klass* Dependencies::ctxk_encoded_as_null(OopRecorder* oop_recorder, DepType dept, DepValue x) {
switch (dept) {
case abstract_with_exclusive_concrete_subtypes_2:
! return x.as_klass(oop_recorder);
case unique_concrete_method:
case exclusive_concrete_methods_2:
! return x.as_method(oop_recorder)->method_holder();
}
return NULL; // let NULL be NULL
}
Klass* Dependencies::ctxk_encoded_as_null(DepType dept, Metadata* x) {
*** 311,347 ****
// cast is safe, no deps can overflow INT_MAX
CompressedWriteStream bytes((int)estimate_size_in_bytes());
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
if (deps->length() == 0) continue;
int stride = dep_args(dept);
int ctxkj = dep_context_arg(dept); // -1 if no context arg
assert(stride > 0, "sanity");
for (int i = 0; i < deps->length(); i += stride) {
jbyte code_byte = (jbyte)dept;
int skipj = -1;
if (ctxkj >= 0 && ctxkj+1 < stride) {
! ciKlass* ctxk = deps->at(i+ctxkj+0)->as_metadata()->as_klass();
! ciBaseObject* x = deps->at(i+ctxkj+1); // following argument
! if (ctxk == ctxk_encoded_as_null(dept, x)) {
skipj = ctxkj; // we win: maybe one less oop to keep track of
code_byte |= default_context_type_bit;
}
}
bytes.write_byte(code_byte);
for (int j = 0; j < stride; j++) {
if (j == skipj) continue;
! ciBaseObject* v = deps->at(i+j);
! int idx;
! if (v->is_object()) {
! idx = _oop_recorder->find_index(v->as_object()->constant_encoding());
! } else {
! ciMetadata* meta = v->as_metadata();
! idx = _oop_recorder->find_index(meta->constant_encoding());
! }
bytes.write_int(idx);
}
}
}
--- 316,346 ----
// cast is safe, no deps can overflow INT_MAX
CompressedWriteStream bytes((int)estimate_size_in_bytes());
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<DepValue>* deps = _deps[dept];
if (deps->length() == 0) continue;
int stride = dep_args(dept);
int ctxkj = dep_context_arg(dept); // -1 if no context arg
assert(stride > 0, "sanity");
for (int i = 0; i < deps->length(); i += stride) {
jbyte code_byte = (jbyte)dept;
int skipj = -1;
if (ctxkj >= 0 && ctxkj+1 < stride) {
! Klass* ctxk = deps->at(i+ctxkj+0).as_klass(_oop_recorder);
! DepValue x = deps->at(i+ctxkj+1); // following argument
! if (ctxk == ctxk_encoded_as_null(_oop_recorder, dept, x)) {
skipj = ctxkj; // we win: maybe one less oop to keep track of
code_byte |= default_context_type_bit;
}
}
bytes.write_byte(code_byte);
for (int j = 0; j < stride; j++) {
if (j == skipj) continue;
! DepValue v = deps->at(i+j);
! int idx = v.index();
bytes.write_int(idx);
}
}
}
*** 404,417 ****
}
// for the sake of the compiler log, print out current dependencies:
void Dependencies::log_all_dependencies() {
if (log() == NULL) return;
! ciBaseObject* args[max_arg_count];
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<ciBaseObject*>* deps = _deps[dept];
if (deps->length() == 0) continue;
int stride = dep_args(dept);
for (int i = 0; i < deps->length(); i += stride) {
for (int j = 0; j < stride; j++) {
// flush out the identities before printing
--- 403,416 ----
}
// for the sake of the compiler log, print out current dependencies:
void Dependencies::log_all_dependencies() {
if (log() == NULL) return;
! DepValue args[max_arg_count];
for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
DepType dept = (DepType)deptv;
! GrowableArray<DepValue>* deps = _deps[dept];
if (deps->length() == 0) continue;
int stride = dep_args(dept);
for (int i = 0; i < deps->length(); i += stride) {
for (int j = 0; j < stride; j++) {
// flush out the identities before printing
*** 422,431 ****
--- 421,450 ----
}
}
void Dependencies::write_dependency_to(CompileLog* log,
DepType dept,
+ int nargs, DepValue args[],
+ Klass* witness) {
+ if (log == NULL) {
+ return;
+ }
+ ciEnv* env = ciEnv::current();
+ ciBaseObject* ciargs[max_arg_count];
+ assert(nargs <= max_arg_count, "oob");
+ for (int j = 0; j < nargs; j++) {
+ if (args[j].is_object()) {
+ ciargs[j] = env->get_object(JNIHandles::resolve(args[j].as_object(_oop_recorder)));
+ } else {
+ ciargs[j] = env->get_metadata(args[j].as_metadata(_oop_recorder));
+ }
+ }
+ Dependencies::write_dependency_to(log, dept, nargs, ciargs, witness);
+ }
+
+ void Dependencies::write_dependency_to(CompileLog* log,
+ DepType dept,
int nargs, DepArgument args[],
Klass* witness) {
if (log == NULL) {
return;
}