Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_Runtime1_x86.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | fd71ca8c5f88 da91efe96a93 |
children | 1baf7f1e3f23 |
comparison
equal
deleted
inserted
replaced
6711:ae13cc658b80 | 6948:e522a00b91aa |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. 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. |
27 #include "c1/c1_Defs.hpp" | 27 #include "c1/c1_Defs.hpp" |
28 #include "c1/c1_MacroAssembler.hpp" | 28 #include "c1/c1_MacroAssembler.hpp" |
29 #include "c1/c1_Runtime1.hpp" | 29 #include "c1/c1_Runtime1.hpp" |
30 #include "interpreter/interpreter.hpp" | 30 #include "interpreter/interpreter.hpp" |
31 #include "nativeInst_x86.hpp" | 31 #include "nativeInst_x86.hpp" |
32 #include "oops/compiledICHolderOop.hpp" | 32 #include "oops/compiledICHolder.hpp" |
33 #include "oops/oop.inline.hpp" | 33 #include "oops/oop.inline.hpp" |
34 #include "prims/jvmtiExport.hpp" | 34 #include "prims/jvmtiExport.hpp" |
35 #include "register_x86.hpp" | 35 #include "register_x86.hpp" |
36 #include "runtime/sharedRuntime.hpp" | 36 #include "runtime/sharedRuntime.hpp" |
37 #include "runtime/signature.hpp" | 37 #include "runtime/signature.hpp" |
40 | 40 |
41 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true); | 41 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true); |
42 | 42 |
43 // Implementation of StubAssembler | 43 // Implementation of StubAssembler |
44 | 44 |
45 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) { | 45 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) { |
46 // setup registers | 46 // setup registers |
47 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) | 47 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) |
48 assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); | 48 assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different"); |
49 assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); | 49 assert(oop_result1 != thread && metadata_result != thread, "registers must be different"); |
50 assert(args_size >= 0, "illegal args_size"); | 50 assert(args_size >= 0, "illegal args_size"); |
51 bool align_stack = false; | 51 bool align_stack = false; |
52 #ifdef _LP64 | 52 #ifdef _LP64 |
53 // At a method handle call, the stack may not be properly aligned | 53 // At a method handle call, the stack may not be properly aligned |
54 // when returning with an exception. | 54 // when returning with an exception. |
108 movptr(rax, Address(thread, Thread::pending_exception_offset())); | 108 movptr(rax, Address(thread, Thread::pending_exception_offset())); |
109 // make sure that the vm_results are cleared | 109 // make sure that the vm_results are cleared |
110 if (oop_result1->is_valid()) { | 110 if (oop_result1->is_valid()) { |
111 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); | 111 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); |
112 } | 112 } |
113 if (oop_result2->is_valid()) { | 113 if (metadata_result->is_valid()) { |
114 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); | 114 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); |
115 } | 115 } |
116 #ifdef GRAAL | 116 #ifdef GRAAL |
117 // (thomaswue) Deoptimize in case of an exception. | 117 // (thomaswue) Deoptimize in case of an exception. |
118 restore_live_registers(this, false); | 118 restore_live_registers(this, false); |
132 #endif | 132 #endif |
133 bind(L); | 133 bind(L); |
134 } | 134 } |
135 // get oop results if there are any and reset the values in the thread | 135 // get oop results if there are any and reset the values in the thread |
136 if (oop_result1->is_valid()) { | 136 if (oop_result1->is_valid()) { |
137 movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); | 137 get_vm_result(oop_result1, thread); |
138 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); | |
139 verify_oop(oop_result1); | |
140 } | 138 } |
141 if (oop_result2->is_valid()) { | 139 if (metadata_result->is_valid()) { |
142 movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); | 140 get_vm_result_2(metadata_result, thread); |
143 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); | |
144 verify_oop(oop_result2); | |
145 } | 141 } |
146 return call_offset; | 142 return call_offset; |
147 } | 143 } |
148 | 144 |
149 | 145 |
150 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) { | 146 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) { |
151 #ifdef _LP64 | 147 #ifdef _LP64 |
152 mov(c_rarg1, arg1); | 148 mov(c_rarg1, arg1); |
153 #else | 149 #else |
154 push(arg1); | 150 push(arg1); |
155 #endif // _LP64 | 151 #endif // _LP64 |
156 return call_RT(oop_result1, oop_result2, entry, 1); | 152 return call_RT(oop_result1, metadata_result, entry, 1); |
157 } | 153 } |
158 | 154 |
159 | 155 |
160 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) { | 156 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) { |
161 #ifdef _LP64 | 157 #ifdef _LP64 |
162 if (c_rarg1 == arg2) { | 158 if (c_rarg1 == arg2) { |
163 if (c_rarg2 == arg1) { | 159 if (c_rarg2 == arg1) { |
164 xchgq(arg1, arg2); | 160 xchgq(arg1, arg2); |
165 } else { | 161 } else { |
172 } | 168 } |
173 #else | 169 #else |
174 push(arg2); | 170 push(arg2); |
175 push(arg1); | 171 push(arg1); |
176 #endif // _LP64 | 172 #endif // _LP64 |
177 return call_RT(oop_result1, oop_result2, entry, 2); | 173 return call_RT(oop_result1, metadata_result, entry, 2); |
178 } | 174 } |
179 | 175 |
180 | 176 |
181 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) { | 177 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) { |
182 #ifdef _LP64 | 178 #ifdef _LP64 |
183 // if there is any conflict use the stack | 179 // if there is any conflict use the stack |
184 if (arg1 == c_rarg2 || arg1 == c_rarg3 || | 180 if (arg1 == c_rarg2 || arg1 == c_rarg3 || |
185 arg2 == c_rarg1 || arg1 == c_rarg3 || | 181 arg2 == c_rarg1 || arg1 == c_rarg3 || |
186 arg3 == c_rarg1 || arg1 == c_rarg2) { | 182 arg3 == c_rarg1 || arg1 == c_rarg2) { |
198 #else | 194 #else |
199 push(arg3); | 195 push(arg3); |
200 push(arg2); | 196 push(arg2); |
201 push(arg1); | 197 push(arg1); |
202 #endif // _LP64 | 198 #endif // _LP64 |
203 return call_RT(oop_result1, oop_result2, entry, 3); | 199 return call_RT(oop_result1, metadata_result, entry, 3); |
204 } | 200 } |
205 | 201 |
206 | 202 |
207 // Implementation of StubFrame | 203 // Implementation of StubFrame |
208 | 204 |
1057 __ push(rsi); | 1053 __ push(rsi); |
1058 #endif | 1054 #endif |
1059 | 1055 |
1060 if (id == fast_new_instance_init_check_id) { | 1056 if (id == fast_new_instance_init_check_id) { |
1061 // make sure the klass is initialized | 1057 // make sure the klass is initialized |
1062 __ cmpb(Address(klass, instanceKlass::init_state_offset()), instanceKlass::fully_initialized); | 1058 __ cmpb(Address(klass, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized); |
1063 __ jcc(Assembler::notEqual, slow_path); | 1059 __ jcc(Assembler::notEqual, slow_path); |
1064 } | 1060 } |
1065 | 1061 |
1066 #ifdef ASSERT | 1062 #ifdef ASSERT |
1067 // assert object can be fast path allocated | 1063 // assert object can be fast path allocated |
1148 Register bci = rax, method = rbx; | 1144 Register bci = rax, method = rbx; |
1149 __ enter(); | 1145 __ enter(); |
1150 OopMap* map = save_live_registers(sasm, 3); | 1146 OopMap* map = save_live_registers(sasm, 3); |
1151 // Retrieve bci | 1147 // Retrieve bci |
1152 __ movl(bci, Address(rbp, 2*BytesPerWord)); | 1148 __ movl(bci, Address(rbp, 2*BytesPerWord)); |
1153 // And a pointer to the methodOop | 1149 // And a pointer to the Method* |
1154 __ movptr(method, Address(rbp, 3*BytesPerWord)); | 1150 __ movptr(method, Address(rbp, 3*BytesPerWord)); |
1155 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); | 1151 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); |
1156 oop_maps = new OopMapSet(); | 1152 oop_maps = new OopMapSet(); |
1157 oop_maps->add_gc_map(call_offset, map); | 1153 oop_maps->add_gc_map(call_offset, map); |
1158 restore_live_registers(sasm); | 1154 restore_live_registers(sasm); |
1338 __ ret(0); | 1334 __ ret(0); |
1339 | 1335 |
1340 __ bind(register_finalizer); | 1336 __ bind(register_finalizer); |
1341 __ enter(); | 1337 __ enter(); |
1342 OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */); | 1338 OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */); |
1343 int call_offset = __ call_RT(noreg, noreg, | 1339 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax); |
1344 CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax); | |
1345 oop_maps = new OopMapSet(); | 1340 oop_maps = new OopMapSet(); |
1346 oop_maps->add_gc_map(call_offset, oop_map); | 1341 oop_maps->add_gc_map(call_offset, oop_map); |
1347 | 1342 |
1348 // Now restore all the live registers | 1343 // Now restore all the live registers |
1349 restore_live_registers(sasm); | 1344 restore_live_registers(sasm); |
1548 | 1543 |
1549 case load_klass_patching_id: | 1544 case load_klass_patching_id: |
1550 { StubFrame f(sasm, "load_klass_patching", dont_gc_arguments); | 1545 { StubFrame f(sasm, "load_klass_patching", dont_gc_arguments); |
1551 // we should set up register map | 1546 // we should set up register map |
1552 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); | 1547 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); |
1548 } | |
1549 break; | |
1550 | |
1551 case load_mirror_patching_id: | |
1552 { StubFrame f(sasm, "load_mirror_patching", dont_gc_arguments); | |
1553 // we should set up register map | |
1554 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); | |
1553 } | 1555 } |
1554 break; | 1556 break; |
1555 | 1557 |
1556 case dtrace_object_alloc_id: | 1558 case dtrace_object_alloc_id: |
1557 { // rax,: object | 1559 { // rax,: object |