Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/frame.cpp @ 1138:dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
Summary: C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance.
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Tue, 05 Jan 2010 15:21:25 +0100 |
parents | 148e5441d916 |
children | 9b9c1ee9b3f6 |
comparison
equal
deleted
inserted
replaced
1137:97125851f396 | 1138:dd57230ba8fe |
---|---|
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 |