Mercurial > hg > truffle
comparison src/cpu/x86/vm/vtableStubs_x86_32.cpp @ 304:dc7f315e41f7
5108146: Merge i486 and amd64 cpu directories
6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up
Reviewed-by: kvn
author | never |
---|---|
date | Wed, 27 Aug 2008 00:21:55 -0700 |
parents | f8236e79048a |
children | 9ee9cf798b59 |
comparison
equal
deleted
inserted
replaced
303:fa4d1d240383 | 304:dc7f315e41f7 |
---|---|
47 MacroAssembler* masm = new MacroAssembler(&cb); | 47 MacroAssembler* masm = new MacroAssembler(&cb); |
48 | 48 |
49 #ifndef PRODUCT | 49 #ifndef PRODUCT |
50 | 50 |
51 if (CountCompiledCalls) { | 51 if (CountCompiledCalls) { |
52 __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); | 52 __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); |
53 } | 53 } |
54 #endif /* PRODUCT */ | 54 #endif /* PRODUCT */ |
55 | 55 |
56 // get receiver (need to skip return address on top of stack) | 56 // get receiver (need to skip return address on top of stack) |
57 assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx"); | 57 assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx"); |
58 | 58 |
59 // get receiver klass | 59 // get receiver klass |
60 address npe_addr = __ pc(); | 60 address npe_addr = __ pc(); |
61 __ movl(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); | 61 __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); |
62 // compute entry offset (in words) | 62 // compute entry offset (in words) |
63 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); | 63 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); |
64 #ifndef PRODUCT | 64 #ifndef PRODUCT |
65 if (DebugVtables) { | 65 if (DebugVtables) { |
66 Label L; | 66 Label L; |
74 #endif // PRODUCT | 74 #endif // PRODUCT |
75 | 75 |
76 const Register method = rbx; | 76 const Register method = rbx; |
77 | 77 |
78 // load methodOop and target address | 78 // load methodOop and target address |
79 __ movl(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); | 79 __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes())); |
80 if (DebugVtables) { | 80 if (DebugVtables) { |
81 Label L; | 81 Label L; |
82 __ cmpl(method, NULL_WORD); | 82 __ cmpptr(method, (int32_t)NULL_WORD); |
83 __ jcc(Assembler::equal, L); | 83 __ jcc(Assembler::equal, L); |
84 __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); | 84 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
85 __ jcc(Assembler::notZero, L); | 85 __ jcc(Assembler::notZero, L); |
86 __ stop("Vtable entry is NULL"); | 86 __ stop("Vtable entry is NULL"); |
87 __ bind(L); | 87 __ bind(L); |
88 } | 88 } |
89 | 89 |
112 // rax,: Interface | 112 // rax,: Interface |
113 // rcx: Receiver | 113 // rcx: Receiver |
114 | 114 |
115 #ifndef PRODUCT | 115 #ifndef PRODUCT |
116 if (CountCompiledCalls) { | 116 if (CountCompiledCalls) { |
117 __ increment(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); | 117 __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); |
118 } | 118 } |
119 #endif /* PRODUCT */ | 119 #endif /* PRODUCT */ |
120 // get receiver (need to skip return address on top of stack) | 120 // get receiver (need to skip return address on top of stack) |
121 | 121 |
122 assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx"); | 122 assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx"); |
123 | 123 |
124 // get receiver klass (also an implicit null-check) | 124 // get receiver klass (also an implicit null-check) |
125 address npe_addr = __ pc(); | 125 address npe_addr = __ pc(); |
126 __ movl(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); | 126 __ movptr(rbx, Address(rcx, oopDesc::klass_offset_in_bytes())); |
127 | 127 |
128 __ movl(rsi, rbx); // Save klass in free register | 128 __ mov(rsi, rbx); // Save klass in free register |
129 // Most registers are in use, so save a few | 129 // Most registers are in use, so save a few |
130 __ pushl(rdx); | 130 __ push(rdx); |
131 // compute itable entry offset (in words) | 131 // compute itable entry offset (in words) |
132 const int base = instanceKlass::vtable_start_offset() * wordSize; | 132 const int base = instanceKlass::vtable_start_offset() * wordSize; |
133 assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); | 133 assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below"); |
134 __ movl(rdx, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable | 134 __ movl(rdx, Address(rbx, instanceKlass::vtable_length_offset() * wordSize)); // Get length of vtable |
135 __ leal(rbx, Address(rbx, rdx, Address::times_4, base)); | 135 __ lea(rbx, Address(rbx, rdx, Address::times_ptr, base)); |
136 if (HeapWordsPerLong > 1) { | 136 if (HeapWordsPerLong > 1) { |
137 // Round up to align_object_offset boundary | 137 // Round up to align_object_offset boundary |
138 __ round_to(rbx, BytesPerLong); | 138 __ round_to(rbx, BytesPerLong); |
139 } | 139 } |
140 | 140 |
141 Label hit, next, entry, throw_icce; | 141 Label hit, next, entry, throw_icce; |
142 | 142 |
143 __ jmpb(entry); | 143 __ jmpb(entry); |
144 | 144 |
145 __ bind(next); | 145 __ bind(next); |
146 __ addl(rbx, itableOffsetEntry::size() * wordSize); | 146 __ addptr(rbx, itableOffsetEntry::size() * wordSize); |
147 | 147 |
148 __ bind(entry); | 148 __ bind(entry); |
149 | 149 |
150 // If the entry is NULL then we've reached the end of the table | 150 // If the entry is NULL then we've reached the end of the table |
151 // without finding the expected interface, so throw an exception | 151 // without finding the expected interface, so throw an exception |
152 __ movl(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); | 152 __ movptr(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); |
153 __ testl(rdx, rdx); | 153 __ testptr(rdx, rdx); |
154 __ jcc(Assembler::zero, throw_icce); | 154 __ jcc(Assembler::zero, throw_icce); |
155 __ cmpl(rax, rdx); | 155 __ cmpptr(rax, rdx); |
156 __ jcc(Assembler::notEqual, next); | 156 __ jcc(Assembler::notEqual, next); |
157 | 157 |
158 // We found a hit, move offset into rbx, | 158 // We found a hit, move offset into rbx, |
159 __ movl(rdx, Address(rbx, itableOffsetEntry::offset_offset_in_bytes())); | 159 __ movl(rdx, Address(rbx, itableOffsetEntry::offset_offset_in_bytes())); |
160 | 160 |
161 // Compute itableMethodEntry. | 161 // Compute itableMethodEntry. |
162 const int method_offset = (itableMethodEntry::size() * wordSize * vtable_index) + itableMethodEntry::method_offset_in_bytes(); | 162 const int method_offset = (itableMethodEntry::size() * wordSize * vtable_index) + itableMethodEntry::method_offset_in_bytes(); |
163 | 163 |
164 // Get methodOop and entrypoint for compiler | 164 // Get methodOop and entrypoint for compiler |
165 const Register method = rbx; | 165 const Register method = rbx; |
166 __ movl(method, Address(rsi, rdx, Address::times_1, method_offset)); | 166 __ movptr(method, Address(rsi, rdx, Address::times_1, method_offset)); |
167 | 167 |
168 // Restore saved register, before possible trap. | 168 // Restore saved register, before possible trap. |
169 __ popl(rdx); | 169 __ pop(rdx); |
170 | 170 |
171 // method (rbx): methodOop | 171 // method (rbx): methodOop |
172 // rcx: receiver | 172 // rcx: receiver |
173 | 173 |
174 #ifdef ASSERT | 174 #ifdef ASSERT |
175 if (DebugVtables) { | 175 if (DebugVtables) { |
176 Label L1; | 176 Label L1; |
177 __ cmpl(method, NULL_WORD); | 177 __ cmpptr(method, (int32_t)NULL_WORD); |
178 __ jcc(Assembler::equal, L1); | 178 __ jcc(Assembler::equal, L1); |
179 __ cmpl(Address(method, methodOopDesc::from_compiled_offset()), NULL_WORD); | 179 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
180 __ jcc(Assembler::notZero, L1); | 180 __ jcc(Assembler::notZero, L1); |
181 __ stop("methodOop is null"); | 181 __ stop("methodOop is null"); |
182 __ bind(L1); | 182 __ bind(L1); |
183 } | 183 } |
184 #endif // ASSERT | 184 #endif // ASSERT |
186 address ame_addr = __ pc(); | 186 address ame_addr = __ pc(); |
187 __ jmp(Address(method, methodOopDesc::from_compiled_offset())); | 187 __ jmp(Address(method, methodOopDesc::from_compiled_offset())); |
188 | 188 |
189 __ bind(throw_icce); | 189 __ bind(throw_icce); |
190 // Restore saved register | 190 // Restore saved register |
191 __ popl(rdx); | 191 __ pop(rdx); |
192 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); | 192 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
193 | 193 |
194 masm->flush(); | 194 masm->flush(); |
195 | 195 |
196 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); | 196 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); |