Mercurial > hg > graal-compiler
annotate src/share/vm/code/icBuffer.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | 1d1603768966 |
children | da91efe96a93 8c5333c80cfd |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2192
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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 "code/compiledIC.hpp" | |
27 #include "code/icBuffer.hpp" | |
28 #include "code/nmethod.hpp" | |
29 #include "code/scopeDesc.hpp" | |
30 #include "gc_interface/collectedHeap.inline.hpp" | |
31 #include "interpreter/interpreter.hpp" | |
32 #include "interpreter/linkResolver.hpp" | |
33 #include "memory/resourceArea.hpp" | |
34 #include "memory/universe.inline.hpp" | |
35 #include "oops/methodOop.hpp" | |
36 #include "oops/oop.inline.hpp" | |
37 #include "oops/oop.inline2.hpp" | |
38 #include "runtime/mutexLocker.hpp" | |
39 #include "runtime/stubRoutines.hpp" | |
40 #ifdef TARGET_ARCH_x86 | |
41 # include "assembler_x86.inline.hpp" | |
42 #endif | |
43 #ifdef TARGET_ARCH_sparc | |
44 # include "assembler_sparc.inline.hpp" | |
45 #endif | |
46 #ifdef TARGET_ARCH_zero | |
47 # include "assembler_zero.inline.hpp" | |
48 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
49 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
50 # include "assembler_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
51 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
52 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
53 # include "assembler_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
54 #endif |
0 | 55 |
56 | |
57 DEF_STUB_INTERFACE(ICStub); | |
58 | |
59 StubQueue* InlineCacheBuffer::_buffer = NULL; | |
60 ICStub* InlineCacheBuffer::_next_stub = NULL; | |
61 | |
62 | |
63 void ICStub::finalize() { | |
64 if (!is_empty()) { | |
65 ResourceMark rm; | |
66 CompiledIC *ic = CompiledIC_at(ic_site()); | |
67 assert(CodeCache::find_nmethod(ic->instruction_address()) != NULL, "inline cache in non-nmethod?"); | |
68 | |
69 assert(this == ICStub_from_destination_address(ic->stub_address()), "wrong owner of ic buffer"); | |
70 ic->set_cached_oop(cached_oop()); | |
71 ic->set_ic_destination(destination()); | |
72 } | |
73 } | |
74 | |
75 | |
76 address ICStub::destination() const { | |
77 return InlineCacheBuffer::ic_buffer_entry_point(code_begin()); | |
78 } | |
79 | |
80 oop ICStub::cached_oop() const { | |
81 return InlineCacheBuffer::ic_buffer_cached_oop(code_begin()); | |
82 } | |
83 | |
84 | |
85 void ICStub::set_stub(CompiledIC *ic, oop cached_value, address dest_addr) { | |
86 // We cannot store a pointer to the 'ic' object, since it is resource allocated. Instead we | |
87 // store the location of the inline cache. Then we have enough information recreate the CompiledIC | |
88 // object when we need to remove the stub. | |
89 _ic_site = ic->instruction_address(); | |
90 | |
91 // Assemble new stub | |
92 InlineCacheBuffer::assemble_ic_buffer_code(code_begin(), cached_value, dest_addr); | |
93 assert(destination() == dest_addr, "can recover destination"); | |
94 assert(cached_oop() == cached_value, "can recover destination"); | |
95 } | |
96 | |
97 | |
98 void ICStub::clear() { | |
99 _ic_site = NULL; | |
100 } | |
101 | |
102 | |
103 #ifndef PRODUCT | |
104 // anybody calling to this stub will trap | |
105 | |
106 void ICStub::verify() { | |
107 } | |
108 | |
109 void ICStub::print() { | |
110 tty->print_cr("ICStub: site: " INTPTR_FORMAT, _ic_site); | |
111 } | |
112 #endif | |
113 | |
114 //----------------------------------------------------------------------------------------------- | |
115 // Implementation of InlineCacheBuffer | |
116 | |
117 void InlineCacheBuffer::init_next_stub() { | |
118 ICStub* ic_stub = (ICStub*)buffer()->request_committed (ic_stub_code_size()); | |
119 assert (ic_stub != NULL, "no room for a single stub"); | |
120 set_next_stub(ic_stub); | |
121 } | |
122 | |
123 void InlineCacheBuffer::initialize() { | |
124 if (_buffer != NULL) return; // already initialized | |
125 _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer"); | |
126 assert (_buffer != NULL, "cannot allocate InlineCacheBuffer"); | |
127 init_next_stub(); | |
128 } | |
129 | |
130 | |
131 ICStub* InlineCacheBuffer::new_ic_stub() { | |
132 while (true) { | |
133 ICStub* ic_stub = (ICStub*)buffer()->request_committed(ic_stub_code_size()); | |
134 if (ic_stub != NULL) { | |
135 return ic_stub; | |
136 } | |
137 // we ran out of inline cache buffer space; must enter safepoint. | |
138 // We do this by forcing a safepoint | |
139 EXCEPTION_MARK; | |
140 | |
141 VM_ForceSafepoint vfs; | |
142 VMThread::execute(&vfs); | |
143 // We could potential get an async. exception at this point. | |
144 // In that case we will rethrow it to ourselvs. | |
145 if (HAS_PENDING_EXCEPTION) { | |
146 oop exception = PENDING_EXCEPTION; | |
147 CLEAR_PENDING_EXCEPTION; | |
148 Thread::send_async_exception(JavaThread::current()->threadObj(), exception); | |
149 } | |
150 } | |
151 ShouldNotReachHere(); | |
152 return NULL; | |
153 } | |
154 | |
155 | |
156 void InlineCacheBuffer::update_inline_caches() { | |
157 if (buffer()->number_of_stubs() > 1) { | |
158 if (TraceICBuffer) { | |
159 tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs()); | |
160 } | |
161 buffer()->remove_all(); | |
162 init_next_stub(); | |
163 } | |
164 } | |
165 | |
166 | |
167 bool InlineCacheBuffer::contains(address instruction_address) { | |
168 return buffer()->contains(instruction_address); | |
169 } | |
170 | |
171 | |
172 bool InlineCacheBuffer::is_empty() { | |
173 return buffer()->number_of_stubs() == 1; // always has sentinel | |
174 } | |
175 | |
176 | |
177 void InlineCacheBuffer_init() { | |
178 InlineCacheBuffer::initialize(); | |
179 } | |
180 | |
181 | |
182 void InlineCacheBuffer::create_transition_stub(CompiledIC *ic, oop cached_oop, address entry) { | |
183 assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint"); | |
184 assert (CompiledIC_lock->is_locked(), ""); | |
185 assert(cached_oop == NULL || cached_oop->is_perm(), "must belong to perm. space"); | |
186 if (TraceICBuffer) { tty->print_cr(" create transition stub for " INTPTR_FORMAT, ic->instruction_address()); } | |
187 | |
188 // If an transition stub is already associate with the inline cache, then we remove the association. | |
189 if (ic->is_in_transition_state()) { | |
190 ICStub* old_stub = ICStub_from_destination_address(ic->stub_address()); | |
191 old_stub->clear(); | |
192 } | |
193 | |
194 // allocate and initialize new "out-of-line" inline-cache | |
195 ICStub* ic_stub = get_next_stub(); | |
196 ic_stub->set_stub(ic, cached_oop, entry); | |
197 | |
198 // Update inline cache in nmethod to point to new "out-of-line" allocated inline cache | |
199 ic->set_ic_destination(ic_stub->code_begin()); | |
200 | |
201 set_next_stub(new_ic_stub()); // can cause safepoint synchronization | |
202 } | |
203 | |
204 | |
205 address InlineCacheBuffer::ic_destination_for(CompiledIC *ic) { | |
206 ICStub* stub = ICStub_from_destination_address(ic->stub_address()); | |
207 return stub->destination(); | |
208 } | |
209 | |
210 | |
211 oop InlineCacheBuffer::cached_oop_for(CompiledIC *ic) { | |
212 ICStub* stub = ICStub_from_destination_address(ic->stub_address()); | |
213 return stub->cached_oop(); | |
214 } |