Mercurial > hg > truffle
annotate src/share/vm/interpreter/rewriter.cpp @ 14649:f6301b007a16
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 26c3b944dc35 |
children | d8041d695d19 |
rev | line source |
---|---|
0 | 1 /* |
14333
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/bytecodes.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "interpreter/rewriter.hpp" | |
29 #include "memory/gcLocker.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "oops/generateOopMap.hpp" | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
32 #include "prims/methodHandles.hpp" |
0 | 33 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
34 // Computes a CPC map (new_index -> original_index) for constant pool entries |
0 | 35 // that are referred to by the interpreter at runtime via the constant pool cache. |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
36 // Also computes a CP map (original_index -> new_index). |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
37 // Marks entries in CP which require additional processing. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
38 void Rewriter::compute_index_maps() { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
39 const int length = _pool->length(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
40 init_maps(length); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
41 bool saw_mh_symbol = false; |
0 | 42 for (int i = 0; i < length; i++) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
43 int tag = _pool->tag_at(i).value(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
44 switch (tag) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
45 case JVM_CONSTANT_InterfaceMethodref: |
0 | 46 case JVM_CONSTANT_Fieldref : // fall through |
47 case JVM_CONSTANT_Methodref : // fall through | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
48 add_cp_cache_entry(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
49 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
50 case JVM_CONSTANT_String: |
1602 | 51 case JVM_CONSTANT_MethodHandle : // fall through |
52 case JVM_CONSTANT_MethodType : // fall through | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
53 add_resolved_references_entry(i); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
54 break; |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
55 case JVM_CONSTANT_Utf8: |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
56 if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle()) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
57 saw_mh_symbol = true; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
58 break; |
0 | 59 } |
60 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
61 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
62 // Record limits of resolved reference map for constant pool cache indices |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
63 record_map_limits(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
64 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
65 guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1), |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
66 "all cp cache indexes fit in a u2"); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
67 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
68 if (saw_mh_symbol) |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
69 _method_handle_invokers.initialize(length, (int)0); |
0 | 70 } |
71 | |
3748 | 72 // Unrewrite the bytecodes if an error occurs. |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
73 void Rewriter::restore_bytecodes() { |
3748 | 74 int len = _methods->length(); |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
75 bool invokespecial_error = false; |
3748 | 76 |
77 for (int i = len-1; i >= 0; i--) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
78 Method* method = _methods->at(i); |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
79 scan_method(method, true, &invokespecial_error); |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
80 assert(!invokespecial_error, "reversing should not get an invokespecial error"); |
3748 | 81 } |
82 } | |
0 | 83 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
84 // Creates a constant pool cache given a CPC map |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
85 void Rewriter::make_constant_pool_cache(TRAPS) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
86 ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
87 ConstantPoolCache* cache = |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
88 ConstantPoolCache::allocate(loader_data, _cp_cache_map, |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
89 _invokedynamic_cp_cache_map, |
8712
3efdfd6ddbf2
8003553: NPG: metaspace objects should be zeroed in constructors
coleenp
parents:
8104
diff
changeset
|
90 _invokedynamic_references_map, CHECK); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
91 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
92 // initialize object cache in constant pool |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
93 _pool->initialize_resolved_references(loader_data, _resolved_references_map, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
94 _resolved_reference_limit, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
95 CHECK); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
96 _pool->set_cache(cache); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
97 cache->set_constant_pool(_pool()); |
0 | 98 } |
99 | |
100 | |
101 | |
102 // The new finalization semantics says that registration of | |
103 // finalizable objects must be performed on successful return from the | |
104 // Object.<init> constructor. We could implement this trivially if | |
105 // <init> were never rewritten but since JVMTI allows this to occur, a | |
106 // more complicated solution is required. A special return bytecode | |
107 // is used only by Object.<init> to signal the finalization | |
108 // registration point. Additionally local 0 must be preserved so it's | |
109 // available to pass to the registration function. For simplicty we | |
110 // require that local 0 is never overwritten so it's available as an | |
111 // argument for registration. | |
112 | |
113 void Rewriter::rewrite_Object_init(methodHandle method, TRAPS) { | |
114 RawBytecodeStream bcs(method); | |
115 while (!bcs.is_last_bytecode()) { | |
116 Bytecodes::Code opcode = bcs.raw_next(); | |
117 switch (opcode) { | |
118 case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break; | |
119 | |
120 case Bytecodes::_istore: | |
121 case Bytecodes::_lstore: | |
122 case Bytecodes::_fstore: | |
123 case Bytecodes::_dstore: | |
124 case Bytecodes::_astore: | |
125 if (bcs.get_index() != 0) continue; | |
126 | |
127 // fall through | |
128 case Bytecodes::_istore_0: | |
129 case Bytecodes::_lstore_0: | |
130 case Bytecodes::_fstore_0: | |
131 case Bytecodes::_dstore_0: | |
132 case Bytecodes::_astore_0: | |
133 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), | |
134 "can't overwrite local 0 in Object.<init>"); | |
135 break; | |
136 } | |
137 } | |
138 } | |
139 | |
140 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
141 // Rewrite a classfile-order CP index into a native-order CPC index. |
3748 | 142 void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
143 address p = bcp + offset; |
3748 | 144 if (!reverse) { |
145 int cp_index = Bytes::get_Java_u2(p); | |
146 int cache_index = cp_entry_to_cp_cache(cp_index); | |
147 Bytes::put_native_u2(p, cache_index); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
148 if (!_method_handle_invokers.is_empty()) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
149 maybe_rewrite_invokehandle(p - 1, cp_index, cache_index, reverse); |
3748 | 150 } else { |
151 int cache_index = Bytes::get_native_u2(p); | |
152 int pool_index = cp_cache_entry_pool_index(cache_index); | |
153 Bytes::put_Java_u2(p, pool_index); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
154 if (!_method_handle_invokers.is_empty()) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
155 maybe_rewrite_invokehandle(p - 1, pool_index, cache_index, reverse); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
156 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
157 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
158 |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
159 // If the constant pool entry for invokespecial is InterfaceMethodref, |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
160 // we need to add a separate cpCache entry for its resolution, because it is |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
161 // different than the resolution for invokeinterface with InterfaceMethodref. |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
162 // These cannot share cpCache entries. It's unclear if all invokespecial to |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
163 // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
164 // is created for each one. This was added with lambda. |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
165 void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) { |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
166 address p = bcp + offset; |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
167 if (!reverse) { |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
168 int cp_index = Bytes::get_Java_u2(p); |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
169 if (_pool->tag_at(cp_index).is_interface_method()) { |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
170 int cache_index = add_invokespecial_cp_cache_entry(cp_index); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
171 if (cache_index != (int)(jushort) cache_index) { |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
172 *invokespecial_error = true; |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
173 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
174 Bytes::put_native_u2(p, cache_index); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
175 } else { |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
176 rewrite_member_reference(bcp, offset, reverse); |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
177 } |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
178 } else { |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
179 rewrite_member_reference(bcp, offset, reverse); |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
180 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
181 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
182 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
183 |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
184 // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
185 void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
186 if (!reverse) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
187 if ((*opc) == (u1)Bytecodes::_invokevirtual || |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
188 // allow invokespecial as an alias, although it would be very odd: |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
189 (*opc) == (u1)Bytecodes::_invokespecial) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
190 assert(_pool->tag_at(cp_index).is_method(), "wrong index"); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
191 // Determine whether this is a signature-polymorphic method. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
192 if (cp_index >= _method_handle_invokers.length()) return; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
193 int status = _method_handle_invokers[cp_index]; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
194 assert(status >= -1 && status <= 1, "oob tri-state"); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
195 if (status == 0) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
196 if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() && |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
197 MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
198 _pool->name_ref_at(cp_index))) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
199 // we may need a resolved_refs entry for the appendix |
6822
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
200 add_invokedynamic_resolved_references_entries(cp_index, cache_index); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
201 status = +1; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
202 } else { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
203 status = -1; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
204 } |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
205 _method_handle_invokers[cp_index] = status; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
206 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
207 // We use a special internal bytecode for such methods (if non-static). |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
208 // The basic reason for this is that such methods need an extra "appendix" argument |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
209 // to transmit the call site's intended call type. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
210 if (status > 0) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
211 (*opc) = (u1)Bytecodes::_invokehandle; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
212 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
213 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
214 } else { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
215 // Do not need to look at cp_index. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
216 if ((*opc) == (u1)Bytecodes::_invokehandle) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
217 (*opc) = (u1)Bytecodes::_invokevirtual; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
218 // Ignore corner case of original _invokespecial instruction. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
219 // This is safe because (a) the signature polymorphic method was final, and |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
220 // (b) the implementation of MethodHandle will not call invokespecial on it. |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
221 } |
3748 | 222 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
223 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
224 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
225 |
3748 | 226 void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
227 address p = bcp + offset; |
3748 | 228 assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode"); |
229 if (!reverse) { | |
230 int cp_index = Bytes::get_Java_u2(p); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
231 int cache_index = add_invokedynamic_cp_cache_entry(cp_index); |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
232 int resolved_index = add_invokedynamic_resolved_references_entries(cp_index, cache_index); |
3748 | 233 // Replace the trailing four bytes with a CPC index for the dynamic |
234 // call site. Unlike other CPC entries, there is one per bytecode, | |
235 // not just one per distinct CP entry. In other words, the | |
236 // CPC-to-CP relation is many-to-one for invokedynamic entries. | |
237 // This means we must use a larger index size than u2 to address | |
238 // all these entries. That is the main reason invokedynamic | |
239 // must have a five-byte instruction format. (Of course, other JVM | |
240 // implementations can use the bytes for other purposes.) | |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
241 // Note: We use native_u4 format exclusively for 4-byte indexes. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
242 Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index)); |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
243 // add the bcp in case we need to patch this bytecode if we also find a |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
244 // invokespecial/InterfaceMethodref in the bytecode stream |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
245 _patch_invokedynamic_bcps->push(p); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
246 _patch_invokedynamic_refs->push(resolved_index); |
3748 | 247 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
248 int cache_index = ConstantPool::decode_invokedynamic_index( |
3748 | 249 Bytes::get_native_u4(p)); |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
250 // We will reverse the bytecode rewriting _after_ adjusting them. |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
251 // Adjust the cache index by offset to the invokedynamic entries in the |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
252 // cpCache plus the delta if the invokedynamic bytecodes were adjusted. |
14333
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
253 int adjustment = cp_cache_delta() + _first_iteration_cp_cache_limit; |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
254 int cp_index = invokedynamic_cp_cache_entry_pool_index(cache_index - adjustment); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
255 assert(_pool->tag_at(cp_index).is_invoke_dynamic(), "wrong index"); |
3748 | 256 // zero out 4 bytes |
257 Bytes::put_Java_u4(p, 0); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
258 Bytes::put_Java_u2(p, cp_index); |
3748 | 259 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
260 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
261 |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
262 void Rewriter::patch_invokedynamic_bytecodes() { |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
263 // If the end of the cp_cache is the same as after initializing with the |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
264 // cpool, nothing needs to be done. Invokedynamic bytecodes are at the |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
265 // correct offsets. ie. no invokespecials added |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
266 int delta = cp_cache_delta(); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
267 if (delta > 0) { |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
268 int length = _patch_invokedynamic_bcps->length(); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
269 assert(length == _patch_invokedynamic_refs->length(), |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
270 "lengths should match"); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
271 for (int i = 0; i < length; i++) { |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
272 address p = _patch_invokedynamic_bcps->at(i); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
273 int cache_index = ConstantPool::decode_invokedynamic_index( |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
274 Bytes::get_native_u4(p)); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
275 Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index + delta)); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
276 |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
277 // invokedynamic resolved references map also points to cp cache and must |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
278 // add delta to each. |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
279 int resolved_index = _patch_invokedynamic_refs->at(i); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
280 for (int entry = 0; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) { |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
281 assert(_invokedynamic_references_map[resolved_index+entry] == cache_index, |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
282 "should be the same index"); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
283 _invokedynamic_references_map.at_put(resolved_index+entry, |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
284 cache_index + delta); |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
285 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
286 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
287 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
288 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
289 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
290 |
1602 | 291 // Rewrite some ldc bytecodes to _fast_aldc |
3748 | 292 void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide, |
293 bool reverse) { | |
294 if (!reverse) { | |
295 assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), "not ldc bytecode"); | |
296 address p = bcp + offset; | |
297 int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p); | |
298 constantTag tag = _pool->tag_at(cp_index).value(); | |
8104 | 299 if (tag.is_method_handle() || tag.is_method_type() || tag.is_string()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
300 int ref_index = cp_entry_to_resolved_references(cp_index); |
3748 | 301 if (is_wide) { |
302 (*bcp) = Bytecodes::_fast_aldc_w; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
303 assert(ref_index == (u2)ref_index, "index overflow"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
304 Bytes::put_native_u2(p, ref_index); |
3748 | 305 } else { |
306 (*bcp) = Bytecodes::_fast_aldc; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
307 assert(ref_index == (u1)ref_index, "index overflow"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
308 (*p) = (u1)ref_index; |
3748 | 309 } |
310 } | |
311 } else { | |
312 Bytecodes::Code rewritten_bc = | |
313 (is_wide ? Bytecodes::_fast_aldc_w : Bytecodes::_fast_aldc); | |
314 if ((*bcp) == rewritten_bc) { | |
315 address p = bcp + offset; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
316 int ref_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
317 int pool_index = resolved_references_entry_to_pool_index(ref_index); |
3748 | 318 if (is_wide) { |
319 (*bcp) = Bytecodes::_ldc_w; | |
320 assert(pool_index == (u2)pool_index, "index overflow"); | |
321 Bytes::put_Java_u2(p, pool_index); | |
322 } else { | |
323 (*bcp) = Bytecodes::_ldc; | |
324 assert(pool_index == (u1)pool_index, "index overflow"); | |
325 (*p) = (u1)pool_index; | |
326 } | |
1602 | 327 } |
328 } | |
329 } | |
330 | |
331 | |
0 | 332 // Rewrites a method given the index_map information |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
333 void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_error) { |
0 | 334 |
335 int nof_jsrs = 0; | |
336 bool has_monitor_bytecodes = false; | |
337 | |
338 { | |
339 // We cannot tolerate a GC in this block, because we've | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
340 // cached the bytecodes in 'code_base'. If the Method* |
0 | 341 // moves, the bytecodes will also move. |
342 No_Safepoint_Verifier nsv; | |
343 Bytecodes::Code c; | |
344 | |
345 // Bytecodes and their length | |
346 const address code_base = method->code_base(); | |
347 const int code_length = method->code_size(); | |
348 | |
349 int bc_length; | |
350 for (int bci = 0; bci < code_length; bci += bc_length) { | |
351 address bcp = code_base + bci; | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
352 int prefix_length = 0; |
0 | 353 c = (Bytecodes::Code)(*bcp); |
354 | |
355 // Since we have the code, see if we can get the length | |
356 // directly. Some more complicated bytecodes will report | |
357 // a length of zero, meaning we need to make another method | |
358 // call to calculate the length. | |
359 bc_length = Bytecodes::length_for(c); | |
360 if (bc_length == 0) { | |
2142 | 361 bc_length = Bytecodes::length_at(method, bcp); |
0 | 362 |
363 // length_at will put us at the bytecode after the one modified | |
364 // by 'wide'. We don't currently examine any of the bytecodes | |
365 // modified by wide, but in case we do in the future... | |
366 if (c == Bytecodes::_wide) { | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
367 prefix_length = 1; |
0 | 368 c = (Bytecodes::Code)bcp[1]; |
369 } | |
370 } | |
371 | |
372 assert(bc_length != 0, "impossible bytecode length"); | |
373 | |
374 switch (c) { | |
375 case Bytecodes::_lookupswitch : { | |
376 #ifndef CC_INTERP | |
2142 | 377 Bytecode_lookupswitch bc(method, bcp); |
1565 | 378 (*bcp) = ( |
2142 | 379 bc.number_of_pairs() < BinarySwitchThreshold |
0 | 380 ? Bytecodes::_fast_linearswitch |
381 : Bytecodes::_fast_binaryswitch | |
382 ); | |
383 #endif | |
384 break; | |
385 } | |
3748 | 386 case Bytecodes::_fast_linearswitch: |
387 case Bytecodes::_fast_binaryswitch: { | |
388 #ifndef CC_INTERP | |
389 (*bcp) = Bytecodes::_lookupswitch; | |
390 #endif | |
391 break; | |
392 } | |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
393 |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
394 case Bytecodes::_invokespecial : { |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
395 rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error); |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
396 break; |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
397 } |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
398 |
0 | 399 case Bytecodes::_getstatic : // fall through |
400 case Bytecodes::_putstatic : // fall through | |
401 case Bytecodes::_getfield : // fall through | |
402 case Bytecodes::_putfield : // fall through | |
403 case Bytecodes::_invokevirtual : // fall through | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
404 case Bytecodes::_invokestatic : |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
405 case Bytecodes::_invokeinterface: |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
406 case Bytecodes::_invokehandle : // if reverse=true |
3748 | 407 rewrite_member_reference(bcp, prefix_length+1, reverse); |
0 | 408 break; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
409 case Bytecodes::_invokedynamic: |
3748 | 410 rewrite_invokedynamic(bcp, prefix_length+1, reverse); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
411 break; |
1602 | 412 case Bytecodes::_ldc: |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
413 case Bytecodes::_fast_aldc: // if reverse=true |
3748 | 414 maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse); |
1602 | 415 break; |
416 case Bytecodes::_ldc_w: | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3748
diff
changeset
|
417 case Bytecodes::_fast_aldc_w: // if reverse=true |
3748 | 418 maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse); |
1602 | 419 break; |
0 | 420 case Bytecodes::_jsr : // fall through |
421 case Bytecodes::_jsr_w : nof_jsrs++; break; | |
422 case Bytecodes::_monitorenter : // fall through | |
423 case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break; | |
424 } | |
425 } | |
426 } | |
427 | |
428 // Update access flags | |
429 if (has_monitor_bytecodes) { | |
430 method->set_has_monitor_bytecodes(); | |
431 } | |
432 | |
433 // The present of a jsr bytecode implies that the method might potentially | |
434 // have to be rewritten, so we run the oopMapGenerator on the method | |
435 if (nof_jsrs > 0) { | |
436 method->set_has_jsrs(); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
437 // Second pass will revisit this method. |
3748 | 438 assert(method->has_jsrs(), "didn't we just set this?"); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
439 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
440 } |
0 | 441 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
442 // After constant pool is created, revisit methods containing jsrs. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
443 methodHandle Rewriter::rewrite_jsrs(methodHandle method, TRAPS) { |
3748 | 444 ResourceMark rm(THREAD); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
445 ResolveOopMapConflicts romc(method); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
446 methodHandle original_method = method; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
447 method = romc.do_potential_rewrite(CHECK_(methodHandle())); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
448 // Update monitor matching info. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
449 if (romc.monitor_safe()) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
450 method->set_guaranteed_monitor_matching(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
451 } |
0 | 452 |
453 return method; | |
454 } | |
455 | |
14333
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
456 void Rewriter::rewrite_bytecodes(TRAPS) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
457 assert(_pool->cache() == NULL, "constant pool cache must not be set yet"); |
0 | 458 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
459 // determine index maps for Method* rewriting |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
460 compute_index_maps(); |
0 | 461 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
462 if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) { |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
463 bool did_rewrite = false; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
464 int i = _methods->length(); |
0 | 465 while (i-- > 0) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
466 Method* method = _methods->at(i); |
0 | 467 if (method->intrinsic_id() == vmIntrinsics::_Object_init) { |
468 // rewrite the return bytecodes of Object.<init> to register the | |
469 // object for finalization if needed. | |
470 methodHandle m(THREAD, method); | |
471 rewrite_Object_init(m, CHECK); | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
472 did_rewrite = true; |
0 | 473 break; |
474 } | |
475 } | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
476 assert(did_rewrite, "must find Object::<init> to rewrite it"); |
0 | 477 } |
478 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
479 // rewrite methods, in two passes |
3748 | 480 int len = _methods->length(); |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
481 bool invokespecial_error = false; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
482 |
3748 | 483 for (int i = len-1; i >= 0; i--) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
484 Method* method = _methods->at(i); |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
485 scan_method(method, false, &invokespecial_error); |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
486 if (invokespecial_error) { |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
487 // If you get an error here, there is no reversing bytecodes |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
488 // This exception is stored for this class and no further attempt is |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
489 // made at verifying or rewriting. |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
490 THROW_MSG(vmSymbols::java_lang_InternalError(), |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
491 "This classfile overflows invokespecial for interfaces " |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
492 "and cannot be loaded"); |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
493 return; |
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
494 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
495 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
496 |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
497 // May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
498 // entries had to be added. |
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
499 patch_invokedynamic_bytecodes(); |
14333
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
500 } |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
501 |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
502 void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
503 ResourceMark rm(THREAD); |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
504 Rewriter rw(klass, klass->constants(), klass->methods(), CHECK); |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
505 // (That's all, folks.) |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
506 } |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
507 |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
508 |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
509 Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
510 : _klass(klass), |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
511 _pool(cpool), |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
512 _methods(methods) |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
513 { |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
514 |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
515 // Rewrite bytecodes - exception here exits. |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
516 rewrite_bytecodes(CHECK); |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
517 |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
518 // Stress restoring bytecodes |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
519 if (StressRewriter) { |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
520 restore_bytecodes(); |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
521 rewrite_bytecodes(CHECK); |
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
522 } |
13056
41cb10cbfb3c
8025937: assert(existing_f1 == NULL || existing_f1 == f1) failed: illegal field change
coleenp
parents:
8712
diff
changeset
|
523 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
524 // allocate constant pool cache, now that we've seen all the bytecodes |
3748 | 525 make_constant_pool_cache(THREAD); |
526 | |
527 // Restore bytecodes to their unrewritten state if there are exceptions | |
528 // rewriting bytecodes or allocating the cpCache | |
529 if (HAS_PENDING_EXCEPTION) { | |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
530 restore_bytecodes(); |
3748 | 531 return; |
532 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
533 |
7459
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
534 // Relocate after everything, but still do this under the is_rewritten flag, |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
535 // so methods with jsrs in custom class lists in aren't attempted to be |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
536 // rewritten in the RO section of the shared archive. |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
537 // Relocated bytecodes don't have to be restored, only the cp cache entries |
14333
26c3b944dc35
8033528: assert(0 <= i && i < length()) failed: index out of bounds
coleenp
parents:
13390
diff
changeset
|
538 int len = _methods->length(); |
3748 | 539 for (int i = len-1; i >= 0; i--) { |
7459
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
540 methodHandle m(THREAD, _methods->at(i)); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
541 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
542 if (m->has_jsrs()) { |
7459
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
543 m = rewrite_jsrs(m, THREAD); |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
544 // Restore bytecodes to their unrewritten state if there are exceptions |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
545 // relocating bytecodes. If some are relocated, that is ok because that |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
546 // doesn't affect constant pool to cpCache rewriting. |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
547 if (HAS_PENDING_EXCEPTION) { |
13390
d61a1a166f44
8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
coleenp
parents:
13056
diff
changeset
|
548 restore_bytecodes(); |
7459
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
549 return; |
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
6822
diff
changeset
|
550 } |
0 | 551 // Method might have gotten rewritten. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
552 methods->at_put(i, m()); |
0 | 553 } |
554 } | |
555 } |