Mercurial > hg > truffle
annotate src/share/vm/code/stubs.hpp @ 17716:cdb71841f4bc
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 | 55fb97c4c58d |
children | abec000618bf |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
8767
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 #ifndef SHARE_VM_CODE_STUBS_HPP |
26 #define SHARE_VM_CODE_STUBS_HPP | |
27 | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
28 #include "asm/codeBuffer.hpp" |
1972 | 29 #include "memory/allocation.hpp" |
30 #ifdef TARGET_OS_FAMILY_linux | |
31 # include "os_linux.inline.hpp" | |
32 #endif | |
33 #ifdef TARGET_OS_FAMILY_solaris | |
34 # include "os_solaris.inline.hpp" | |
35 #endif | |
36 #ifdef TARGET_OS_FAMILY_windows | |
37 # include "os_windows.inline.hpp" | |
38 #endif | |
3960 | 39 #ifdef TARGET_OS_FAMILY_bsd |
40 # include "os_bsd.inline.hpp" | |
41 #endif | |
1972 | 42 |
0 | 43 // The classes in this file provide a simple framework for the |
44 // management of little pieces of machine code - or stubs - | |
45 // created on the fly and frequently discarded. In this frame- | |
46 // work stubs are stored in a queue. | |
47 | |
48 | |
49 // Stub serves as abstract base class. A concrete stub | |
50 // implementation is a subclass of Stub, implementing | |
51 // all (non-virtual!) functions required sketched out | |
52 // in the Stub class. | |
53 // | |
54 // A concrete stub layout may look like this (both data | |
55 // and code sections could be empty as well): | |
56 // | |
57 // ________ | |
58 // stub -->| | <--+ | |
59 // | data | | | |
60 // |________| | | |
61 // code_begin -->| | | | |
62 // | | | | |
63 // | code | | size | |
64 // | | | | |
65 // |________| | | |
66 // code_end -->| | | | |
67 // | data | | | |
68 // |________| | | |
69 // <--+ | |
70 | |
71 | |
72 class Stub VALUE_OBJ_CLASS_SPEC { | |
73 public: | |
74 // Initialization/finalization | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
75 void initialize(int size, |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6842
diff
changeset
|
76 CodeStrings& strings) { ShouldNotCallThis(); } // called to initialize/specify the stub's size |
0 | 77 void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated |
78 | |
79 // General info/converters | |
80 int size() const { ShouldNotCallThis(); return 0; } // must return the size provided by initialize | |
81 static int code_size_to_size(int code_size) { ShouldNotCallThis(); return 0; } // computes the size given the code size | |
82 | |
83 // Code info | |
84 address code_begin() const { ShouldNotCallThis(); return NULL; } // points to the first byte of the code | |
85 address code_end() const { ShouldNotCallThis(); return NULL; } // points to the first byte after the code | |
86 | |
87 // Debugging | |
88 void verify() { ShouldNotCallThis(); } // verifies the Stub | |
89 void print() { ShouldNotCallThis(); } // prints some information about the stub | |
90 }; | |
91 | |
92 | |
93 // A stub interface defines the interface between a stub queue | |
94 // and the stubs it queues. In order to avoid a vtable and | |
95 // (and thus the extra word) in each stub, a concrete stub | |
96 // interface object is created and associated with a stub | |
97 // buffer which in turn uses the stub interface to interact | |
98 // with its stubs. | |
99 // | |
100 // StubInterface serves as an abstract base class. A concrete | |
101 // stub interface implementation is a subclass of StubInterface, | |
102 // forwarding its virtual function calls to non-virtual calls | |
103 // of the concrete stub (see also macro below). There's exactly | |
104 // one stub interface instance required per stub queue. | |
105 | |
6197 | 106 class StubInterface: public CHeapObj<mtCode> { |
0 | 107 public: |
108 // Initialization/finalization | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
109 virtual void initialize(Stub* self, int size, |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6842
diff
changeset
|
110 CodeStrings& strings) = 0; // called after creation (called twice if allocated via (request, commit)) |
0 | 111 virtual void finalize(Stub* self) = 0; // called before deallocation |
112 | |
113 // General info/converters | |
114 virtual int size(Stub* self) const = 0; // the total size of the stub in bytes (must be a multiple of CodeEntryAlignment) | |
115 virtual int code_size_to_size(int code_size) const = 0; // computes the total stub size in bytes given the code size in bytes | |
116 | |
117 // Code info | |
118 virtual address code_begin(Stub* self) const = 0; // points to the first code byte | |
119 virtual address code_end(Stub* self) const = 0; // points to the first byte after the code | |
120 | |
121 // Debugging | |
122 virtual void verify(Stub* self) = 0; // verifies the stub | |
123 virtual void print(Stub* self) = 0; // prints information about the stub | |
124 }; | |
125 | |
126 | |
127 // DEF_STUB_INTERFACE is used to create a concrete stub interface | |
128 // class, forwarding stub interface calls to the corresponding | |
129 // stub calls. | |
130 | |
131 #define DEF_STUB_INTERFACE(stub) \ | |
132 class stub##Interface: public StubInterface { \ | |
133 private: \ | |
134 static stub* cast(Stub* self) { return (stub*)self; } \ | |
135 \ | |
136 public: \ | |
137 /* Initialization/finalization */ \ | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
138 virtual void initialize(Stub* self, int size, \ |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6842
diff
changeset
|
139 CodeStrings& strings) { cast(self)->initialize(size, strings); } \ |
0 | 140 virtual void finalize(Stub* self) { cast(self)->finalize(); } \ |
141 \ | |
142 /* General info */ \ | |
143 virtual int size(Stub* self) const { return cast(self)->size(); } \ | |
144 virtual int code_size_to_size(int code_size) const { return stub::code_size_to_size(code_size); } \ | |
145 \ | |
146 /* Code info */ \ | |
147 virtual address code_begin(Stub* self) const { return cast(self)->code_begin(); } \ | |
148 virtual address code_end(Stub* self) const { return cast(self)->code_end(); } \ | |
149 \ | |
150 /* Debugging */ \ | |
151 virtual void verify(Stub* self) { cast(self)->verify(); } \ | |
152 virtual void print(Stub* self) { cast(self)->print(); } \ | |
153 }; | |
154 | |
155 | |
156 // A StubQueue maintains a queue of stubs. | |
157 // Note: All sizes (spaces) are given in bytes. | |
158 | |
6197 | 159 class StubQueue: public CHeapObj<mtCode> { |
0 | 160 friend class VMStructs; |
161 private: | |
162 StubInterface* _stub_interface; // the interface prototype | |
163 address _stub_buffer; // where all stubs are stored | |
164 int _buffer_size; // the buffer size in bytes | |
165 int _buffer_limit; // the (byte) index of the actual buffer limit (_buffer_limit <= _buffer_size) | |
166 int _queue_begin; // the (byte) index of the first queue entry (word-aligned) | |
167 int _queue_end; // the (byte) index of the first entry after the queue (word-aligned) | |
168 int _number_of_stubs; // the number of buffered stubs | |
169 Mutex* const _mutex; // the lock used for a (request, commit) transaction | |
170 | |
171 void check_index(int i) const { assert(0 <= i && i < _buffer_limit && i % CodeEntryAlignment == 0, "illegal index"); } | |
172 bool is_contiguous() const { return _queue_begin <= _queue_end; } | |
173 int index_of(Stub* s) const { int i = (address)s - _stub_buffer; check_index(i); return i; } | |
174 Stub* stub_at(int i) const { check_index(i); return (Stub*)(_stub_buffer + i); } | |
175 Stub* current_stub() const { return stub_at(_queue_end); } | |
176 | |
177 // Stub functionality accessed via interface | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
178 void stub_initialize(Stub* s, int size, |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6842
diff
changeset
|
179 CodeStrings& strings) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, strings); } |
0 | 180 void stub_finalize(Stub* s) { _stub_interface->finalize(s); } |
181 int stub_size(Stub* s) const { return _stub_interface->size(s); } | |
182 bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } | |
183 int stub_code_size_to_size(int code_size) const { return _stub_interface->code_size_to_size(code_size); } | |
184 void stub_verify(Stub* s) { _stub_interface->verify(s); } | |
185 void stub_print(Stub* s) { _stub_interface->print(s); } | |
186 | |
187 static void register_queue(StubQueue*); | |
188 | |
189 public: | |
190 StubQueue(StubInterface* stub_interface, int buffer_size, Mutex* lock, | |
191 const char* name); | |
192 ~StubQueue(); | |
193 | |
194 // General queue info | |
195 bool is_empty() const { return _queue_begin == _queue_end; } | |
196 int total_space() const { return _buffer_size - 1; } | |
197 int available_space() const { int d = _queue_begin - _queue_end - 1; return d < 0 ? d + _buffer_size : d; } | |
198 int used_space() const { return total_space() - available_space(); } | |
199 int number_of_stubs() const { return _number_of_stubs; } | |
200 bool contains(address pc) const { return _stub_buffer <= pc && pc < _stub_buffer + _buffer_limit; } | |
201 Stub* stub_containing(address pc) const; | |
202 address code_start() const { return _stub_buffer; } | |
203 address code_end() const { return _stub_buffer + _buffer_limit; } | |
204 | |
205 // Stub allocation (atomic transactions) | |
206 Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code | |
207 Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue | |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6197
diff
changeset
|
208 void commit (int committed_code_size, |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6842
diff
changeset
|
209 CodeStrings& strings); // commit the previously requested stub - unlocks the queue |
0 | 210 |
211 // Stub deallocation | |
212 void remove_first(); // remove the first stub in the queue | |
213 void remove_first(int n); // remove the first n stubs in the queue | |
214 void remove_all(); // remove all stubs in the queue | |
215 | |
216 // Iteration | |
217 static void queues_do(void f(StubQueue* s)); // call f with each StubQueue | |
218 void stubs_do(void f(Stub* s)); // call f with all stubs | |
219 Stub* first() const { return number_of_stubs() > 0 ? stub_at(_queue_begin) : NULL; } | |
220 Stub* next(Stub* s) const { int i = index_of(s) + stub_size(s); | |
221 if (i == _buffer_limit) i = 0; | |
222 return (i == _queue_end) ? NULL : stub_at(i); | |
223 } | |
224 | |
225 address stub_code_begin(Stub* s) const { return _stub_interface->code_begin(s); } | |
226 address stub_code_end(Stub* s) const { return _stub_interface->code_end(s); } | |
227 | |
228 // Debugging/printing | |
229 void verify(); // verifies the stub queue | |
230 void print(); // prints information about the stub queue | |
231 }; | |
1972 | 232 |
233 #endif // SHARE_VM_CODE_STUBS_HPP |