Mercurial > hg > truffle
comparison src/share/vm/code/dependencies.cpp @ 3894:b27c72d69fd1
7083184: JSR 292: don't store context class argument with call site dependencies
Reviewed-by: jrose, never
author | twisti |
---|---|
date | Mon, 29 Aug 2011 05:07:35 -0700 |
parents | fdb992d83a87 |
children | c9a03402fe56 75c0a73eee98 |
comparison
equal
deleted
inserted
replaced
3893:8805f8c1e23e | 3894:b27c72d69fd1 |
---|---|
111 void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) { | 111 void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) { |
112 check_ctxk(ctxk); | 112 check_ctxk(ctxk); |
113 assert_common_1(no_finalizable_subclasses, ctxk); | 113 assert_common_1(no_finalizable_subclasses, ctxk); |
114 } | 114 } |
115 | 115 |
116 void Dependencies::assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle) { | 116 void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) { |
117 check_ctxk(ctxk); | 117 check_ctxk(call_site->klass()); |
118 assert_common_3(call_site_target_value, ctxk, call_site, method_handle); | 118 assert_common_2(call_site_target_value, call_site, method_handle); |
119 } | 119 } |
120 | 120 |
121 // Helper function. If we are adding a new dep. under ctxk2, | 121 // Helper function. If we are adding a new dep. under ctxk2, |
122 // try to find an old dep. under a broader* ctxk1. If there is | 122 // try to find an old dep. under a broader* ctxk1. If there is |
123 // | 123 // |
133 } else { | 133 } else { |
134 return false; | 134 return false; |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 void Dependencies::assert_common_1(Dependencies::DepType dept, ciObject* x) { | 138 void Dependencies::assert_common_1(DepType dept, ciObject* x) { |
139 assert(dep_args(dept) == 1, "sanity"); | 139 assert(dep_args(dept) == 1, "sanity"); |
140 log_dependency(dept, x); | 140 log_dependency(dept, x); |
141 GrowableArray<ciObject*>* deps = _deps[dept]; | 141 GrowableArray<ciObject*>* deps = _deps[dept]; |
142 | 142 |
143 // see if the same (or a similar) dep is already recorded | 143 // see if the same (or a similar) dep is already recorded |
146 } else { | 146 } else { |
147 deps->append(x); | 147 deps->append(x); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 void Dependencies::assert_common_2(Dependencies::DepType dept, | 151 void Dependencies::assert_common_2(DepType dept, |
152 ciKlass* ctxk, ciObject* x) { | 152 ciObject* x0, ciObject* x1) { |
153 assert(dep_context_arg(dept) == 0, "sanity"); | |
154 assert(dep_args(dept) == 2, "sanity"); | 153 assert(dep_args(dept) == 2, "sanity"); |
155 log_dependency(dept, ctxk, x); | 154 log_dependency(dept, x0, x1); |
156 GrowableArray<ciObject*>* deps = _deps[dept]; | 155 GrowableArray<ciObject*>* deps = _deps[dept]; |
157 | 156 |
158 // see if the same (or a similar) dep is already recorded | 157 // see if the same (or a similar) dep is already recorded |
159 if (note_dep_seen(dept, x)) { | 158 bool has_ctxk = has_explicit_context_arg(dept); |
160 // look in this bucket for redundant assertions | 159 if (has_ctxk) { |
161 const int stride = 2; | 160 assert(dep_context_arg(dept) == 0, "sanity"); |
162 for (int i = deps->length(); (i -= stride) >= 0; ) { | 161 if (note_dep_seen(dept, x1)) { |
163 ciObject* x1 = deps->at(i+1); | 162 // look in this bucket for redundant assertions |
164 if (x == x1) { // same subject; check the context | 163 const int stride = 2; |
165 if (maybe_merge_ctxk(deps, i+0, ctxk)) { | 164 for (int i = deps->length(); (i -= stride) >= 0; ) { |
165 ciObject* y1 = deps->at(i+1); | |
166 if (x1 == y1) { // same subject; check the context | |
167 if (maybe_merge_ctxk(deps, i+0, x0->as_klass())) { | |
168 return; | |
169 } | |
170 } | |
171 } | |
172 } | |
173 } else { | |
174 assert(dep_implicit_context_arg(dept) == 0, "sanity"); | |
175 if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) { | |
176 // look in this bucket for redundant assertions | |
177 const int stride = 2; | |
178 for (int i = deps->length(); (i -= stride) >= 0; ) { | |
179 ciObject* y0 = deps->at(i+0); | |
180 ciObject* y1 = deps->at(i+1); | |
181 if (x0 == y0 && x1 == y1) { | |
166 return; | 182 return; |
167 } | 183 } |
168 } | 184 } |
169 } | 185 } |
170 } | 186 } |
171 | 187 |
172 // append the assertion in the correct bucket: | 188 // append the assertion in the correct bucket: |
173 deps->append(ctxk); | 189 deps->append(x0); |
174 deps->append(x); | 190 deps->append(x1); |
175 } | 191 } |
176 | 192 |
177 void Dependencies::assert_common_3(Dependencies::DepType dept, | 193 void Dependencies::assert_common_3(DepType dept, |
178 ciKlass* ctxk, ciObject* x, ciObject* x2) { | 194 ciKlass* ctxk, ciObject* x, ciObject* x2) { |
179 assert(dep_context_arg(dept) == 0, "sanity"); | 195 assert(dep_context_arg(dept) == 0, "sanity"); |
180 assert(dep_args(dept) == 3, "sanity"); | 196 assert(dep_args(dept) == 3, "sanity"); |
181 log_dependency(dept, ctxk, x, x2); | 197 log_dependency(dept, ctxk, x, x2); |
182 GrowableArray<ciObject*>* deps = _deps[dept]; | 198 GrowableArray<ciObject*>* deps = _deps[dept]; |
359 1, // concrete_with_no_concrete_subtype ctxk | 375 1, // concrete_with_no_concrete_subtype ctxk |
360 2, // unique_concrete_method ctxk, m | 376 2, // unique_concrete_method ctxk, m |
361 3, // unique_concrete_subtypes_2 ctxk, k1, k2 | 377 3, // unique_concrete_subtypes_2 ctxk, k1, k2 |
362 3, // unique_concrete_methods_2 ctxk, m1, m2 | 378 3, // unique_concrete_methods_2 ctxk, m1, m2 |
363 1, // no_finalizable_subclasses ctxk | 379 1, // no_finalizable_subclasses ctxk |
364 3 // call_site_target_value ctxk, call_site, method_handle | 380 2 // call_site_target_value call_site, method_handle |
365 }; | 381 }; |
366 | 382 |
367 const char* Dependencies::dep_name(Dependencies::DepType dept) { | 383 const char* Dependencies::dep_name(Dependencies::DepType dept) { |
368 if (!dept_in_mask(dept, all_types)) return "?bad-dep?"; | 384 if (!dept_in_mask(dept, all_types)) return "?bad-dep?"; |
369 return _dep_name[dept]; | 385 return _dep_name[dept]; |
373 if (!dept_in_mask(dept, all_types)) return -1; | 389 if (!dept_in_mask(dept, all_types)) return -1; |
374 return _dep_args[dept]; | 390 return _dep_args[dept]; |
375 } | 391 } |
376 | 392 |
377 void Dependencies::check_valid_dependency_type(DepType dept) { | 393 void Dependencies::check_valid_dependency_type(DepType dept) { |
378 for (int deptv = (int) FIRST_TYPE; deptv < (int) TYPE_LIMIT; deptv++) { | 394 guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, err_msg("invalid dependency type: %d", (int) dept)); |
379 if (dept == ((DepType) deptv)) return; | |
380 } | |
381 ShouldNotReachHere(); | |
382 } | 395 } |
383 | 396 |
384 // for the sake of the compiler log, print out current dependencies: | 397 // for the sake of the compiler log, print out current dependencies: |
385 void Dependencies::log_all_dependencies() { | 398 void Dependencies::log_all_dependencies() { |
386 if (log() == NULL) return; | 399 if (log() == NULL) return; |
584 } else { | 597 } else { |
585 int ctxk_bit = (code_byte & Dependencies::default_context_type_bit); | 598 int ctxk_bit = (code_byte & Dependencies::default_context_type_bit); |
586 code_byte -= ctxk_bit; | 599 code_byte -= ctxk_bit; |
587 DepType dept = (DepType)code_byte; | 600 DepType dept = (DepType)code_byte; |
588 _type = dept; | 601 _type = dept; |
589 guarantee((dept - FIRST_TYPE) < (TYPE_LIMIT - FIRST_TYPE), | 602 Dependencies::check_valid_dependency_type(dept); |
590 "bad dependency type tag"); | |
591 int stride = _dep_args[dept]; | 603 int stride = _dep_args[dept]; |
592 assert(stride == dep_args(dept), "sanity"); | 604 assert(stride == dep_args(dept), "sanity"); |
593 int skipj = -1; | 605 int skipj = -1; |
594 if (ctxk_bit != 0) { | 606 if (ctxk_bit != 0) { |
595 skipj = 0; // currently the only context argument is at zero | 607 skipj = 0; // currently the only context argument is at zero |
613 return recorded_oop_at(argument_index(i)); | 625 return recorded_oop_at(argument_index(i)); |
614 } | 626 } |
615 | 627 |
616 klassOop Dependencies::DepStream::context_type() { | 628 klassOop Dependencies::DepStream::context_type() { |
617 assert(must_be_in_vm(), "raw oops here"); | 629 assert(must_be_in_vm(), "raw oops here"); |
618 int ctxkj = dep_context_arg(_type); // -1 if no context arg | 630 |
619 if (ctxkj < 0) { | 631 // Most dependencies have an explicit context type argument. |
620 return NULL; // for example, evol_method | 632 { |
621 } else { | 633 int ctxkj = dep_context_arg(_type); // -1 if no explicit context arg |
622 oop k = recorded_oop_at(_xi[ctxkj]); | 634 if (ctxkj >= 0) { |
623 if (k != NULL) { // context type was not compressed away | 635 oop k = argument(ctxkj); |
636 if (k != NULL) { // context type was not compressed away | |
637 assert(k->is_klass(), "type check"); | |
638 return (klassOop) k; | |
639 } | |
640 // recompute "default" context type | |
641 return ctxk_encoded_as_null(_type, argument(ctxkj+1)); | |
642 } | |
643 } | |
644 | |
645 // Some dependencies are using the klass of the first object | |
646 // argument as implicit context type (e.g. call_site_target_value). | |
647 { | |
648 int ctxkj = dep_implicit_context_arg(_type); | |
649 if (ctxkj >= 0) { | |
650 oop k = argument(ctxkj)->klass(); | |
624 assert(k->is_klass(), "type check"); | 651 assert(k->is_klass(), "type check"); |
625 return (klassOop) k; | 652 return (klassOop) k; |
626 } else { // recompute "default" context type | 653 } |
627 return ctxk_encoded_as_null(_type, recorded_oop_at(_xi[ctxkj+1])); | 654 } |
628 } | 655 |
629 } | 656 // And some dependencies don't have a context type at all, |
657 // e.g. evol_method. | |
658 return NULL; | |
630 } | 659 } |
631 | 660 |
632 /// Checking dependencies: | 661 /// Checking dependencies: |
633 | 662 |
634 // This hierarchy walker inspects subtypes of a given type, | 663 // This hierarchy walker inspects subtypes of a given type, |
1407 } | 1436 } |
1408 return result->as_klassOop(); | 1437 return result->as_klassOop(); |
1409 } | 1438 } |
1410 | 1439 |
1411 | 1440 |
1412 klassOop Dependencies::check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) { | 1441 klassOop Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) { |
1413 assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity"); | 1442 assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity"); |
1414 assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity"); | 1443 assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity"); |
1415 if (changes == NULL) { | 1444 if (changes == NULL) { |
1416 // Validate all CallSites | 1445 // Validate all CallSites |
1417 if (java_lang_invoke_CallSite::target(call_site) != method_handle) | 1446 if (java_lang_invoke_CallSite::target(call_site) != method_handle) |
1418 return ctxk; // assertion failed | 1447 return call_site->klass(); // assertion failed |
1419 } else { | 1448 } else { |
1420 // Validate the given CallSite | 1449 // Validate the given CallSite |
1421 if (call_site == changes->call_site() && java_lang_invoke_CallSite::target(call_site) != changes->method_handle()) { | 1450 if (call_site == changes->call_site() && java_lang_invoke_CallSite::target(call_site) != changes->method_handle()) { |
1422 assert(method_handle != changes->method_handle(), "must be"); | 1451 assert(method_handle != changes->method_handle(), "must be"); |
1423 return ctxk; // assertion failed | 1452 return call_site->klass(); // assertion failed |
1424 } | 1453 } |
1425 } | 1454 } |
1426 assert(java_lang_invoke_CallSite::target(call_site) == method_handle, "should still be valid"); | |
1427 return NULL; // assertion still valid | 1455 return NULL; // assertion still valid |
1428 } | 1456 } |
1429 | 1457 |
1430 | 1458 |
1431 void Dependencies::DepStream::trace_and_log_witness(klassOop witness) { | 1459 void Dependencies::DepStream::trace_and_log_witness(klassOop witness) { |
1486 Dependencies::check_valid_dependency_type(type()); | 1514 Dependencies::check_valid_dependency_type(type()); |
1487 | 1515 |
1488 klassOop witness = NULL; | 1516 klassOop witness = NULL; |
1489 switch (type()) { | 1517 switch (type()) { |
1490 case call_site_target_value: | 1518 case call_site_target_value: |
1491 witness = check_call_site_target_value(context_type(), argument(1), argument(2), changes); | 1519 witness = check_call_site_target_value(argument(0), argument(1), changes); |
1492 break; | 1520 break; |
1493 default: | 1521 default: |
1494 witness = NULL; | 1522 witness = NULL; |
1495 break; | 1523 break; |
1496 } | 1524 } |