23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "code/codeCache.hpp"
28 #include "code/scopeDesc.hpp"
29 #include "code/vmreg.inline.hpp"
30 #include "compiler/abstractCompiler.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "compiler/oopMap.hpp"
33 #include "gc/shared/collectedHeap.inline.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "interpreter/oopMapCache.hpp"
36 #include "logging/log.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/markWord.hpp"
40 #include "oops/method.inline.hpp"
41 #include "oops/methodData.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/stackChunkOop.inline.hpp"
44 #include "oops/verifyOopClosure.hpp"
45 #include "prims/methodHandles.hpp"
46 #include "runtime/continuation.hpp"
47 #include "runtime/continuationEntry.inline.hpp"
48 #include "runtime/frame.inline.hpp"
49 #include "runtime/handles.inline.hpp"
50 #include "runtime/javaCalls.hpp"
51 #include "runtime/javaThread.hpp"
52 #include "runtime/monitorChunk.hpp"
53 #include "runtime/os.hpp"
54 #include "runtime/sharedRuntime.hpp"
55 #include "runtime/signature.hpp"
56 #include "runtime/stackValue.hpp"
57 #include "runtime/stubCodeGenerator.hpp"
58 #include "runtime/stubRoutines.hpp"
59 #include "utilities/debug.hpp"
60 #include "utilities/decoder.hpp"
61 #include "utilities/formatBuffer.hpp"
62
63 RegisterMap::RegisterMap(JavaThread *thread, UpdateMap update_map, ProcessFrames process_frames, WalkContinuation walk_cont) {
64 _thread = thread;
65 _update_map = update_map == UpdateMap::include;
66 _process_frames = process_frames == ProcessFrames::include;
67 _walk_cont = walk_cont == WalkContinuation::include;
68 clear();
69 DEBUG_ONLY (_update_for_id = NULL;)
70 NOT_PRODUCT(_skip_missing = false;)
71 NOT_PRODUCT(_async = false;)
72
73 if (walk_cont == WalkContinuation::include && thread != NULL && thread->last_continuation() != NULL) {
74 _chunk = stackChunkHandle(Thread::current()->handle_area()->allocate_null_handle(), true /* dummy */);
75 }
76 _chunk_index = -1;
77
78 #ifndef PRODUCT
79 for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
80 #endif /* PRODUCT */
81 }
330 return !nm->is_at_poll_return(pc());
331 }
332
333 void frame::deoptimize(JavaThread* thread) {
334 assert(thread == NULL
335 || (thread->frame_anchor()->has_last_Java_frame() &&
336 thread->frame_anchor()->walkable()), "must be");
337 // Schedule deoptimization of an nmethod activation with this frame.
338 assert(_cb != NULL && _cb->is_compiled(), "must be");
339
340 // If the call site is a MethodHandle call site use the MH deopt handler.
341 CompiledMethod* cm = (CompiledMethod*) _cb;
342 address deopt = cm->is_method_handle_return(pc()) ?
343 cm->deopt_mh_handler_begin() :
344 cm->deopt_handler_begin();
345
346 NativePostCallNop* inst = nativePostCallNop_at(pc());
347
348 // Save the original pc before we patch in the new one
349 cm->set_original_pc(this, pc());
350 patch_pc(thread, deopt);
351 assert(is_deoptimized_frame(), "must be");
352
353 #ifdef ASSERT
354 if (thread != NULL) {
355 frame check = thread->last_frame();
356 if (is_older(check.id())) {
357 RegisterMap map(thread,
358 RegisterMap::UpdateMap::skip,
359 RegisterMap::ProcessFrames::include,
360 RegisterMap::WalkContinuation::skip);
361 while (id() != check.id()) {
362 check = check.sender(&map);
363 }
364 assert(check.is_deoptimized_frame(), "missed deopt");
365 }
366 }
367 #endif // ASSERT
368 }
369
728 }
729
730
731 /*
732 The interpreter_frame_expression_stack_at method in the case of SPARC needs the
733 max_stack value of the method in order to compute the expression stack address.
734 It uses the Method* in order to get the max_stack value but during GC this
735 Method* value saved on the frame is changed by reverse_and_push and hence cannot
736 be used. So we save the max_stack value in the FrameClosure object and pass it
737 down to the interpreter_frame_expression_stack_at method
738 */
739 class InterpreterFrameClosure : public OffsetClosure {
740 private:
741 const frame* _fr;
742 OopClosure* _f;
743 int _max_locals;
744 int _max_stack;
745
746 public:
747 InterpreterFrameClosure(const frame* fr, int max_locals, int max_stack,
748 OopClosure* f) {
749 _fr = fr;
750 _max_locals = max_locals;
751 _max_stack = max_stack;
752 _f = f;
753 }
754
755 void offset_do(int offset) {
756 oop* addr;
757 if (offset < _max_locals) {
758 addr = (oop*) _fr->interpreter_frame_local_at(offset);
759 assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
760 _f->do_oop(addr);
761 } else {
762 addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
763 // In case of exceptions, the expression stack is invalid and the esp will be reset to express
764 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
765 bool in_stack;
766 if (frame::interpreter_frame_expression_stack_direction() > 0) {
767 in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
768 } else {
769 in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
770 }
771 if (in_stack) {
772 _f->do_oop(addr);
773 }
774 }
775 }
776 };
777
778
779 class InterpretedArgumentOopFinder: public SignatureIterator {
780 private:
781 OopClosure* _f; // Closure to invoke
782 int _offset; // TOS-relative offset, decremented with each argument
783 bool _has_receiver; // true if the callee has a receiver
784 const frame* _fr;
785
786 friend class SignatureIterator; // so do_parameters_on can call do_type
787 void do_type(BasicType type) {
788 _offset -= parameter_type_word_count(type);
789 if (is_reference_type(type)) oop_offset_do();
790 }
791
792 void oop_offset_do() {
927 signature = call.signature();
928 has_receiver = call.has_receiver();
929 if (map->include_argument_oops() &&
930 interpreter_frame_expression_stack_size() > 0) {
931 ResourceMark rm(thread); // is this right ???
932 // we are at a call site & the expression stack is not empty
933 // => process callee's arguments
934 //
935 // Note: The expression stack can be empty if an exception
936 // occurred during method resolution/execution. In all
937 // cases we empty the expression stack completely be-
938 // fore handling the exception (the exception handling
939 // code in the interpreter calls a blocking runtime
940 // routine which can cause this code to be executed).
941 // (was bug gri 7/27/98)
942 oops_interpreted_arguments_do(signature, has_receiver, f);
943 }
944 }
945 }
946
947 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
948
949 // process locals & expression stack
950 InterpreterOopMap mask;
951 if (query_oop_map_cache) {
952 m->mask_for(bci, &mask);
953 } else {
954 OopMapCache::compute_one_oop_map(m, bci, &mask);
955 }
956 mask.iterate_oop(&blk);
957 }
958
959
960 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
961 InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
962 finder.oops_do();
963 }
964
965 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* reg_map) const {
966 assert(_cb != NULL, "sanity check");
967 assert((oop_map() == NULL) == (_cb->oop_maps() == NULL), "frame and _cb must agree that oopmap is set or not");
968 if (oop_map() != NULL) {
969 if (df != NULL) {
970 _oop_map->oops_do(this, reg_map, f, df);
971 } else {
972 _oop_map->oops_do(this, reg_map, f, derived_mode);
973 }
974
975 // Preserve potential arguments for a callee. We handle this by dispatching
976 // on the codeblob. For c2i, we do
977 if (reg_map->include_argument_oops()) {
978 _cb->preserve_callee_argument_oops(*this, reg_map, f);
990 class CompiledArgumentOopFinder: public SignatureIterator {
991 protected:
992 OopClosure* _f;
993 int _offset; // the current offset, incremented with each argument
994 bool _has_receiver; // true if the callee has a receiver
995 bool _has_appendix; // true if the call has an appendix
996 frame _fr;
997 RegisterMap* _reg_map;
998 int _arg_size;
999 VMRegPair* _regs; // VMReg list of arguments
1000
1001 friend class SignatureIterator; // so do_parameters_on can call do_type
1002 void do_type(BasicType type) {
1003 if (is_reference_type(type)) handle_oop_offset();
1004 _offset += parameter_type_word_count(type);
1005 }
1006
1007 virtual void handle_oop_offset() {
1008 // Extract low order register number from register array.
1009 // In LP64-land, the high-order bits are valid but unhelpful.
1010 VMReg reg = _regs[_offset].first();
1011 oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1012 #ifdef ASSERT
1013 if (loc == NULL) {
1014 if (_reg_map->should_skip_missing()) {
1015 return;
1016 }
1017 tty->print_cr("Error walking frame oops:");
1018 _fr.print_on(tty);
1019 assert(loc != NULL, "missing register map entry reg: " INTPTR_FORMAT " %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1020 }
1021 #endif
1022 _f->do_oop(loc);
1023 }
1024
1025 public:
1026 CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1027 : SignatureIterator(signature) {
1028
1029 // initialize CompiledArgumentOopFinder
1030 _f = f;
1031 _offset = 0;
1032 _has_receiver = has_receiver;
1033 _has_appendix = has_appendix;
1034 _fr = fr;
1035 _reg_map = (RegisterMap*)reg_map;
1036 _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
1037
1038 int arg_size;
1039 _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
1040 assert(arg_size == _arg_size, "wrong arg size");
1041 }
1042
1043 void oops_do() {
1044 if (_has_receiver) {
1045 handle_oop_offset();
1046 _offset++;
1047 }
1048 do_parameters_on(this);
1049 if (_has_appendix) {
1050 handle_oop_offset();
1051 _offset++;
1052 }
1053 }
1054 };
1055
1056 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1057 const RegisterMap* reg_map, OopClosure* f) const {
1058 // ResourceMark rm;
1059 CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1060 finder.oops_do();
|
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "code/codeCache.hpp"
28 #include "code/scopeDesc.hpp"
29 #include "code/vmreg.inline.hpp"
30 #include "compiler/abstractCompiler.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "compiler/oopMap.hpp"
33 #include "gc/shared/collectedHeap.inline.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "interpreter/oopMapCache.hpp"
36 #include "logging/log.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/markWord.hpp"
40 #include "oops/method.inline.hpp"
41 #include "oops/methodData.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/inlineKlass.hpp"
44 #include "oops/stackChunkOop.inline.hpp"
45 #include "oops/verifyOopClosure.hpp"
46 #include "prims/methodHandles.hpp"
47 #include "runtime/continuation.hpp"
48 #include "runtime/continuationEntry.inline.hpp"
49 #include "runtime/frame.inline.hpp"
50 #include "runtime/handles.inline.hpp"
51 #include "runtime/javaCalls.hpp"
52 #include "runtime/javaThread.hpp"
53 #include "runtime/monitorChunk.hpp"
54 #include "runtime/os.hpp"
55 #include "runtime/sharedRuntime.hpp"
56 #include "runtime/signature.hpp"
57 #include "runtime/stackValue.hpp"
58 #include "runtime/stubCodeGenerator.hpp"
59 #include "runtime/stubRoutines.hpp"
60 #include "utilities/debug.hpp"
61 #include "utilities/decoder.hpp"
62 #include "utilities/formatBuffer.hpp"
63 #ifdef COMPILER1
64 #include "c1/c1_Runtime1.hpp"
65 #endif
66
67 RegisterMap::RegisterMap(JavaThread *thread, UpdateMap update_map, ProcessFrames process_frames, WalkContinuation walk_cont) {
68 _thread = thread;
69 _update_map = update_map == UpdateMap::include;
70 _process_frames = process_frames == ProcessFrames::include;
71 _walk_cont = walk_cont == WalkContinuation::include;
72 clear();
73 DEBUG_ONLY (_update_for_id = NULL;)
74 NOT_PRODUCT(_skip_missing = false;)
75 NOT_PRODUCT(_async = false;)
76
77 if (walk_cont == WalkContinuation::include && thread != NULL && thread->last_continuation() != NULL) {
78 _chunk = stackChunkHandle(Thread::current()->handle_area()->allocate_null_handle(), true /* dummy */);
79 }
80 _chunk_index = -1;
81
82 #ifndef PRODUCT
83 for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
84 #endif /* PRODUCT */
85 }
334 return !nm->is_at_poll_return(pc());
335 }
336
337 void frame::deoptimize(JavaThread* thread) {
338 assert(thread == NULL
339 || (thread->frame_anchor()->has_last_Java_frame() &&
340 thread->frame_anchor()->walkable()), "must be");
341 // Schedule deoptimization of an nmethod activation with this frame.
342 assert(_cb != NULL && _cb->is_compiled(), "must be");
343
344 // If the call site is a MethodHandle call site use the MH deopt handler.
345 CompiledMethod* cm = (CompiledMethod*) _cb;
346 address deopt = cm->is_method_handle_return(pc()) ?
347 cm->deopt_mh_handler_begin() :
348 cm->deopt_handler_begin();
349
350 NativePostCallNop* inst = nativePostCallNop_at(pc());
351
352 // Save the original pc before we patch in the new one
353 cm->set_original_pc(this, pc());
354
355 #ifdef COMPILER1
356 if (cm->is_compiled_by_c1() && cm->method()->has_scalarized_args() &&
357 pc() < cm->verified_inline_entry_point()) {
358 // The VEP and VIEP(RO) of C1-compiled methods call into the runtime to buffer scalarized value
359 // type args. We can't deoptimize at that point because the buffers have not yet been initialized.
360 // Also, if the method is synchronized, we first need to acquire the lock.
361 // Don't patch the return pc to delay deoptimization until we enter the method body (the check
362 // added in LIRGenerator::do_Base will detect the pending deoptimization by checking the original_pc).
363 #if defined ASSERT && !defined AARCH64 // Stub call site does not look like NativeCall on AArch64
364 NativeCall* call = nativeCall_before(this->pc());
365 address dest = call->destination();
366 assert(dest == Runtime1::entry_for(Runtime1::buffer_inline_args_no_receiver_id) ||
367 dest == Runtime1::entry_for(Runtime1::buffer_inline_args_id), "unexpected safepoint in entry point");
368 #endif
369 return;
370 }
371 #endif
372
373 patch_pc(thread, deopt);
374 assert(is_deoptimized_frame(), "must be");
375
376 #ifdef ASSERT
377 if (thread != NULL) {
378 frame check = thread->last_frame();
379 if (is_older(check.id())) {
380 RegisterMap map(thread,
381 RegisterMap::UpdateMap::skip,
382 RegisterMap::ProcessFrames::include,
383 RegisterMap::WalkContinuation::skip);
384 while (id() != check.id()) {
385 check = check.sender(&map);
386 }
387 assert(check.is_deoptimized_frame(), "missed deopt");
388 }
389 }
390 #endif // ASSERT
391 }
392
751 }
752
753
754 /*
755 The interpreter_frame_expression_stack_at method in the case of SPARC needs the
756 max_stack value of the method in order to compute the expression stack address.
757 It uses the Method* in order to get the max_stack value but during GC this
758 Method* value saved on the frame is changed by reverse_and_push and hence cannot
759 be used. So we save the max_stack value in the FrameClosure object and pass it
760 down to the interpreter_frame_expression_stack_at method
761 */
762 class InterpreterFrameClosure : public OffsetClosure {
763 private:
764 const frame* _fr;
765 OopClosure* _f;
766 int _max_locals;
767 int _max_stack;
768
769 public:
770 InterpreterFrameClosure(const frame* fr, int max_locals, int max_stack,
771 OopClosure* f, BufferedValueClosure* bvt_f) {
772 _fr = fr;
773 _max_locals = max_locals;
774 _max_stack = max_stack;
775 _f = f;
776 }
777
778 void offset_do(int offset) {
779 oop* addr;
780 if (offset < _max_locals) {
781 addr = (oop*) _fr->interpreter_frame_local_at(offset);
782 assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
783 if (_f != NULL) {
784 _f->do_oop(addr);
785 }
786 } else {
787 addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
788 // In case of exceptions, the expression stack is invalid and the esp will be reset to express
789 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
790 bool in_stack;
791 if (frame::interpreter_frame_expression_stack_direction() > 0) {
792 in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
793 } else {
794 in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
795 }
796 if (in_stack) {
797 if (_f != NULL) {
798 _f->do_oop(addr);
799 }
800 }
801 }
802 }
803 };
804
805
806 class InterpretedArgumentOopFinder: public SignatureIterator {
807 private:
808 OopClosure* _f; // Closure to invoke
809 int _offset; // TOS-relative offset, decremented with each argument
810 bool _has_receiver; // true if the callee has a receiver
811 const frame* _fr;
812
813 friend class SignatureIterator; // so do_parameters_on can call do_type
814 void do_type(BasicType type) {
815 _offset -= parameter_type_word_count(type);
816 if (is_reference_type(type)) oop_offset_do();
817 }
818
819 void oop_offset_do() {
954 signature = call.signature();
955 has_receiver = call.has_receiver();
956 if (map->include_argument_oops() &&
957 interpreter_frame_expression_stack_size() > 0) {
958 ResourceMark rm(thread); // is this right ???
959 // we are at a call site & the expression stack is not empty
960 // => process callee's arguments
961 //
962 // Note: The expression stack can be empty if an exception
963 // occurred during method resolution/execution. In all
964 // cases we empty the expression stack completely be-
965 // fore handling the exception (the exception handling
966 // code in the interpreter calls a blocking runtime
967 // routine which can cause this code to be executed).
968 // (was bug gri 7/27/98)
969 oops_interpreted_arguments_do(signature, has_receiver, f);
970 }
971 }
972 }
973
974 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f, NULL);
975
976 // process locals & expression stack
977 InterpreterOopMap mask;
978 if (query_oop_map_cache) {
979 m->mask_for(bci, &mask);
980 } else {
981 OopMapCache::compute_one_oop_map(m, bci, &mask);
982 }
983 mask.iterate_oop(&blk);
984 }
985
986 void frame::buffered_values_interpreted_do(BufferedValueClosure* f) {
987 assert(is_interpreted_frame(), "Not an interpreted frame");
988 Thread *thread = Thread::current();
989 methodHandle m (thread, interpreter_frame_method());
990 jint bci = interpreter_frame_bci();
991
992 assert(m->is_method(), "checking frame value");
993 assert(!m->is_native() && bci >= 0 && bci < m->code_size(),
994 "invalid bci value");
995
996 InterpreterFrameClosure blk(this, m->max_locals(), m->max_stack(), NULL, f);
997
998 // process locals & expression stack
999 InterpreterOopMap mask;
1000 m->mask_for(bci, &mask);
1001 mask.iterate_oop(&blk);
1002 }
1003
1004 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
1005 InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
1006 finder.oops_do();
1007 }
1008
1009 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* reg_map) const {
1010 assert(_cb != NULL, "sanity check");
1011 assert((oop_map() == NULL) == (_cb->oop_maps() == NULL), "frame and _cb must agree that oopmap is set or not");
1012 if (oop_map() != NULL) {
1013 if (df != NULL) {
1014 _oop_map->oops_do(this, reg_map, f, df);
1015 } else {
1016 _oop_map->oops_do(this, reg_map, f, derived_mode);
1017 }
1018
1019 // Preserve potential arguments for a callee. We handle this by dispatching
1020 // on the codeblob. For c2i, we do
1021 if (reg_map->include_argument_oops()) {
1022 _cb->preserve_callee_argument_oops(*this, reg_map, f);
1034 class CompiledArgumentOopFinder: public SignatureIterator {
1035 protected:
1036 OopClosure* _f;
1037 int _offset; // the current offset, incremented with each argument
1038 bool _has_receiver; // true if the callee has a receiver
1039 bool _has_appendix; // true if the call has an appendix
1040 frame _fr;
1041 RegisterMap* _reg_map;
1042 int _arg_size;
1043 VMRegPair* _regs; // VMReg list of arguments
1044
1045 friend class SignatureIterator; // so do_parameters_on can call do_type
1046 void do_type(BasicType type) {
1047 if (is_reference_type(type)) handle_oop_offset();
1048 _offset += parameter_type_word_count(type);
1049 }
1050
1051 virtual void handle_oop_offset() {
1052 // Extract low order register number from register array.
1053 // In LP64-land, the high-order bits are valid but unhelpful.
1054 assert(_offset < _arg_size, "out of bounds");
1055 VMReg reg = _regs[_offset].first();
1056 oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1057 #ifdef ASSERT
1058 if (loc == NULL) {
1059 if (_reg_map->should_skip_missing()) {
1060 return;
1061 }
1062 tty->print_cr("Error walking frame oops:");
1063 _fr.print_on(tty);
1064 assert(loc != NULL, "missing register map entry reg: " INTPTR_FORMAT " %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1065 }
1066 #endif
1067 _f->do_oop(loc);
1068 }
1069
1070 public:
1071 CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1072 : SignatureIterator(signature) {
1073
1074 // initialize CompiledArgumentOopFinder
1075 _f = f;
1076 _offset = 0;
1077 _has_receiver = has_receiver;
1078 _has_appendix = has_appendix;
1079 _fr = fr;
1080 _reg_map = (RegisterMap*)reg_map;
1081 _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &_arg_size);
1082 }
1083
1084 void oops_do() {
1085 if (_has_receiver) {
1086 handle_oop_offset();
1087 _offset++;
1088 }
1089 do_parameters_on(this);
1090 if (_has_appendix) {
1091 handle_oop_offset();
1092 _offset++;
1093 }
1094 }
1095 };
1096
1097 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1098 const RegisterMap* reg_map, OopClosure* f) const {
1099 // ResourceMark rm;
1100 CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1101 finder.oops_do();
|