Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_Runtime1_x86.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | bf7796b7367a |
children | e522a00b91aa db9981fd3124 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
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" |
39 #include "vmreg_x86.inline.hpp" | 39 #include "vmreg_x86.inline.hpp" |
40 | 40 |
41 | 41 |
42 // Implementation of StubAssembler | 42 // Implementation of StubAssembler |
43 | 43 |
44 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) { | 44 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) { |
45 // setup registers | 45 // setup registers |
46 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) | 46 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) |
47 assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); | 47 assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different"); |
48 assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); | 48 assert(oop_result1 != thread && metadata_result != thread, "registers must be different"); |
49 assert(args_size >= 0, "illegal args_size"); | 49 assert(args_size >= 0, "illegal args_size"); |
50 bool align_stack = false; | 50 bool align_stack = false; |
51 #ifdef _LP64 | 51 #ifdef _LP64 |
52 // At a method handle call, the stack may not be properly aligned | 52 // At a method handle call, the stack may not be properly aligned |
53 // when returning with an exception. | 53 // when returning with an exception. |
107 movptr(rax, Address(thread, Thread::pending_exception_offset())); | 107 movptr(rax, Address(thread, Thread::pending_exception_offset())); |
108 // make sure that the vm_results are cleared | 108 // make sure that the vm_results are cleared |
109 if (oop_result1->is_valid()) { | 109 if (oop_result1->is_valid()) { |
110 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); | 110 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); |
111 } | 111 } |
112 if (oop_result2->is_valid()) { | 112 if (metadata_result->is_valid()) { |
113 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); | 113 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); |
114 } | 114 } |
115 if (frame_size() == no_frame_size) { | 115 if (frame_size() == no_frame_size) { |
116 leave(); | 116 leave(); |
117 jump(RuntimeAddress(StubRoutines::forward_exception_entry())); | 117 jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
122 } | 122 } |
123 bind(L); | 123 bind(L); |
124 } | 124 } |
125 // get oop results if there are any and reset the values in the thread | 125 // get oop results if there are any and reset the values in the thread |
126 if (oop_result1->is_valid()) { | 126 if (oop_result1->is_valid()) { |
127 movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); | 127 get_vm_result(oop_result1, thread); |
128 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); | 128 } |
129 verify_oop(oop_result1); | 129 if (metadata_result->is_valid()) { |
130 } | 130 get_vm_result_2(metadata_result, thread); |
131 if (oop_result2->is_valid()) { | |
132 movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); | |
133 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); | |
134 verify_oop(oop_result2); | |
135 } | 131 } |
136 return call_offset; | 132 return call_offset; |
137 } | 133 } |
138 | 134 |
139 | 135 |
140 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) { | 136 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) { |
141 #ifdef _LP64 | 137 #ifdef _LP64 |
142 mov(c_rarg1, arg1); | 138 mov(c_rarg1, arg1); |
143 #else | 139 #else |
144 push(arg1); | 140 push(arg1); |
145 #endif // _LP64 | 141 #endif // _LP64 |
146 return call_RT(oop_result1, oop_result2, entry, 1); | 142 return call_RT(oop_result1, metadata_result, entry, 1); |
147 } | 143 } |
148 | 144 |
149 | 145 |
150 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) { | 146 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) { |
151 #ifdef _LP64 | 147 #ifdef _LP64 |
152 if (c_rarg1 == arg2) { | 148 if (c_rarg1 == arg2) { |
153 if (c_rarg2 == arg1) { | 149 if (c_rarg2 == arg1) { |
154 xchgq(arg1, arg2); | 150 xchgq(arg1, arg2); |
155 } else { | 151 } else { |
162 } | 158 } |
163 #else | 159 #else |
164 push(arg2); | 160 push(arg2); |
165 push(arg1); | 161 push(arg1); |
166 #endif // _LP64 | 162 #endif // _LP64 |
167 return call_RT(oop_result1, oop_result2, entry, 2); | 163 return call_RT(oop_result1, metadata_result, entry, 2); |
168 } | 164 } |
169 | 165 |
170 | 166 |
171 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) { | 167 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) { |
172 #ifdef _LP64 | 168 #ifdef _LP64 |
173 // if there is any conflict use the stack | 169 // if there is any conflict use the stack |
174 if (arg1 == c_rarg2 || arg1 == c_rarg3 || | 170 if (arg1 == c_rarg2 || arg1 == c_rarg3 || |
175 arg2 == c_rarg1 || arg1 == c_rarg3 || | 171 arg2 == c_rarg1 || arg1 == c_rarg3 || |
176 arg3 == c_rarg1 || arg1 == c_rarg2) { | 172 arg3 == c_rarg1 || arg1 == c_rarg2) { |
188 #else | 184 #else |
189 push(arg3); | 185 push(arg3); |
190 push(arg2); | 186 push(arg2); |
191 push(arg1); | 187 push(arg1); |
192 #endif // _LP64 | 188 #endif // _LP64 |
193 return call_RT(oop_result1, oop_result2, entry, 3); | 189 return call_RT(oop_result1, metadata_result, entry, 3); |
194 } | 190 } |
195 | 191 |
196 | 192 |
197 // Implementation of StubFrame | 193 // Implementation of StubFrame |
198 | 194 |
1025 __ push(rdi); | 1021 __ push(rdi); |
1026 __ push(rbx); | 1022 __ push(rbx); |
1027 | 1023 |
1028 if (id == fast_new_instance_init_check_id) { | 1024 if (id == fast_new_instance_init_check_id) { |
1029 // make sure the klass is initialized | 1025 // make sure the klass is initialized |
1030 __ cmpb(Address(klass, instanceKlass::init_state_offset()), instanceKlass::fully_initialized); | 1026 __ cmpb(Address(klass, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized); |
1031 __ jcc(Assembler::notEqual, slow_path); | 1027 __ jcc(Assembler::notEqual, slow_path); |
1032 } | 1028 } |
1033 | 1029 |
1034 #ifdef ASSERT | 1030 #ifdef ASSERT |
1035 // assert object can be fast path allocated | 1031 // assert object can be fast path allocated |
1104 Register bci = rax, method = rbx; | 1100 Register bci = rax, method = rbx; |
1105 __ enter(); | 1101 __ enter(); |
1106 OopMap* map = save_live_registers(sasm, 3); | 1102 OopMap* map = save_live_registers(sasm, 3); |
1107 // Retrieve bci | 1103 // Retrieve bci |
1108 __ movl(bci, Address(rbp, 2*BytesPerWord)); | 1104 __ movl(bci, Address(rbp, 2*BytesPerWord)); |
1109 // And a pointer to the methodOop | 1105 // And a pointer to the Method* |
1110 __ movptr(method, Address(rbp, 3*BytesPerWord)); | 1106 __ movptr(method, Address(rbp, 3*BytesPerWord)); |
1111 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); | 1107 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); |
1112 oop_maps = new OopMapSet(); | 1108 oop_maps = new OopMapSet(); |
1113 oop_maps->add_gc_map(call_offset, map); | 1109 oop_maps->add_gc_map(call_offset, map); |
1114 restore_live_registers(sasm); | 1110 restore_live_registers(sasm); |
1289 __ ret(0); | 1285 __ ret(0); |
1290 | 1286 |
1291 __ bind(register_finalizer); | 1287 __ bind(register_finalizer); |
1292 __ enter(); | 1288 __ enter(); |
1293 OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */); | 1289 OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */); |
1294 int call_offset = __ call_RT(noreg, noreg, | 1290 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax); |
1295 CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax); | |
1296 oop_maps = new OopMapSet(); | 1291 oop_maps = new OopMapSet(); |
1297 oop_maps->add_gc_map(call_offset, oop_map); | 1292 oop_maps->add_gc_map(call_offset, oop_map); |
1298 | 1293 |
1299 // Now restore all the live registers | 1294 // Now restore all the live registers |
1300 restore_live_registers(sasm); | 1295 restore_live_registers(sasm); |
1491 | 1486 |
1492 case load_klass_patching_id: | 1487 case load_klass_patching_id: |
1493 { StubFrame f(sasm, "load_klass_patching", dont_gc_arguments); | 1488 { StubFrame f(sasm, "load_klass_patching", dont_gc_arguments); |
1494 // we should set up register map | 1489 // we should set up register map |
1495 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); | 1490 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); |
1491 } | |
1492 break; | |
1493 | |
1494 case load_mirror_patching_id: | |
1495 { StubFrame f(sasm, "load_mirror_patching", dont_gc_arguments); | |
1496 // we should set up register map | |
1497 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); | |
1496 } | 1498 } |
1497 break; | 1499 break; |
1498 | 1500 |
1499 case dtrace_object_alloc_id: | 1501 case dtrace_object_alloc_id: |
1500 { // rax,: object | 1502 { // rax,: object |