Mercurial > hg > truffle
comparison src/cpu/x86/vm/graalRuntime_x86.cpp @ 8127:3d41998c30de
Create new way of handling unwind that recalculates rbp from rsp. Remove unused instanceof slow path stub.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Wed, 06 Mar 2013 16:37:18 +0100 |
parents | c6c72de0537e |
children | 3d33975f6497 |
comparison
equal
deleted
inserted
replaced
8125:0026a2e70695 | 8127:3d41998c30de |
---|---|
44 // setup registers | 44 // setup registers |
45 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) | 45 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) |
46 assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different"); | 46 assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different"); |
47 assert(oop_result1 != thread && metadata_result != thread, "registers must be different"); | 47 assert(oop_result1 != thread && metadata_result != thread, "registers must be different"); |
48 assert(args_size >= 0, "illegal args_size"); | 48 assert(args_size >= 0, "illegal args_size"); |
49 bool align_stack = false; | |
50 #ifdef _LP64 | |
51 // At a method handle call, the stack may not be properly aligned | |
52 // when returning with an exception. | |
53 align_stack = (stub_id() == false /*GraalRuntime::handle_exception_from_callee_id*/); | |
54 #endif | |
55 | 49 |
56 #ifdef _LP64 | 50 #ifdef _LP64 |
57 mov(c_rarg0, thread); | 51 mov(c_rarg0, thread); |
58 set_num_rt_args(0); // Nothing on stack | 52 set_num_rt_args(0); // Nothing on stack |
59 #else | 53 #else |
63 get_thread(thread); | 57 get_thread(thread); |
64 push(thread); | 58 push(thread); |
65 #endif // _LP64 | 59 #endif // _LP64 |
66 | 60 |
67 int call_offset; | 61 int call_offset; |
68 if (!align_stack) { | 62 set_last_Java_frame(thread, rsp, noreg, NULL); |
69 set_last_Java_frame(thread, noreg, rbp, NULL); | |
70 } else { | |
71 address the_pc = pc(); | |
72 call_offset = offset(); | |
73 set_last_Java_frame(thread, noreg, rbp, the_pc); | |
74 andptr(rsp, -(StackAlignmentInBytes)); // Align stack | |
75 } | |
76 | 63 |
77 // do the call | 64 // do the call |
78 call(RuntimeAddress(entry)); | 65 call(RuntimeAddress(entry)); |
79 if (!align_stack) { | 66 call_offset = offset(); |
80 call_offset = offset(); | |
81 } | |
82 // verify callee-saved register | 67 // verify callee-saved register |
83 #ifdef ASSERT | 68 #ifdef ASSERT |
84 guarantee(thread != rax, "change this code"); | 69 guarantee(thread != rax, "change this code"); |
85 push(rax); | 70 push(rax); |
86 { Label L; | 71 { Label L; |
91 stop("GraalStubAssembler::call_RT: rdi not callee saved?"); | 76 stop("GraalStubAssembler::call_RT: rdi not callee saved?"); |
92 bind(L); | 77 bind(L); |
93 } | 78 } |
94 pop(rax); | 79 pop(rax); |
95 #endif | 80 #endif |
96 reset_last_Java_frame(thread, true, align_stack); | 81 reset_last_Java_frame(thread, true, false); |
97 | 82 |
98 // discard thread and arguments | 83 // discard thread and arguments |
99 NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); | 84 NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); |
100 | 85 |
101 // check for pending exceptions | 86 // check for pending exceptions |
354 OopMap* map = new OopMap(frame_size_in_slots, 0); | 339 OopMap* map = new OopMap(frame_size_in_slots, 0); |
355 map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg()); | 340 map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg()); |
356 map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); | 341 map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); |
357 map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); | 342 map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); |
358 map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); | 343 map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); |
344 map->set_callee_saved(VMRegImpl::stack2reg(rbp_off + num_rt_args), rbp->as_VMReg()); | |
359 map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); | 345 map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); |
360 map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); | 346 map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); |
361 #ifdef _LP64 | 347 #ifdef _LP64 |
362 map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg()); | 348 map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg()); |
363 map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg()); | 349 map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg()); |
371 // This is stupid but needed. | 357 // This is stupid but needed. |
372 map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next()); | 358 map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next()); |
373 map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); | 359 map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); |
374 map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); | 360 map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); |
375 map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); | 361 map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); |
362 map->set_callee_saved(VMRegImpl::stack2reg(rbpH_off + num_rt_args), rbp->as_VMReg()->next()); | |
376 map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); | 363 map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); |
377 map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); | 364 map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); |
378 | 365 |
379 map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next()); | 366 map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next()); |
380 map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next()); | 367 map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next()); |
931 { GraalStubFrame f(sasm, "handle_exception", dont_gc_arguments); | 918 { GraalStubFrame f(sasm, "handle_exception", dont_gc_arguments); |
932 oop_maps = generate_handle_exception(id, sasm); | 919 oop_maps = generate_handle_exception(id, sasm); |
933 } | 920 } |
934 break; | 921 break; |
935 | 922 |
936 case slow_subtype_check_id: | |
937 { | |
938 // Typical calling sequence: | |
939 // __ push(klass_RInfo); // object klass or other subclass | |
940 // __ push(sup_k_RInfo); // array element klass or other superclass | |
941 // __ call(slow_subtype_check); | |
942 // Note that the subclass is pushed first, and is therefore deepest. | |
943 // Previous versions of this code reversed the names 'sub' and 'super'. | |
944 // This was operationally harmless but made the code unreadable. | |
945 enum layout { | |
946 rax_off, SLOT2(raxH_off) | |
947 rcx_off, SLOT2(rcxH_off) | |
948 rsi_off, SLOT2(rsiH_off) | |
949 rdi_off, SLOT2(rdiH_off) | |
950 // saved_rbp_off, SLOT2(saved_rbpH_off) | |
951 return_off, SLOT2(returnH_off) | |
952 sup_k_off, SLOT2(sup_kH_off) | |
953 klass_off, SLOT2(superH_off) | |
954 framesize, | |
955 result_off = klass_off // deepest argument is also the return value | |
956 }; | |
957 | |
958 __ set_info("slow_subtype_check", dont_gc_arguments); | |
959 __ push(rdi); | |
960 __ push(rsi); | |
961 __ push(rcx); | |
962 __ push(rax); | |
963 | |
964 // This is called by pushing args and not with C abi | |
965 __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass | |
966 __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass | |
967 | |
968 Label miss; | |
969 Label success; | |
970 __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL); | |
971 | |
972 __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss); | |
973 | |
974 // fallthrough on success: | |
975 __ bind(success); | |
976 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result | |
977 __ pop(rax); | |
978 __ pop(rcx); | |
979 __ pop(rsi); | |
980 __ pop(rdi); | |
981 __ ret(0); | |
982 | |
983 __ bind(miss); | |
984 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result | |
985 __ pop(rax); | |
986 __ pop(rcx); | |
987 __ pop(rsi); | |
988 __ pop(rdi); | |
989 __ ret(0); | |
990 } | |
991 break; | |
992 | |
993 case unwind_exception_call_id: { | 923 case unwind_exception_call_id: { |
994 // remove the frame from the stack | 924 // remove the frame from the stack |
995 __ movptr(rsp, rbp); | 925 __ movptr(rsp, rbp); |
996 __ pop(rbp); | 926 __ pop(rbp); |
997 // exception_oop is passed using ordinary java calling conventions | |
998 __ movptr(rax, j_rarg0); | |
999 | 927 |
1000 Label nonNullExceptionOop; | 928 Label nonNullExceptionOop; |
1001 __ testptr(rax, rax); | 929 __ testptr(rax, rax); |
1002 __ jcc(Assembler::notZero, nonNullExceptionOop); | 930 __ jcc(Assembler::notZero, nonNullExceptionOop); |
1003 { | 931 { |