vtableStubs_x86_32.cpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "asm/assembler.hpp"
27#include "assembler_x86.inline.hpp"
28#include "code/vtableStubs.hpp"
29#include "interp_masm_x86_32.hpp"
30#include "memory/resourceArea.hpp"
31#include "oops/instanceKlass.hpp"
32#include "oops/klassVtable.hpp"
33#include "runtime/sharedRuntime.hpp"
34#include "vmreg_x86.inline.hpp"
35#ifdef COMPILER2
36#include "opto/runtime.hpp"
37#endif
38
39// machine-dependent part of VtableStubs: create VtableStub of correct size and
40// initialize its code
41
42#define __ masm->
43
44#ifndef PRODUCT
45extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index);
46#endif
47
48// These stubs are used by the compiler only.
49// Argument registers, which must be preserved:
50//   rcx - receiver (always first argument)
51//   rdx - second argument (if any)
52// Other registers that might be usable:
53//   rax - inline cache register (is interface for itable stub)
54//   rbx - method (used when calling out to interpreter)
55// Available now, but may become callee-save at some point:
56//   rsi, rdi
57// Note that rax and rdx are also used for return values.
58//
59VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
60  const int i486_code_length = VtableStub::pd_code_size_limit(true);
61  VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index);
62  ResourceMark rm;
63  CodeBuffer cb(s->entry_point(), i486_code_length);
64  MacroAssembler* masm = new MacroAssembler(&cb);
65
66#ifndef PRODUCT
67
68  if (CountCompiledCalls) {
69    __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
70  }
71#endif /* PRODUCT */
72
73  // get receiver (need to skip return address on top of stack)
74  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
75
76  // get receiver klass
77  address npe_addr = __ pc();
78  __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
79
80#ifndef PRODUCT
81  if (DebugVtables) {
82    Label L;
83    // check offset vs vtable length
84    __ cmpl(Address(rax, InstanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size());
85    __ jcc(Assembler::greater, L);
86    __ movl(rbx, vtable_index);
87    __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx);
88    __ bind(L);
89  }
90#endif // PRODUCT
91
92  const Register method = rbx;
93
94  // load Method* and target address
95  __ lookup_virtual_method(rax, vtable_index, method);
96
97  if (DebugVtables) {
98    Label L;
99    __ cmpptr(method, (int32_t)NULL_WORD);
100    __ jcc(Assembler::equal, L);
101    __ cmpptr(Address(method, Method::from_compiled_offset()), (int32_t)NULL_WORD);
102    __ jcc(Assembler::notZero, L);
103    __ stop("Vtable entry is NULL");
104    __ bind(L);
105  }
106
107  // rax,: receiver klass
108  // method (rbx): Method*
109  // rcx: receiver
110  address ame_addr = __ pc();
111  __ jmp( Address(method, Method::from_compiled_offset()));
112
113  masm->flush();
114
115  if (PrintMiscellaneous && (WizardMode || Verbose)) {
116    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
117                  vtable_index, s->entry_point(),
118                  (int)(s->code_end() - s->entry_point()),
119                  (int)(s->code_end() - __ pc()));
120  }
121  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
122  // shut the door on sizing bugs
123  int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
124  assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
125
126  s->set_exception_points(npe_addr, ame_addr);
127  return s;
128}
129
130
131VtableStub* VtableStubs::create_itable_stub(int itable_index) {
132  // Note well: pd_code_size_limit is the absolute minimum we can get away with.  If you
133  //            add code here, bump the code stub size returned by pd_code_size_limit!
134  const int i486_code_length = VtableStub::pd_code_size_limit(false);
135  VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
136  ResourceMark rm;
137  CodeBuffer cb(s->entry_point(), i486_code_length);
138  MacroAssembler* masm = new MacroAssembler(&cb);
139
140  // Entry arguments:
141  //  rax,: Interface
142  //  rcx: Receiver
143
144#ifndef PRODUCT
145  if (CountCompiledCalls) {
146    __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
147  }
148#endif /* PRODUCT */
149  // get receiver (need to skip return address on top of stack)
150
151  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
152
153  // get receiver klass (also an implicit null-check)
154  address npe_addr = __ pc();
155  __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
156
157  // Most registers are in use; we'll use rax, rbx, rsi, rdi
158  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
159  const Register method = rbx;
160  Label throw_icce;
161
162  // Get Method* and entrypoint for compiler
163  __ lookup_interface_method(// inputs: rec. class, interface, itable index
164                             rsi, rax, itable_index,
165                             // outputs: method, scan temp. reg
166                             method, rdi,
167                             throw_icce);
168
169  // method (rbx): Method*
170  // rcx: receiver
171
172#ifdef ASSERT
173  if (DebugVtables) {
174      Label L1;
175      __ cmpptr(method, (int32_t)NULL_WORD);
176      __ jcc(Assembler::equal, L1);
177      __ cmpptr(Address(method, Method::from_compiled_offset()), (int32_t)NULL_WORD);
178      __ jcc(Assembler::notZero, L1);
179      __ stop("Method* is null");
180      __ bind(L1);
181    }
182#endif // ASSERT
183
184  address ame_addr = __ pc();
185  __ jmp(Address(method, Method::from_compiled_offset()));
186
187  __ bind(throw_icce);
188  __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
189  masm->flush();
190
191  if (PrintMiscellaneous && (WizardMode || Verbose)) {
192    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
193                  itable_index, s->entry_point(),
194                  (int)(s->code_end() - s->entry_point()),
195                  (int)(s->code_end() - __ pc()));
196  }
197  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
198  // shut the door on sizing bugs
199  int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
200  assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
201
202  s->set_exception_points(npe_addr, ame_addr);
203  return s;
204}
205
206
207
208int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
209  if (is_vtable_stub) {
210    // Vtable stub size
211    return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
212  } else {
213    // Itable stub size
214    return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
215  }
216  // In order to tune these parameters, run the JVM with VM options
217  // +PrintMiscellaneous and +WizardMode to see information about
218  // actual itable stubs.  Look for lines like this:
219  //   itable #1 at 0x5551212[65] left over: 3
220  // Reduce the constants so that the "left over" number is >=3
221  // for the common cases.
222  // Do not aim at a left-over number of zero, because a
223  // large vtable or itable index (> 16) will require a 32-bit
224  // immediate displacement instead of an 8-bit one.
225  //
226  // The JVM98 app. _202_jess has a megamorphic interface call.
227  // The itable code looks like this:
228  // Decoding VtableStub itbl[1]@1
229  //   mov    0x4(%ecx),%esi
230  //   mov    0xe8(%esi),%edi
231  //   lea    0x130(%esi,%edi,4),%edi
232  //   add    $0x7,%edi
233  //   and    $0xfffffff8,%edi
234  //   lea    0x4(%esi),%esi
235  //   mov    (%edi),%ebx
236  //   cmp    %ebx,%eax
237  //   je     success
238  // loop:
239  //   test   %ebx,%ebx
240  //   je     throw_icce
241  //   add    $0x8,%edi
242  //   mov    (%edi),%ebx
243  //   cmp    %ebx,%eax
244  //   jne    loop
245  // success:
246  //   mov    0x4(%edi),%edi
247  //   mov    (%esi,%edi,1),%ebx
248  //   jmp    *0x44(%ebx)
249  // throw_icce:
250  //   jmp    throw_ICCE_entry
251}
252
253int VtableStub::pd_code_alignment() {
254  return wordSize;
255}
256