Mercurial > hg > truffle
comparison src/share/vm/runtime/deoptimization.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | d8ce2825b193 c3e799c37717 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
32 #include "interpreter/interpreter.hpp" | 32 #include "interpreter/interpreter.hpp" |
33 #include "interpreter/oopMapCache.hpp" | 33 #include "interpreter/oopMapCache.hpp" |
34 #include "memory/allocation.inline.hpp" | 34 #include "memory/allocation.inline.hpp" |
35 #include "memory/oopFactory.hpp" | 35 #include "memory/oopFactory.hpp" |
36 #include "memory/resourceArea.hpp" | 36 #include "memory/resourceArea.hpp" |
37 #include "oops/methodOop.hpp" | 37 #include "oops/method.hpp" |
38 #include "oops/oop.inline.hpp" | 38 #include "oops/oop.inline.hpp" |
39 #include "prims/jvmtiThreadState.hpp" | 39 #include "prims/jvmtiThreadState.hpp" |
40 #include "runtime/biasedLocking.hpp" | 40 #include "runtime/biasedLocking.hpp" |
41 #include "runtime/compilationPolicy.hpp" | 41 #include "runtime/compilationPolicy.hpp" |
42 #include "runtime/deoptimization.hpp" | 42 #include "runtime/deoptimization.hpp" |
746 | 746 |
747 for (int i = 0; i < objects->length(); i++) { | 747 for (int i = 0; i < objects->length(); i++) { |
748 assert(objects->at(i)->is_object(), "invalid debug information"); | 748 assert(objects->at(i)->is_object(), "invalid debug information"); |
749 ObjectValue* sv = (ObjectValue*) objects->at(i); | 749 ObjectValue* sv = (ObjectValue*) objects->at(i); |
750 | 750 |
751 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | 751 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
752 oop obj = NULL; | 752 oop obj = NULL; |
753 | 753 |
754 if (k->oop_is_instance()) { | 754 if (k->oop_is_instance()) { |
755 instanceKlass* ik = instanceKlass::cast(k()); | 755 InstanceKlass* ik = InstanceKlass::cast(k()); |
756 obj = ik->allocate_instance(CHECK_(false)); | 756 obj = ik->allocate_instance(CHECK_(false)); |
757 } else if (k->oop_is_typeArray()) { | 757 } else if (k->oop_is_typeArray()) { |
758 typeArrayKlass* ak = typeArrayKlass::cast(k()); | 758 typeArrayKlass* ak = typeArrayKlass::cast(k()); |
759 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); | 759 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); |
760 int len = sv->field_size() / type2size[ak->element_type()]; | 760 int len = sv->field_size() / type2size[ak->element_type()]; |
780 // they are yielded by do_nonstatic_fields. | 780 // they are yielded by do_nonstatic_fields. |
781 class FieldReassigner: public FieldClosure { | 781 class FieldReassigner: public FieldClosure { |
782 frame* _fr; | 782 frame* _fr; |
783 RegisterMap* _reg_map; | 783 RegisterMap* _reg_map; |
784 ObjectValue* _sv; | 784 ObjectValue* _sv; |
785 instanceKlass* _ik; | 785 InstanceKlass* _ik; |
786 oop _obj; | 786 oop _obj; |
787 | 787 |
788 int _i; | 788 int _i; |
789 public: | 789 public: |
790 FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) : | 790 FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) : |
912 | 912 |
913 // restore fields of all eliminated objects and arrays | 913 // restore fields of all eliminated objects and arrays |
914 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) { | 914 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) { |
915 for (int i = 0; i < objects->length(); i++) { | 915 for (int i = 0; i < objects->length(); i++) { |
916 ObjectValue* sv = (ObjectValue*) objects->at(i); | 916 ObjectValue* sv = (ObjectValue*) objects->at(i); |
917 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | 917 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
918 Handle obj = sv->value(); | 918 Handle obj = sv->value(); |
919 assert(obj.not_null(), "reallocation was missed"); | 919 assert(obj.not_null(), "reallocation was missed"); |
920 | 920 |
921 if (k->oop_is_instance()) { | 921 if (k->oop_is_instance()) { |
922 instanceKlass* ik = instanceKlass::cast(k()); | 922 InstanceKlass* ik = InstanceKlass::cast(k()); |
923 FieldReassigner reassign(fr, reg_map, sv, obj()); | 923 FieldReassigner reassign(fr, reg_map, sv, obj()); |
924 ik->do_nonstatic_fields(&reassign); | 924 ik->do_nonstatic_fields(&reassign); |
925 } else if (k->oop_is_typeArray()) { | 925 } else if (k->oop_is_typeArray()) { |
926 typeArrayKlass* ak = typeArrayKlass::cast(k()); | 926 typeArrayKlass* ak = typeArrayKlass::cast(k()); |
927 reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); | 927 reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); |
963 void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) { | 963 void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) { |
964 fieldDescriptor fd; | 964 fieldDescriptor fd; |
965 | 965 |
966 for (int i = 0; i < objects->length(); i++) { | 966 for (int i = 0; i < objects->length(); i++) { |
967 ObjectValue* sv = (ObjectValue*) objects->at(i); | 967 ObjectValue* sv = (ObjectValue*) objects->at(i); |
968 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | 968 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
969 Handle obj = sv->value(); | 969 Handle obj = sv->value(); |
970 | 970 |
971 tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); | 971 tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); |
972 k->as_klassOop()->print_value(); | 972 k->print_value(); |
973 tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); | 973 tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); |
974 tty->cr(); | 974 tty->cr(); |
975 | 975 |
976 if (Verbose) { | 976 if (Verbose) { |
977 k->oop_print_on(obj(), tty); | 977 k->oop_print_on(obj(), tty); |
1180 | 1180 |
1181 #if defined(COMPILER2) || defined(SHARK) | 1181 #if defined(COMPILER2) || defined(SHARK) |
1182 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { | 1182 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { |
1183 // in case of an unresolved klass entry, load the class. | 1183 // in case of an unresolved klass entry, load the class. |
1184 if (constant_pool->tag_at(index).is_unresolved_klass()) { | 1184 if (constant_pool->tag_at(index).is_unresolved_klass()) { |
1185 klassOop tk = constant_pool->klass_at(index, CHECK); | 1185 Klass* tk = constant_pool->klass_at(index, CHECK); |
1186 return; | 1186 return; |
1187 } | 1187 } |
1188 | 1188 |
1189 if (!constant_pool->tag_at(index).is_symbol()) return; | 1189 if (!constant_pool->tag_at(index).is_symbol()) return; |
1190 | 1190 |
1191 Handle class_loader (THREAD, instanceKlass::cast(constant_pool->pool_holder())->class_loader()); | 1191 Handle class_loader (THREAD, InstanceKlass::cast(constant_pool->pool_holder())->class_loader()); |
1192 Symbol* symbol = constant_pool->symbol_at(index); | 1192 Symbol* symbol = constant_pool->symbol_at(index); |
1193 | 1193 |
1194 // class name? | 1194 // class name? |
1195 if (symbol->byte_at(0) != '(') { | 1195 if (symbol->byte_at(0) != '(') { |
1196 Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); | 1196 Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); |
1266 gather_statistics(reason, action, trap_bc); | 1266 gather_statistics(reason, action, trap_bc); |
1267 | 1267 |
1268 // Ensure that we can record deopt. history: | 1268 // Ensure that we can record deopt. history: |
1269 bool create_if_missing = ProfileTraps; | 1269 bool create_if_missing = ProfileTraps; |
1270 | 1270 |
1271 methodDataHandle trap_mdo | 1271 MethodData* trap_mdo = |
1272 (THREAD, get_method_data(thread, trap_method, create_if_missing)); | 1272 get_method_data(thread, trap_method, create_if_missing); |
1273 | 1273 |
1274 // Print a bunch of diagnostics, if requested. | 1274 // Print a bunch of diagnostics, if requested. |
1275 if (TraceDeoptimization || LogCompilation) { | 1275 if (TraceDeoptimization || LogCompilation) { |
1276 ResourceMark rm; | 1276 ResourceMark rm; |
1277 ttyLocker ttyl; | 1277 ttyLocker ttyl; |
1295 class_name = constants->symbol_at(unloaded_class_index); | 1295 class_name = constants->symbol_at(unloaded_class_index); |
1296 } | 1296 } |
1297 if (xtty != NULL) | 1297 if (xtty != NULL) |
1298 xtty->name(class_name); | 1298 xtty->name(class_name); |
1299 } | 1299 } |
1300 if (xtty != NULL && trap_mdo.not_null()) { | 1300 if (xtty != NULL && trap_mdo != NULL) { |
1301 // Dump the relevant MDO state. | 1301 // Dump the relevant MDO state. |
1302 // This is the deopt count for the current reason, any previous | 1302 // This is the deopt count for the current reason, any previous |
1303 // reasons or recompiles seen at this point. | 1303 // reasons or recompiles seen at this point. |
1304 int dcnt = trap_mdo->trap_count(reason); | 1304 int dcnt = trap_mdo->trap_count(reason); |
1305 if (dcnt != 0) | 1305 if (dcnt != 0) |
1378 // 3. In parallel with the previous measures, if the total number of | 1378 // 3. In parallel with the previous measures, if the total number of |
1379 // recompilations of a method exceeds the much larger set limit | 1379 // recompilations of a method exceeds the much larger set limit |
1380 // PerMethodRecompilationCutoff, the method is abandoned. | 1380 // PerMethodRecompilationCutoff, the method is abandoned. |
1381 // This should only happen if the method is very large and has | 1381 // This should only happen if the method is very large and has |
1382 // many "lukewarm" deoptimizations. The code which enforces this | 1382 // many "lukewarm" deoptimizations. The code which enforces this |
1383 // limit is elsewhere (class nmethod, class methodOopDesc). | 1383 // limit is elsewhere (class nmethod, class Method). |
1384 // | 1384 // |
1385 // Note that the per-BCI 'is_recompiled' bit gives the compiler one chance | 1385 // Note that the per-BCI 'is_recompiled' bit gives the compiler one chance |
1386 // to recompile at each bytecode independently of the per-BCI cutoff. | 1386 // to recompile at each bytecode independently of the per-BCI cutoff. |
1387 // | 1387 // |
1388 // The decision to update code is up to the compiler, and is encoded | 1388 // The decision to update code is up to the compiler, and is encoded |
1447 } | 1447 } |
1448 | 1448 |
1449 // Setting +ProfileTraps fixes the following, on all platforms: | 1449 // Setting +ProfileTraps fixes the following, on all platforms: |
1450 // 4852688: ProfileInterpreter is off by default for ia64. The result is | 1450 // 4852688: ProfileInterpreter is off by default for ia64. The result is |
1451 // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the | 1451 // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the |
1452 // recompile relies on a methodDataOop to record heroic opt failures. | 1452 // recompile relies on a MethodData* to record heroic opt failures. |
1453 | 1453 |
1454 // Whether the interpreter is producing MDO data or not, we also need | 1454 // Whether the interpreter is producing MDO data or not, we also need |
1455 // to use the MDO to detect hot deoptimization points and control | 1455 // to use the MDO to detect hot deoptimization points and control |
1456 // aggressive optimization. | 1456 // aggressive optimization. |
1457 bool inc_recompile_count = false; | 1457 bool inc_recompile_count = false; |
1458 ProfileData* pdata = NULL; | 1458 ProfileData* pdata = NULL; |
1459 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { | 1459 if (ProfileTraps && update_trap_state && trap_mdo != NULL) { |
1460 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); | 1460 assert(trap_mdo == get_method_data(thread, trap_method, false), "sanity"); |
1461 uint this_trap_count = 0; | 1461 uint this_trap_count = 0; |
1462 bool maybe_prior_trap = false; | 1462 bool maybe_prior_trap = false; |
1463 bool maybe_prior_recompile = false; | 1463 bool maybe_prior_recompile = false; |
1464 pdata = query_update_method_data(trap_mdo, trap_bci, reason, | 1464 pdata = query_update_method_data(trap_mdo, trap_bci, reason, |
1465 //outputs: | 1465 //outputs: |
1571 } // Free marked resources | 1571 } // Free marked resources |
1572 | 1572 |
1573 } | 1573 } |
1574 JRT_END | 1574 JRT_END |
1575 | 1575 |
1576 methodDataOop | 1576 MethodData* |
1577 Deoptimization::get_method_data(JavaThread* thread, methodHandle m, | 1577 Deoptimization::get_method_data(JavaThread* thread, methodHandle m, |
1578 bool create_if_missing) { | 1578 bool create_if_missing) { |
1579 Thread* THREAD = thread; | 1579 Thread* THREAD = thread; |
1580 methodDataOop mdo = m()->method_data(); | 1580 MethodData* mdo = m()->method_data(); |
1581 if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { | 1581 if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { |
1582 // Build an MDO. Ignore errors like OutOfMemory; | 1582 // Build an MDO. Ignore errors like OutOfMemory; |
1583 // that simply means we won't have an MDO to update. | 1583 // that simply means we won't have an MDO to update. |
1584 methodOopDesc::build_interpreter_method_data(m, THREAD); | 1584 Method::build_interpreter_method_data(m, THREAD); |
1585 if (HAS_PENDING_EXCEPTION) { | 1585 if (HAS_PENDING_EXCEPTION) { |
1586 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); | 1586 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); |
1587 CLEAR_PENDING_EXCEPTION; | 1587 CLEAR_PENDING_EXCEPTION; |
1588 } | 1588 } |
1589 mdo = m()->method_data(); | 1589 mdo = m()->method_data(); |
1590 } | 1590 } |
1591 return mdo; | 1591 return mdo; |
1592 } | 1592 } |
1593 | 1593 |
1594 ProfileData* | 1594 ProfileData* |
1595 Deoptimization::query_update_method_data(methodDataHandle trap_mdo, | 1595 Deoptimization::query_update_method_data(MethodData* trap_mdo, |
1596 int trap_bci, | 1596 int trap_bci, |
1597 Deoptimization::DeoptReason reason, | 1597 Deoptimization::DeoptReason reason, |
1598 //outputs: | 1598 //outputs: |
1599 uint& ret_this_trap_count, | 1599 uint& ret_this_trap_count, |
1600 bool& ret_maybe_prior_trap, | 1600 bool& ret_maybe_prior_trap, |
1650 ret_maybe_prior_recompile = maybe_prior_recompile; | 1650 ret_maybe_prior_recompile = maybe_prior_recompile; |
1651 return pdata; | 1651 return pdata; |
1652 } | 1652 } |
1653 | 1653 |
1654 void | 1654 void |
1655 Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) { | 1655 Deoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) { |
1656 ResourceMark rm; | 1656 ResourceMark rm; |
1657 // Ignored outputs: | 1657 // Ignored outputs: |
1658 uint ignore_this_trap_count; | 1658 uint ignore_this_trap_count; |
1659 bool ignore_maybe_prior_trap; | 1659 bool ignore_maybe_prior_trap; |
1660 bool ignore_maybe_prior_recompile; | 1660 bool ignore_maybe_prior_recompile; |
1938 void Deoptimization::print_statistics() { | 1938 void Deoptimization::print_statistics() { |
1939 // no output | 1939 // no output |
1940 } | 1940 } |
1941 | 1941 |
1942 void | 1942 void |
1943 Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) { | 1943 Deoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) { |
1944 // no udpate | 1944 // no udpate |
1945 } | 1945 } |
1946 | 1946 |
1947 int Deoptimization::trap_state_has_reason(int trap_state, int reason) { | 1947 int Deoptimization::trap_state_has_reason(int trap_state, int reason) { |
1948 return 0; | 1948 return 0; |