1 /* |
1 /* |
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
767 }; |
767 }; |
768 |
768 |
769 |
769 |
770 class InterpretedArgumentOopFinder: public SignatureInfo { |
770 class InterpretedArgumentOopFinder: public SignatureInfo { |
771 private: |
771 private: |
772 OopClosure* _f; // Closure to invoke |
772 OopClosure* _f; // Closure to invoke |
773 int _offset; // TOS-relative offset, decremented with each argument |
773 int _offset; // TOS-relative offset, decremented with each argument |
774 bool _is_static; // true if the callee is a static method |
774 bool _has_receiver; // true if the callee has a receiver |
775 frame* _fr; |
775 frame* _fr; |
776 |
776 |
777 void set(int size, BasicType type) { |
777 void set(int size, BasicType type) { |
778 _offset -= size; |
778 _offset -= size; |
779 if (type == T_OBJECT || type == T_ARRAY) oop_offset_do(); |
779 if (type == T_OBJECT || type == T_ARRAY) oop_offset_do(); |
784 addr = (oop*)_fr->interpreter_frame_tos_at(_offset); |
784 addr = (oop*)_fr->interpreter_frame_tos_at(_offset); |
785 _f->do_oop(addr); |
785 _f->do_oop(addr); |
786 } |
786 } |
787 |
787 |
788 public: |
788 public: |
789 InterpretedArgumentOopFinder(symbolHandle signature, bool is_static, frame* fr, OopClosure* f) : SignatureInfo(signature) { |
789 InterpretedArgumentOopFinder(symbolHandle signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) { |
790 // compute size of arguments |
790 // compute size of arguments |
791 int args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1); |
791 int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
792 assert(!fr->is_interpreted_frame() || |
792 assert(!fr->is_interpreted_frame() || |
793 args_size <= fr->interpreter_frame_expression_stack_size(), |
793 args_size <= fr->interpreter_frame_expression_stack_size(), |
794 "args cannot be on stack anymore"); |
794 "args cannot be on stack anymore"); |
795 // initialize InterpretedArgumentOopFinder |
795 // initialize InterpretedArgumentOopFinder |
796 _f = f; |
796 _f = f; |
797 _fr = fr; |
797 _fr = fr; |
798 _offset = args_size; |
798 _offset = args_size; |
799 _is_static = is_static; |
|
800 } |
799 } |
801 |
800 |
802 void oops_do() { |
801 void oops_do() { |
803 if (!_is_static) { |
802 if (_has_receiver) { |
804 --_offset; |
803 --_offset; |
805 oop_offset_do(); |
804 oop_offset_do(); |
806 } |
805 } |
807 iterate_parameters(); |
806 iterate_parameters(); |
808 } |
807 } |
910 } |
909 } |
911 |
910 |
912 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); |
911 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); |
913 |
912 |
914 symbolHandle signature; |
913 symbolHandle signature; |
915 bool is_static = false; |
914 bool has_receiver = false; |
916 |
915 |
917 // Process a callee's arguments if we are at a call site |
916 // Process a callee's arguments if we are at a call site |
918 // (i.e., if we are at an invoke bytecode) |
917 // (i.e., if we are at an invoke bytecode) |
919 // This is used sometimes for calling into the VM, not for another |
918 // This is used sometimes for calling into the VM, not for another |
920 // interpreted or compiled frame. |
919 // interpreted or compiled frame. |
921 if (!m->is_native()) { |
920 if (!m->is_native()) { |
922 Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci); |
921 Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci); |
923 if (call != NULL) { |
922 if (call != NULL) { |
924 signature = symbolHandle(thread, call->signature()); |
923 signature = symbolHandle(thread, call->signature()); |
925 is_static = call->is_invokestatic(); |
924 has_receiver = call->has_receiver(); |
926 if (map->include_argument_oops() && |
925 if (map->include_argument_oops() && |
927 interpreter_frame_expression_stack_size() > 0) { |
926 interpreter_frame_expression_stack_size() > 0) { |
928 ResourceMark rm(thread); // is this right ??? |
927 ResourceMark rm(thread); // is this right ??? |
929 // we are at a call site & the expression stack is not empty |
928 // we are at a call site & the expression stack is not empty |
930 // => process callee's arguments |
929 // => process callee's arguments |
934 // cases we empty the expression stack completely be- |
933 // cases we empty the expression stack completely be- |
935 // fore handling the exception (the exception handling |
934 // fore handling the exception (the exception handling |
936 // code in the interpreter calls a blocking runtime |
935 // code in the interpreter calls a blocking runtime |
937 // routine which can cause this code to be executed). |
936 // routine which can cause this code to be executed). |
938 // (was bug gri 7/27/98) |
937 // (was bug gri 7/27/98) |
939 oops_interpreted_arguments_do(signature, is_static, f); |
938 oops_interpreted_arguments_do(signature, has_receiver, f); |
940 } |
939 } |
941 } |
940 } |
942 } |
941 } |
943 |
942 |
944 if (TaggedStackInterpreter) { |
943 if (TaggedStackInterpreter) { |
948 InterpreterOopMap oopmap_mask; |
947 InterpreterOopMap oopmap_mask; |
949 OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask); |
948 OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask); |
950 mask = &oopmap_mask; |
949 mask = &oopmap_mask; |
951 #endif // ASSERT |
950 #endif // ASSERT |
952 oops_interpreted_locals_do(f, max_locals, mask); |
951 oops_interpreted_locals_do(f, max_locals, mask); |
953 oops_interpreted_expressions_do(f, signature, is_static, |
952 oops_interpreted_expressions_do(f, signature, has_receiver, |
954 m->max_stack(), |
953 m->max_stack(), |
955 max_locals, mask); |
954 max_locals, mask); |
956 } else { |
955 } else { |
957 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); |
956 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); |
958 |
957 |
990 } |
989 } |
991 } |
990 } |
992 |
991 |
993 void frame::oops_interpreted_expressions_do(OopClosure *f, |
992 void frame::oops_interpreted_expressions_do(OopClosure *f, |
994 symbolHandle signature, |
993 symbolHandle signature, |
995 bool is_static, |
994 bool has_receiver, |
996 int max_stack, |
995 int max_stack, |
997 int max_locals, |
996 int max_locals, |
998 InterpreterOopMap *mask) { |
997 InterpreterOopMap *mask) { |
999 // There is no stack no matter what the esp is pointing to (native methods |
998 // There is no stack no matter what the esp is pointing to (native methods |
1000 // might look like expression stack is nonempty). |
999 // might look like expression stack is nonempty). |
1003 // Point the top of the expression stack above arguments to a call so |
1002 // Point the top of the expression stack above arguments to a call so |
1004 // arguments aren't gc'ed as both stack values for callee and callee |
1003 // arguments aren't gc'ed as both stack values for callee and callee |
1005 // arguments in callee's locals. |
1004 // arguments in callee's locals. |
1006 int args_size = 0; |
1005 int args_size = 0; |
1007 if (!signature.is_null()) { |
1006 if (!signature.is_null()) { |
1008 args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1); |
1007 args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
1009 } |
1008 } |
1010 |
1009 |
1011 intptr_t *tos_addr = interpreter_frame_tos_at(args_size); |
1010 intptr_t *tos_addr = interpreter_frame_tos_at(args_size); |
1012 assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same"); |
1011 assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same"); |
1013 intptr_t *frst_expr = interpreter_frame_expression_stack_at(0); |
1012 intptr_t *frst_expr = interpreter_frame_expression_stack_at(0); |
1036 #endif // ASSERT |
1035 #endif // ASSERT |
1037 } |
1036 } |
1038 } |
1037 } |
1039 } |
1038 } |
1040 |
1039 |
1041 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool is_static, OopClosure* f) { |
1040 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f) { |
1042 InterpretedArgumentOopFinder finder(signature, is_static, this, f); |
1041 InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); |
1043 finder.oops_do(); |
1042 finder.oops_do(); |
1044 } |
1043 } |
1045 |
1044 |
1046 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) { |
1045 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) { |
1047 assert(_cb != NULL, "sanity check"); |
1046 assert(_cb != NULL, "sanity check"); |
1064 } |
1063 } |
1065 |
1064 |
1066 class CompiledArgumentOopFinder: public SignatureInfo { |
1065 class CompiledArgumentOopFinder: public SignatureInfo { |
1067 protected: |
1066 protected: |
1068 OopClosure* _f; |
1067 OopClosure* _f; |
1069 int _offset; // the current offset, incremented with each argument |
1068 int _offset; // the current offset, incremented with each argument |
1070 bool _is_static; // true if the callee is a static method |
1069 bool _has_receiver; // true if the callee has a receiver |
1071 frame _fr; |
1070 frame _fr; |
1072 RegisterMap* _reg_map; |
1071 RegisterMap* _reg_map; |
1073 int _arg_size; |
1072 int _arg_size; |
1074 VMRegPair* _regs; // VMReg list of arguments |
1073 VMRegPair* _regs; // VMReg list of arguments |
1075 |
1074 |
1085 oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); |
1084 oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); |
1086 _f->do_oop(loc); |
1085 _f->do_oop(loc); |
1087 } |
1086 } |
1088 |
1087 |
1089 public: |
1088 public: |
1090 CompiledArgumentOopFinder(symbolHandle signature, bool is_static, OopClosure* f, frame fr, const RegisterMap* reg_map) |
1089 CompiledArgumentOopFinder(symbolHandle signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map) |
1091 : SignatureInfo(signature) { |
1090 : SignatureInfo(signature) { |
1092 |
1091 |
1093 // initialize CompiledArgumentOopFinder |
1092 // initialize CompiledArgumentOopFinder |
1094 _f = f; |
1093 _f = f; |
1095 _offset = 0; |
1094 _offset = 0; |
1096 _is_static = is_static; |
1095 _has_receiver = has_receiver; |
1097 _fr = fr; |
1096 _fr = fr; |
1098 _reg_map = (RegisterMap*)reg_map; |
1097 _reg_map = (RegisterMap*)reg_map; |
1099 _arg_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1); |
1098 _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
1100 |
1099 |
1101 int arg_size; |
1100 int arg_size; |
1102 _regs = SharedRuntime::find_callee_arguments(signature(), is_static, &arg_size); |
1101 _regs = SharedRuntime::find_callee_arguments(signature(), has_receiver, &arg_size); |
1103 assert(arg_size == _arg_size, "wrong arg size"); |
1102 assert(arg_size == _arg_size, "wrong arg size"); |
1104 } |
1103 } |
1105 |
1104 |
1106 void oops_do() { |
1105 void oops_do() { |
1107 if (!_is_static) { |
1106 if (_has_receiver) { |
1108 handle_oop_offset(); |
1107 handle_oop_offset(); |
1109 _offset++; |
1108 _offset++; |
1110 } |
1109 } |
1111 iterate_parameters(); |
1110 iterate_parameters(); |
1112 } |
1111 } |
1113 }; |
1112 }; |
1114 |
1113 |
1115 void frame::oops_compiled_arguments_do(symbolHandle signature, bool is_static, const RegisterMap* reg_map, OopClosure* f) { |
1114 void frame::oops_compiled_arguments_do(symbolHandle signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) { |
1116 ResourceMark rm; |
1115 ResourceMark rm; |
1117 CompiledArgumentOopFinder finder(signature, is_static, f, *this, reg_map); |
1116 CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map); |
1118 finder.oops_do(); |
1117 finder.oops_do(); |
1119 } |
1118 } |
1120 |
1119 |
1121 |
1120 |
1122 // Get receiver out of callers frame, i.e. find parameter 0 in callers |
1121 // Get receiver out of callers frame, i.e. find parameter 0 in callers |