Mercurial > hg > truffle
comparison src/share/vm/runtime/frame.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 | e522a00b91aa d0aa87f04bd5 cd3d6a6b95d9 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
27 #include "interpreter/interpreter.hpp" | 27 #include "interpreter/interpreter.hpp" |
28 #include "interpreter/oopMapCache.hpp" | 28 #include "interpreter/oopMapCache.hpp" |
29 #include "memory/resourceArea.hpp" | 29 #include "memory/resourceArea.hpp" |
30 #include "memory/universe.inline.hpp" | 30 #include "memory/universe.inline.hpp" |
31 #include "oops/markOop.hpp" | 31 #include "oops/markOop.hpp" |
32 #include "oops/methodDataOop.hpp" | 32 #include "oops/methodData.hpp" |
33 #include "oops/methodOop.hpp" | 33 #include "oops/method.hpp" |
34 #include "oops/oop.inline.hpp" | 34 #include "oops/oop.inline.hpp" |
35 #include "oops/oop.inline2.hpp" | 35 #include "oops/oop.inline2.hpp" |
36 #include "prims/methodHandles.hpp" | 36 #include "prims/methodHandles.hpp" |
37 #include "runtime/frame.inline.hpp" | 37 #include "runtime/frame.inline.hpp" |
38 #include "runtime/handles.inline.hpp" | 38 #include "runtime/handles.inline.hpp" |
381 void frame::interpreter_frame_set_locals(intptr_t* locs) { | 381 void frame::interpreter_frame_set_locals(intptr_t* locs) { |
382 assert(is_interpreted_frame(), "Not an interpreted frame"); | 382 assert(is_interpreted_frame(), "Not an interpreted frame"); |
383 *interpreter_frame_locals_addr() = locs; | 383 *interpreter_frame_locals_addr() = locs; |
384 } | 384 } |
385 | 385 |
386 methodOop frame::interpreter_frame_method() const { | 386 Method* frame::interpreter_frame_method() const { |
387 assert(is_interpreted_frame(), "interpreted frame expected"); | 387 assert(is_interpreted_frame(), "interpreted frame expected"); |
388 methodOop m = *interpreter_frame_method_addr(); | 388 Method* m = *interpreter_frame_method_addr(); |
389 assert(m->is_perm(), "bad methodOop in interpreter frame"); | 389 assert(m->is_metadata(), "bad Method* in interpreter frame"); |
390 assert(m->is_method(), "not a methodOop"); | 390 assert(m->is_method(), "not a Method*"); |
391 return m; | 391 return m; |
392 } | 392 } |
393 | 393 |
394 void frame::interpreter_frame_set_method(methodOop method) { | 394 void frame::interpreter_frame_set_method(Method* method) { |
395 assert(is_interpreted_frame(), "interpreted frame expected"); | 395 assert(is_interpreted_frame(), "interpreted frame expected"); |
396 *interpreter_frame_method_addr() = method; | 396 *interpreter_frame_method_addr() = method; |
397 } | 397 } |
398 | 398 |
399 void frame::interpreter_frame_set_bcx(intptr_t bcx) { | 399 void frame::interpreter_frame_set_bcx(intptr_t bcx) { |
408 if (mdx != 0) { | 408 if (mdx != 0) { |
409 if (formerly_bci) { | 409 if (formerly_bci) { |
410 if (!is_now_bci) { | 410 if (!is_now_bci) { |
411 // The bcx was just converted from bci to bcp. | 411 // The bcx was just converted from bci to bcp. |
412 // Convert the mdx in parallel. | 412 // Convert the mdx in parallel. |
413 methodDataOop mdo = interpreter_frame_method()->method_data(); | 413 MethodData* mdo = interpreter_frame_method()->method_data(); |
414 assert(mdo != NULL, ""); | 414 assert(mdo != NULL, ""); |
415 int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one. | 415 int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one. |
416 address mdp = mdo->di_to_dp(mdi); | 416 address mdp = mdo->di_to_dp(mdi); |
417 interpreter_frame_set_mdx((intptr_t)mdp); | 417 interpreter_frame_set_mdx((intptr_t)mdp); |
418 } | 418 } |
419 } else { | 419 } else { |
420 if (is_now_bci) { | 420 if (is_now_bci) { |
421 // The bcx was just converted from bcp to bci. | 421 // The bcx was just converted from bcp to bci. |
422 // Convert the mdx in parallel. | 422 // Convert the mdx in parallel. |
423 methodDataOop mdo = interpreter_frame_method()->method_data(); | 423 MethodData* mdo = interpreter_frame_method()->method_data(); |
424 assert(mdo != NULL, ""); | 424 assert(mdo != NULL, ""); |
425 int mdi = mdo->dp_to_di((address)mdx); | 425 int mdi = mdo->dp_to_di((address)mdx); |
426 interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0. | 426 interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0. |
427 } | 427 } |
428 } | 428 } |
689 // suggests the problem is in user lib; everything else is likely a VM bug. | 689 // suggests the problem is in user lib; everything else is likely a VM bug. |
690 | 690 |
691 void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const { | 691 void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const { |
692 if (_cb != NULL) { | 692 if (_cb != NULL) { |
693 if (Interpreter::contains(pc())) { | 693 if (Interpreter::contains(pc())) { |
694 methodOop m = this->interpreter_frame_method(); | 694 Method* m = this->interpreter_frame_method(); |
695 if (m != NULL) { | 695 if (m != NULL) { |
696 m->name_and_sig_as_C_string(buf, buflen); | 696 m->name_and_sig_as_C_string(buf, buflen); |
697 st->print("j %s", buf); | 697 st->print("j %s", buf); |
698 st->print("+%d", this->interpreter_frame_bci()); | 698 st->print("+%d", this->interpreter_frame_bci()); |
699 } else { | 699 } else { |
707 st->print("v ~StubRoutines::" PTR_FORMAT, pc()); | 707 st->print("v ~StubRoutines::" PTR_FORMAT, pc()); |
708 } | 708 } |
709 } else if (_cb->is_buffer_blob()) { | 709 } else if (_cb->is_buffer_blob()) { |
710 st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); | 710 st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); |
711 } else if (_cb->is_nmethod()) { | 711 } else if (_cb->is_nmethod()) { |
712 methodOop m = ((nmethod *)_cb)->method(); | 712 Method* m = ((nmethod *)_cb)->method(); |
713 if (m != NULL) { | 713 if (m != NULL) { |
714 m->name_and_sig_as_C_string(buf, buflen); | 714 m->name_and_sig_as_C_string(buf, buflen); |
715 st->print("J %s", buf); | 715 st->print("J %s", buf); |
716 } else { | 716 } else { |
717 st->print("J " PTR_FORMAT, pc()); | 717 st->print("J " PTR_FORMAT, pc()); |
734 | 734 |
735 | 735 |
736 /* | 736 /* |
737 The interpreter_frame_expression_stack_at method in the case of SPARC needs the | 737 The interpreter_frame_expression_stack_at method in the case of SPARC needs the |
738 max_stack value of the method in order to compute the expression stack address. | 738 max_stack value of the method in order to compute the expression stack address. |
739 It uses the methodOop in order to get the max_stack value but during GC this | 739 It uses the Method* in order to get the max_stack value but during GC this |
740 methodOop value saved on the frame is changed by reverse_and_push and hence cannot | 740 Method* value saved on the frame is changed by reverse_and_push and hence cannot |
741 be used. So we save the max_stack value in the FrameClosure object and pass it | 741 be used. So we save the max_stack value in the FrameClosure object and pass it |
742 down to the interpreter_frame_expression_stack_at method | 742 down to the interpreter_frame_expression_stack_at method |
743 */ | 743 */ |
744 class InterpreterFrameClosure : public OffsetClosure { | 744 class InterpreterFrameClosure : public OffsetClosure { |
745 private: | 745 private: |
884 assert(map != NULL, "map must be set"); | 884 assert(map != NULL, "map must be set"); |
885 Thread *thread = Thread::current(); | 885 Thread *thread = Thread::current(); |
886 methodHandle m (thread, interpreter_frame_method()); | 886 methodHandle m (thread, interpreter_frame_method()); |
887 jint bci = interpreter_frame_bci(); | 887 jint bci = interpreter_frame_bci(); |
888 | 888 |
889 assert(Universe::heap()->is_in(m()), "must be valid oop"); | 889 assert(!Universe::heap()->is_in(m()), |
890 "must be valid oop"); | |
890 assert(m->is_method(), "checking frame value"); | 891 assert(m->is_method(), "checking frame value"); |
891 assert((m->is_native() && bci == 0) || (!m->is_native() && bci >= 0 && bci < m->code_size()), "invalid bci value"); | 892 assert((m->is_native() && bci == 0) || |
893 (!m->is_native() && bci >= 0 && bci < m->code_size()), | |
894 "invalid bci value"); | |
892 | 895 |
893 // Handle the monitor elements in the activation | 896 // Handle the monitor elements in the activation |
894 for ( | 897 for ( |
895 BasicObjectLock* current = interpreter_frame_monitor_end(); | 898 BasicObjectLock* current = interpreter_frame_monitor_end(); |
896 current < interpreter_frame_monitor_begin(); | 899 current < interpreter_frame_monitor_begin(); |
901 #endif | 904 #endif |
902 current->oops_do(f); | 905 current->oops_do(f); |
903 } | 906 } |
904 | 907 |
905 // process fixed part | 908 // process fixed part |
906 f->do_oop((oop*)interpreter_frame_method_addr()); | |
907 f->do_oop((oop*)interpreter_frame_cache_addr()); | |
908 | |
909 // Hmm what about the mdp? | |
910 #ifdef CC_INTERP | |
911 // Interpreter frame in the midst of a call have a methodOop within the | |
912 // object. | |
913 interpreterState istate = get_interpreterState(); | |
914 if (istate->msg() == BytecodeInterpreter::call_method) { | |
915 f->do_oop((oop*)&istate->_result._to_call._callee); | |
916 } | |
917 | |
918 #endif /* CC_INTERP */ | |
919 | |
920 #if !defined(PPC) || defined(ZERO) | 909 #if !defined(PPC) || defined(ZERO) |
921 if (m->is_native()) { | 910 if (m->is_native()) { |
922 #ifdef CC_INTERP | 911 #ifdef CC_INTERP |
912 interpreterState istate = get_interpreterState(); | |
923 f->do_oop((oop*)&istate->_oop_temp); | 913 f->do_oop((oop*)&istate->_oop_temp); |
924 #else | 914 #else |
925 f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset )); | 915 f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset )); |
926 #endif /* CC_INTERP */ | 916 #endif /* CC_INTERP */ |
927 } | 917 } |
1146 cf->do_code_blob(_cb); | 1136 cf->do_code_blob(_cb); |
1147 } | 1137 } |
1148 } | 1138 } |
1149 | 1139 |
1150 | 1140 |
1141 // call f() on the interpreted Method*s in the stack. | |
1142 // Have to walk the entire code cache for the compiled frames Yuck. | |
1143 void frame::metadata_do(void f(Metadata*)) { | |
1144 if (_cb != NULL && Interpreter::contains(pc())) { | |
1145 Method* m = this->interpreter_frame_method(); | |
1146 assert(m != NULL, "huh?"); | |
1147 f(m); | |
1148 } | |
1149 } | |
1150 | |
1151 void frame::gc_prologue() { | 1151 void frame::gc_prologue() { |
1152 if (is_interpreted_frame()) { | 1152 if (is_interpreted_frame()) { |
1153 // set bcx to bci to become methodOop position independent during GC | 1153 // set bcx to bci to become Method* position independent during GC |
1154 interpreter_frame_set_bcx(interpreter_frame_bci()); | 1154 interpreter_frame_set_bcx(interpreter_frame_bci()); |
1155 } | 1155 } |
1156 } | 1156 } |
1157 | 1157 |
1158 | 1158 |
1223 | 1223 |
1224 | 1224 |
1225 void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) { | 1225 void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) { |
1226 // get current interpreter 'pc' | 1226 // get current interpreter 'pc' |
1227 assert(is_interpreted_frame(), "Not an interpreted frame"); | 1227 assert(is_interpreted_frame(), "Not an interpreted frame"); |
1228 methodOop m = interpreter_frame_method(); | 1228 Method* m = interpreter_frame_method(); |
1229 int bci = interpreter_frame_bci(); | 1229 int bci = interpreter_frame_bci(); |
1230 | 1230 |
1231 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); | 1231 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); |
1232 | 1232 |
1233 // process dynamic part | 1233 // process dynamic part |
1267 # endif // ENABLE_ZAP_DEAD_LOCALS | 1267 # endif // ENABLE_ZAP_DEAD_LOCALS |
1268 | 1268 |
1269 void frame::verify(const RegisterMap* map) { | 1269 void frame::verify(const RegisterMap* map) { |
1270 // for now make sure receiver type is correct | 1270 // for now make sure receiver type is correct |
1271 if (is_interpreted_frame()) { | 1271 if (is_interpreted_frame()) { |
1272 methodOop method = interpreter_frame_method(); | 1272 Method* method = interpreter_frame_method(); |
1273 guarantee(method->is_method(), "method is wrong in frame::verify"); | 1273 guarantee(method->is_method(), "method is wrong in frame::verify"); |
1274 if (!method->is_static()) { | 1274 if (!method->is_static()) { |
1275 // fetch the receiver | 1275 // fetch the receiver |
1276 oop* p = (oop*) interpreter_frame_local_at(0); | 1276 oop* p = (oop*) interpreter_frame_local_at(0); |
1277 // make sure we have the right receiver type | 1277 // make sure we have the right receiver type |
1332 // Label values common to most frames | 1332 // Label values common to most frames |
1333 values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no)); | 1333 values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no)); |
1334 } | 1334 } |
1335 | 1335 |
1336 if (is_interpreted_frame()) { | 1336 if (is_interpreted_frame()) { |
1337 methodOop m = interpreter_frame_method(); | 1337 Method* m = interpreter_frame_method(); |
1338 int bci = interpreter_frame_bci(); | 1338 int bci = interpreter_frame_bci(); |
1339 | 1339 |
1340 // Label the method and current bci | 1340 // Label the method and current bci |
1341 values.describe(-1, info_address, | 1341 values.describe(-1, info_address, |
1342 FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2); | 1342 FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2); |