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 {