Mercurial > hg > truffle
annotate src/share/vm/code/compiledIC.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 | 22ae97935e05 |
children | 02f27ecb4f3a 78bbf4d43a14 |
rev | line source |
---|---|
0 | 1 /* |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
2 * Copyright (c) 1997, 2013, 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:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "code/codeCache.hpp" | |
28 #include "code/compiledIC.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/nmethod.hpp" | |
31 #include "code/vtableStubs.hpp" | |
32 #include "interpreter/interpreter.hpp" | |
33 #include "interpreter/linkResolver.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
34 #include "memory/metadataFactory.hpp" |
1972 | 35 #include "memory/oopFactory.hpp" |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
36 #include "oops/method.hpp" |
1972 | 37 #include "oops/oop.inline.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
38 #include "oops/symbol.hpp" |
1972 | 39 #include "runtime/icache.hpp" |
40 #include "runtime/sharedRuntime.hpp" | |
41 #include "runtime/stubRoutines.hpp" | |
42 #include "utilities/events.hpp" | |
0 | 43 |
44 | |
45 // Every time a compiled IC is changed or its type is being accessed, | |
46 // either the CompiledIC_lock must be set or we must be at a safe point. | |
47 | |
48 //----------------------------------------------------------------------------- | |
49 // Low-level access to an inline cache. Private, since they might not be | |
50 // MT-safe to use. | |
51 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
52 void* CompiledIC::cached_value() const { |
0 | 53 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
54 assert (!is_optimized(), "an optimized virtual call does not have a cached metadata"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
55 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
56 if (!is_in_transition_state()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
57 void* data = (void*)_value->data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
58 // If we let the metadata value here be initialized to zero... |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
59 assert(data != NULL || Universe::non_oop_word() == NULL, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
60 "no raw nulls in CompiledIC metadatas, because of patching races"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
61 return (data == (void*)Universe::non_oop_word()) ? NULL : data; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
62 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
63 return InlineCacheBuffer::cached_value_for((CompiledIC *)this); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
64 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
65 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
66 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
67 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
68 void CompiledIC::internal_set_ic_destination(address entry_point, bool is_icstub, void* cache, bool is_icholder) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
69 assert(entry_point != NULL, "must set legal entry point"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
70 assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
71 assert (!is_optimized() || cache == NULL, "an optimized virtual call does not have a cached metadata"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
72 assert (cache == NULL || cache != (Metadata*)badOopVal, "invalid metadata"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
73 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
74 assert(!is_icholder || is_icholder_entry(entry_point), "must be"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
75 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
76 // Don't use ic_destination for this test since that forwards |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
77 // through ICBuffer instead of returning the actual current state of |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
78 // the CompiledIC. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
79 if (is_icholder_entry(_ic_call->destination())) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
80 // When patching for the ICStub case the cached value isn't |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
81 // overwritten until the ICStub copied into the CompiledIC during |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
82 // the next safepoint. Make sure that the CompiledICHolder* is |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
83 // marked for release at this point since it won't be identifiable |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
84 // once the entry point is overwritten. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
85 InlineCacheBuffer::queue_for_release((CompiledICHolder*)_value->data()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
86 } |
0 | 87 |
88 if (TraceCompiledIC) { | |
89 tty->print(" "); | |
90 print_compiled_ic(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
91 tty->print(" changing destination to " INTPTR_FORMAT, entry_point); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
92 if (!is_optimized()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
93 tty->print(" changing cached %s to " INTPTR_FORMAT, is_icholder ? "icholder" : "metadata", (address)cache); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
94 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
95 if (is_icstub) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
96 tty->print(" (icstub)"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
97 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
98 tty->cr(); |
0 | 99 } |
100 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
101 { |
0 | 102 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); |
103 #ifdef ASSERT | |
104 CodeBlob* cb = CodeCache::find_blob_unsafe(_ic_call); | |
105 assert(cb != NULL && cb->is_nmethod(), "must be nmethod"); | |
106 #endif | |
107 _ic_call->set_destination_mt_safe(entry_point); | |
108 } | |
109 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
110 if (is_optimized() || is_icstub) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
111 // Optimized call sites don't have a cache value and ICStub call |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
112 // sites only change the entry point. Changing the value in that |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
113 // case could lead to MT safety issues. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
114 assert(cache == NULL, "must be null"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
115 return; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
116 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
117 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
118 if (cache == NULL) cache = (void*)Universe::non_oop_word(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
119 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
120 _value->set_data((intptr_t)cache); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
121 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
122 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
123 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
124 void CompiledIC::set_ic_destination(ICStub* stub) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
125 internal_set_ic_destination(stub->code_begin(), true, NULL, false); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
126 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
127 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
128 |
0 | 129 |
130 address CompiledIC::ic_destination() const { | |
131 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
132 if (!is_in_transition_state()) { | |
133 return _ic_call->destination(); | |
134 } else { | |
135 return InlineCacheBuffer::ic_destination_for((CompiledIC *)this); | |
136 } | |
137 } | |
138 | |
139 | |
140 bool CompiledIC::is_in_transition_state() const { | |
141 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
142 return InlineCacheBuffer::contains(_ic_call->destination()); | |
143 } | |
144 | |
145 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
146 bool CompiledIC::is_icholder_call() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
147 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
148 return !_is_optimized && is_icholder_entry(ic_destination()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
149 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
150 |
0 | 151 // Returns native address of 'call' instruction in inline-cache. Used by |
152 // the InlineCacheBuffer when it needs to find the stub. | |
153 address CompiledIC::stub_address() const { | |
154 assert(is_in_transition_state(), "should only be called when we are in a transition state"); | |
155 return _ic_call->destination(); | |
156 } | |
157 | |
158 | |
159 //----------------------------------------------------------------------------- | |
160 // High-level access to an inline cache. Guaranteed to be MT-safe. | |
161 | |
162 | |
12294 | 163 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { |
0 | 164 assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
165 assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); | |
166 assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); | |
167 | |
168 address entry; | |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
169 if (call_info->call_kind() == CallInfo::itable_call) { |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
170 assert(bytecode == Bytecodes::_invokeinterface, ""); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
171 int itable_index = call_info->itable_index(); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
172 entry = VtableStubs::find_itable_stub(itable_index); |
12294 | 173 if (entry == false) { |
174 return false; | |
175 } | |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
176 #ifdef ASSERT |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
177 int index = call_info->resolved_method()->itable_index(); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
178 assert(index == itable_index, "CallInfo pre-computes this"); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
179 #endif //ASSERT |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
180 InstanceKlass* k = call_info->resolved_method()->method_holder(); |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
181 assert(k->verify_itable_index(itable_index), "sanity check"); |
0 | 182 InlineCacheBuffer::create_transition_stub(this, k, entry); |
183 } else { | |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
184 assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
185 // Can be different than selected_method->vtable_index(), due to package-private etc. |
0 | 186 int vtable_index = call_info->vtable_index(); |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
187 assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); |
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
188 entry = VtableStubs::find_vtable_stub(vtable_index); |
12294 | 189 if (entry == NULL) { |
190 return false; | |
191 } | |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
192 InlineCacheBuffer::create_transition_stub(this, NULL, entry); |
0 | 193 } |
194 | |
195 if (TraceICs) { | |
196 ResourceMark rm; | |
197 tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, | |
12264
b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
drchase
parents:
10168
diff
changeset
|
198 instruction_address(), call_info->selected_method()->print_value_string(), entry); |
0 | 199 } |
200 | |
201 // We can't check this anymore. With lazy deopt we could have already | |
202 // cleaned this IC entry before we even return. This is possible if | |
203 // we ran out of space in the inline cache buffer trying to do the | |
204 // set_next and we safepointed to free up space. This is a benign | |
205 // race because the IC entry was complete when we safepointed so | |
206 // cleaning it immediately is harmless. | |
207 // assert(is_megamorphic(), "sanity check"); | |
12294 | 208 return true; |
0 | 209 } |
210 | |
211 | |
212 // true if destination is megamorphic stub | |
213 bool CompiledIC::is_megamorphic() const { | |
214 assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
215 assert(!is_optimized(), "an optimized call cannot be megamorphic"); | |
216 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
217 // Cannot rely on cached_value. It is either an interface or a method. |
0 | 218 return VtableStubs::is_entry_point(ic_destination()); |
219 } | |
220 | |
221 bool CompiledIC::is_call_to_compiled() const { | |
222 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
223 | |
224 // Use unsafe, since an inline cache might point to a zombie method. However, the zombie | |
225 // method is guaranteed to still exist, since we only remove methods after all inline caches | |
226 // has been cleaned up | |
227 CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination()); | |
228 bool is_monomorphic = (cb != NULL && cb->is_nmethod()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
229 // Check that the cached_value is a klass for non-optimized monomorphic calls |
0 | 230 // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
231 // for calling directly to vep without using the inline cache (i.e., cached_value == NULL) |
0 | 232 #ifdef ASSERT |
233 CodeBlob* caller = CodeCache::find_blob_unsafe(instruction_address()); | |
234 bool is_c1_method = caller->is_compiled_by_c1(); | |
235 assert( is_c1_method || | |
236 !is_monomorphic || | |
237 is_optimized() || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
238 (cached_metadata() != NULL && cached_metadata()->is_klass()), "sanity check"); |
0 | 239 #endif // ASSERT |
240 return is_monomorphic; | |
241 } | |
242 | |
243 | |
244 bool CompiledIC::is_call_to_interpreted() const { | |
245 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
246 // Call to interpreter if destination is either calling to a stub (if it | |
247 // is optimized), or calling to an I2C blob | |
248 bool is_call_to_interpreted = false; | |
249 if (!is_optimized()) { | |
250 // must use unsafe because the destination can be a zombie (and we're cleaning) | |
251 // and the print_compiled_ic code wants to know if site (in the non-zombie) | |
252 // is to the interpreter. | |
253 CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination()); | |
254 is_call_to_interpreted = (cb != NULL && cb->is_adapter_blob()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
255 assert(!is_call_to_interpreted || (is_icholder_call() && cached_icholder() != NULL), "sanity check"); |
0 | 256 } else { |
257 // Check if we are calling into our own codeblob (i.e., to a stub) | |
258 CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); | |
259 address dest = ic_destination(); | |
260 #ifdef ASSERT | |
261 { | |
262 CodeBlob* db = CodeCache::find_blob_unsafe(dest); | |
263 assert(!db->is_adapter_blob(), "must use stub!"); | |
264 } | |
265 #endif /* ASSERT */ | |
266 is_call_to_interpreted = cb->contains(dest); | |
267 } | |
268 return is_call_to_interpreted; | |
269 } | |
270 | |
271 | |
272 void CompiledIC::set_to_clean() { | |
273 assert(SafepointSynchronize::is_at_safepoint() || CompiledIC_lock->is_locked() , "MT-unsafe call"); | |
274 if (TraceInlineCacheClearing || TraceICs) { | |
275 tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", instruction_address()); | |
276 print(); | |
277 } | |
278 | |
279 address entry; | |
280 if (is_optimized()) { | |
281 entry = SharedRuntime::get_resolve_opt_virtual_call_stub(); | |
282 } else { | |
283 entry = SharedRuntime::get_resolve_virtual_call_stub(); | |
284 } | |
285 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
286 // A zombie transition will always be safe, since the metadata has already been set to NULL, so |
0 | 287 // we only need to patch the destination |
288 bool safe_transition = is_optimized() || SafepointSynchronize::is_at_safepoint(); | |
289 | |
290 if (safe_transition) { | |
291 // Kill any leftover stub we might have too | |
292 if (is_in_transition_state()) { | |
293 ICStub* old_stub = ICStub_from_destination_address(stub_address()); | |
294 old_stub->clear(); | |
295 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
296 if (is_optimized()) { |
0 | 297 set_ic_destination(entry); |
298 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
299 set_ic_destination_and_value(entry, (void*)NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
300 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
301 } else { |
0 | 302 // Unsafe transition - create stub. |
303 InlineCacheBuffer::create_transition_stub(this, NULL, entry); | |
304 } | |
305 // We can't check this anymore. With lazy deopt we could have already | |
306 // cleaned this IC entry before we even return. This is possible if | |
307 // we ran out of space in the inline cache buffer trying to do the | |
308 // set_next and we safepointed to free up space. This is a benign | |
309 // race because the IC entry was complete when we safepointed so | |
310 // cleaning it immediately is harmless. | |
311 // assert(is_clean(), "sanity check"); | |
312 } | |
313 | |
314 | |
315 bool CompiledIC::is_clean() const { | |
316 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); | |
317 bool is_clean = false; | |
318 address dest = ic_destination(); | |
319 is_clean = dest == SharedRuntime::get_resolve_opt_virtual_call_stub() || | |
320 dest == SharedRuntime::get_resolve_virtual_call_stub(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
321 assert(!is_clean || is_optimized() || cached_value() == NULL, "sanity check"); |
0 | 322 return is_clean; |
323 } | |
324 | |
325 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
326 void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { |
0 | 327 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
328 // Updating a cache to the wrong entry can cause bugs that are very hard | |
329 // to track down - if cache entry gets invalid - we just clean it. In | |
330 // this way it is always the same code path that is responsible for | |
331 // updating and resolving an inline cache | |
332 // | |
333 // The above is no longer true. SharedRuntime::fixup_callers_callsite will change optimized | |
334 // callsites. In addition ic_miss code will update a site to monomorphic if it determines | |
335 // that an monomorphic call to the interpreter can now be monomorphic to compiled code. | |
336 // | |
337 // In both of these cases the only thing being modifed is the jump/call target and these | |
338 // transitions are mt_safe | |
339 | |
340 Thread *thread = Thread::current(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
341 if (info.to_interpreter()) { |
0 | 342 // Call to interpreter |
343 if (info.is_optimized() && is_optimized()) { | |
344 assert(is_clean(), "unsafe IC path"); | |
345 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
346 // the call analysis (callee structure) specifies that the call is optimized | |
347 // (either because of CHA or the static target is final) | |
348 // At code generation time, this call has been emitted as static call | |
349 // Call via stub | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
350 assert(info.cached_metadata() != NULL && info.cached_metadata()->is_method(), "sanity check"); |
0 | 351 CompiledStaticCall* csc = compiledStaticCall_at(instruction_address()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
352 methodHandle method (thread, (Method*)info.cached_metadata()); |
0 | 353 csc->set_to_interpreted(method, info.entry()); |
354 if (TraceICs) { | |
355 ResourceMark rm(thread); | |
356 tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter: %s", | |
357 instruction_address(), | |
358 method->print_value_string()); | |
359 } | |
360 } else { | |
361 // Call via method-klass-holder | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
362 InlineCacheBuffer::create_transition_stub(this, info.claim_cached_icholder(), info.entry()); |
0 | 363 if (TraceICs) { |
364 ResourceMark rm(thread); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
365 tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", instruction_address()); |
0 | 366 } |
367 } | |
368 } else { | |
369 // Call to compiled code | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
370 bool static_bound = info.is_optimized() || (info.cached_metadata() == NULL); |
0 | 371 #ifdef ASSERT |
372 CodeBlob* cb = CodeCache::find_blob_unsafe(info.entry()); | |
373 assert (cb->is_nmethod(), "must be compiled!"); | |
374 #endif /* ASSERT */ | |
375 | |
376 // This is MT safe if we come from a clean-cache and go through a | |
377 // non-verified entry point | |
378 bool safe = SafepointSynchronize::is_at_safepoint() || | |
379 (!is_in_transition_state() && (info.is_optimized() || static_bound || is_clean())); | |
380 | |
381 if (!safe) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
382 InlineCacheBuffer::create_transition_stub(this, info.cached_metadata(), info.entry()); |
0 | 383 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
384 if (is_optimized()) { |
0 | 385 set_ic_destination(info.entry()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
386 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
387 set_ic_destination_and_value(info.entry(), info.cached_metadata()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
388 } |
0 | 389 } |
390 | |
391 if (TraceICs) { | |
392 ResourceMark rm(thread); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
393 assert(info.cached_metadata() == NULL || info.cached_metadata()->is_klass(), "must be"); |
0 | 394 tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to compiled (rcvr klass) %s: %s", |
395 instruction_address(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
396 ((Klass*)info.cached_metadata())->print_value_string(), |
0 | 397 (safe) ? "" : "via stub"); |
398 } | |
399 } | |
400 // We can't check this anymore. With lazy deopt we could have already | |
401 // cleaned this IC entry before we even return. This is possible if | |
402 // we ran out of space in the inline cache buffer trying to do the | |
403 // set_next and we safepointed to free up space. This is a benign | |
404 // race because the IC entry was complete when we safepointed so | |
405 // cleaning it immediately is harmless. | |
406 // assert(is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); | |
407 } | |
408 | |
409 | |
410 // is_optimized: Compiler has generated an optimized call (i.e., no inline | |
411 // cache) static_bound: The call can be static bound (i.e, no need to use | |
412 // inline cache) | |
413 void CompiledIC::compute_monomorphic_entry(methodHandle method, | |
414 KlassHandle receiver_klass, | |
415 bool is_optimized, | |
416 bool static_bound, | |
417 CompiledICInfo& info, | |
418 TRAPS) { | |
419 nmethod* method_code = method->code(); | |
420 address entry = NULL; | |
14212 | 421 if (method_code != NULL && method_code->is_in_use()) { |
0 | 422 // Call to compiled code |
423 if (static_bound || is_optimized) { | |
424 entry = method_code->verified_entry_point(); | |
425 } else { | |
426 entry = method_code->entry_point(); | |
427 } | |
428 } | |
429 if (entry != NULL) { | |
430 // Call to compiled code | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
431 info.set_compiled_entry(entry, (static_bound || is_optimized) ? NULL : receiver_klass(), is_optimized); |
0 | 432 } else { |
433 // Note: the following problem exists with Compiler1: | |
434 // - at compile time we may or may not know if the destination is final | |
435 // - if we know that the destination is final, we will emit an optimized | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
436 // virtual call (no inline cache), and need a Method* to make a call |
0 | 437 // to the interpreter |
438 // - if we do not know if the destination is final, we emit a standard | |
439 // virtual call, and use CompiledICHolder to call interpreted code | |
440 // (no static call stub has been generated) | |
441 // However in that case we will now notice it is static_bound | |
442 // and convert the call into what looks to be an optimized | |
443 // virtual call. This causes problems in verifying the IC because | |
444 // it look vanilla but is optimized. Code in is_call_to_interpreted | |
445 // is aware of this and weakens its asserts. | |
446 | |
447 // static_bound should imply is_optimized -- otherwise we have a | |
448 // performance bug (statically-bindable method is called via | |
449 // dynamically-dispatched call note: the reverse implication isn't | |
450 // necessarily true -- the call may have been optimized based on compiler | |
451 // analysis (static_bound is only based on "final" etc.) | |
452 #ifdef COMPILER2 | |
453 #ifdef TIERED | |
454 #if defined(ASSERT) | |
455 // can't check the assert because we don't have the CompiledIC with which to | |
456 // find the address if the call instruction. | |
457 // | |
458 // CodeBlob* cb = find_blob_unsafe(instruction_address()); | |
459 // assert(cb->is_compiled_by_c1() || !static_bound || is_optimized, "static_bound should imply is_optimized"); | |
460 #endif // ASSERT | |
461 #else | |
462 assert(!static_bound || is_optimized, "static_bound should imply is_optimized"); | |
463 #endif // TIERED | |
464 #endif // COMPILER2 | |
465 if (is_optimized) { | |
466 // Use stub entry | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
467 info.set_interpreter_entry(method()->get_c2i_entry(), method()); |
0 | 468 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
469 // Use icholder entry |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
470 CompiledICHolder* holder = new CompiledICHolder(method(), receiver_klass()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
471 info.set_icholder_entry(method()->get_c2i_unverified_entry(), holder); |
0 | 472 } |
473 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
474 assert(info.is_optimized() == is_optimized, "must agree"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
475 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
476 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
477 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
478 bool CompiledIC::is_icholder_entry(address entry) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
479 CodeBlob* cb = CodeCache::find_blob_unsafe(entry); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
480 return (cb != NULL && cb->is_adapter_blob()); |
0 | 481 } |
482 | |
483 // ---------------------------------------------------------------------------- | |
484 | |
485 void CompiledStaticCall::set_to_clean() { | |
486 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call"); | |
487 // Reset call site | |
488 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
489 #ifdef ASSERT | |
490 CodeBlob* cb = CodeCache::find_blob_unsafe(this); | |
491 assert(cb != NULL && cb->is_nmethod(), "must be nmethod"); | |
492 #endif | |
493 set_destination_mt_safe(SharedRuntime::get_resolve_static_call_stub()); | |
494 | |
495 // Do not reset stub here: It is too expensive to call find_stub. | |
496 // Instead, rely on caller (nmethod::clear_inline_caches) to clear | |
497 // both the call and its stub. | |
498 } | |
499 | |
500 | |
501 bool CompiledStaticCall::is_clean() const { | |
502 return destination() == SharedRuntime::get_resolve_static_call_stub(); | |
503 } | |
504 | |
505 bool CompiledStaticCall::is_call_to_compiled() const { | |
506 return CodeCache::contains(destination()); | |
507 } | |
508 | |
509 | |
510 bool CompiledStaticCall::is_call_to_interpreted() const { | |
511 // It is a call to interpreted, if it calls to a stub. Hence, the destination | |
512 // must be in the stub part of the nmethod that contains the call | |
513 nmethod* nm = CodeCache::find_nmethod(instruction_address()); | |
514 return nm->stub_contains(destination()); | |
515 } | |
516 | |
517 void CompiledStaticCall::set(const StaticCallInfo& info) { | |
518 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call"); | |
519 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
520 // Updating a cache to the wrong entry can cause bugs that are very hard | |
521 // to track down - if cache entry gets invalid - we just clean it. In | |
522 // this way it is always the same code path that is responsible for | |
523 // updating and resolving an inline cache | |
524 assert(is_clean(), "do not update a call entry - use clean"); | |
525 | |
526 if (info._to_interpreter) { | |
527 // Call to interpreted code | |
528 set_to_interpreted(info.callee(), info.entry()); | |
529 } else { | |
530 if (TraceICs) { | |
531 ResourceMark rm; | |
532 tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_compiled " INTPTR_FORMAT, | |
533 instruction_address(), | |
534 info.entry()); | |
535 } | |
536 // Call to compiled code | |
537 assert (CodeCache::contains(info.entry()), "wrong entry point"); | |
538 set_destination_mt_safe(info.entry()); | |
539 } | |
540 } | |
541 | |
542 | |
543 // Compute settings for a CompiledStaticCall. Since we might have to set | |
544 // the stub when calling to the interpreter, we need to return arguments. | |
545 void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info) { | |
546 nmethod* m_code = m->code(); | |
547 info._callee = m; | |
14212 | 548 if (m_code != NULL && m_code->is_in_use()) { |
0 | 549 info._to_interpreter = false; |
550 info._entry = m_code->verified_entry_point(); | |
551 } else { | |
552 // Callee is interpreted code. In any case entering the interpreter | |
553 // puts a converter-frame on the stack to save arguments. | |
554 info._to_interpreter = true; | |
555 info._entry = m()->get_c2i_entry(); | |
556 } | |
557 } | |
558 | |
559 address CompiledStaticCall::find_stub() { | |
560 // Find reloc. information containing this call-site | |
561 RelocIterator iter((nmethod*)NULL, instruction_address()); | |
562 while (iter.next()) { | |
563 if (iter.addr() == instruction_address()) { | |
564 switch(iter.type()) { | |
565 case relocInfo::static_call_type: | |
566 return iter.static_call_reloc()->static_stub(); | |
567 // We check here for opt_virtual_call_type, since we reuse the code | |
568 // from the CompiledIC implementation | |
569 case relocInfo::opt_virtual_call_type: | |
570 return iter.opt_virtual_call_reloc()->static_stub(); | |
571 case relocInfo::poll_type: | |
572 case relocInfo::poll_return_type: // A safepoint can't overlap a call. | |
573 default: | |
574 ShouldNotReachHere(); | |
575 } | |
576 } | |
577 } | |
578 return NULL; | |
579 } | |
580 | |
581 | |
582 //----------------------------------------------------------------------------- | |
583 // Non-product mode code | |
584 #ifndef PRODUCT | |
585 | |
586 void CompiledIC::verify() { | |
587 // make sure code pattern is actually a call imm32 instruction | |
588 _ic_call->verify(); | |
589 if (os::is_MP()) { | |
590 _ic_call->verify_alignment(); | |
591 } | |
592 assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() | |
593 || is_optimized() || is_megamorphic(), "sanity check"); | |
594 } | |
595 | |
596 void CompiledIC::print() { | |
597 print_compiled_ic(); | |
598 tty->cr(); | |
599 } | |
600 | |
601 void CompiledIC::print_compiled_ic() { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
602 tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4872
diff
changeset
|
603 instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination(), is_optimized() ? NULL : cached_value()); |
0 | 604 } |
605 | |
606 void CompiledStaticCall::print() { | |
607 tty->print("static call at " INTPTR_FORMAT " -> ", instruction_address()); | |
608 if (is_clean()) { | |
609 tty->print("clean"); | |
610 } else if (is_call_to_compiled()) { | |
611 tty->print("compiled"); | |
612 } else if (is_call_to_interpreted()) { | |
613 tty->print("interpreted"); | |
614 } | |
615 tty->cr(); | |
616 } | |
617 | |
10168
a6e09d6dd8e5
8003853: specify offset of IC load in java_to_interp stub
dlong
parents:
8776
diff
changeset
|
618 #endif // !PRODUCT |