Mercurial > hg > truffle
annotate src/share/vm/shark/sharkFunction.cpp @ 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 | 4ca6dc0799b6 |
rev | line source |
---|---|
1692 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
7600
diff
changeset
|
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
1692 | 3 * Copyright 2008, 2009 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
27 #include "ci/ciTypeFlow.hpp" | |
28 #include "memory/allocation.hpp" | |
29 #include "shark/llvmHeaders.hpp" | |
30 #include "shark/llvmValue.hpp" | |
31 #include "shark/sharkBuilder.hpp" | |
32 #include "shark/sharkEntry.hpp" | |
33 #include "shark/sharkFunction.hpp" | |
34 #include "shark/sharkState.hpp" | |
35 #include "shark/sharkTopLevelBlock.hpp" | |
36 #include "shark/shark_globals.hpp" | |
37 #include "utilities/debug.hpp" | |
1692 | 38 |
39 using namespace llvm; | |
40 | |
41 void SharkFunction::initialize(const char *name) { | |
42 // Create the function | |
43 _function = Function::Create( | |
44 entry_point_type(), | |
45 GlobalVariable::InternalLinkage, | |
46 name); | |
47 | |
48 // Get our arguments | |
49 Function::arg_iterator ai = function()->arg_begin(); | |
50 Argument *method = ai++; | |
51 method->setName("method"); | |
52 Argument *osr_buf = NULL; | |
53 if (is_osr()) { | |
54 osr_buf = ai++; | |
55 osr_buf->setName("osr_buf"); | |
56 } | |
57 Argument *base_pc = ai++; | |
58 base_pc->setName("base_pc"); | |
59 code_buffer()->set_base_pc(base_pc); | |
60 Argument *thread = ai++; | |
61 thread->setName("thread"); | |
62 set_thread(thread); | |
63 | |
64 // Create the list of blocks | |
65 set_block_insertion_point(NULL); | |
66 _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count()); | |
67 for (int i = 0; i < block_count(); i++) { | |
68 ciTypeFlow::Block *b = flow()->pre_order_at(i); | |
69 | |
70 // Work around a bug in pre_order_at() that does not return | |
71 // the correct pre-ordering. If pre_order_at() were correct | |
72 // this line could simply be: | |
73 // _blocks[i] = new SharkTopLevelBlock(this, b); | |
74 _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b); | |
75 } | |
76 | |
77 // Walk the tree from the start block to determine which | |
78 // blocks are entered and which blocks require phis | |
79 SharkTopLevelBlock *start_block = block(flow()->start_block_num()); | |
7600
c095a7f289aa
8005818: Shark: fix OSR for non-empty incoming stack
twisti
parents:
1972
diff
changeset
|
80 if (is_osr() && start_block->stack_depth_at_entry() != 0) { |
c095a7f289aa
8005818: Shark: fix OSR for non-empty incoming stack
twisti
parents:
1972
diff
changeset
|
81 env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0"); |
c095a7f289aa
8005818: Shark: fix OSR for non-empty incoming stack
twisti
parents:
1972
diff
changeset
|
82 return; |
c095a7f289aa
8005818: Shark: fix OSR for non-empty incoming stack
twisti
parents:
1972
diff
changeset
|
83 } |
1692 | 84 assert(start_block->start() == flow()->start_bci(), "blocks out of order"); |
85 start_block->enter(); | |
86 | |
87 // Initialize all entered blocks | |
88 for (int i = 0; i < block_count(); i++) { | |
89 if (block(i)->entered()) | |
90 block(i)->initialize(); | |
91 } | |
92 | |
93 // Create and push our stack frame | |
94 set_block_insertion_point(&function()->front()); | |
95 builder()->SetInsertPoint(CreateBlock()); | |
96 _stack = SharkStack::CreateBuildAndPushFrame(this, method); | |
97 | |
98 // Create the entry state | |
99 SharkState *entry_state; | |
100 if (is_osr()) { | |
101 entry_state = new SharkOSREntryState(start_block, method, osr_buf); | |
102 | |
103 // Free the OSR buffer | |
104 builder()->CreateCall(builder()->osr_migration_end(), osr_buf); | |
105 } | |
106 else { | |
107 entry_state = new SharkNormalEntryState(start_block, method); | |
108 | |
109 // Lock if necessary | |
110 if (is_synchronized()) { | |
111 SharkTopLevelBlock *locker = | |
112 new SharkTopLevelBlock(this, start_block->ciblock()); | |
113 locker->add_incoming(entry_state); | |
114 | |
115 set_block_insertion_point(start_block->entry_block()); | |
116 locker->acquire_method_lock(); | |
117 | |
118 entry_state = locker->current_state(); | |
119 } | |
120 } | |
121 | |
122 // Transition into the method proper | |
123 start_block->add_incoming(entry_state); | |
124 builder()->CreateBr(start_block->entry_block()); | |
125 | |
126 // Parse the blocks | |
127 for (int i = 0; i < block_count(); i++) { | |
128 if (!block(i)->entered()) | |
129 continue; | |
130 | |
131 if (i + 1 < block_count()) | |
132 set_block_insertion_point(block(i + 1)->entry_block()); | |
133 else | |
134 set_block_insertion_point(NULL); | |
135 | |
136 block(i)->emit_IR(); | |
137 } | |
138 do_deferred_zero_checks(); | |
139 } | |
140 | |
141 class DeferredZeroCheck : public SharkTargetInvariants { | |
142 public: | |
143 DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value) | |
144 : SharkTargetInvariants(block), | |
145 _block(block), | |
146 _value(value), | |
147 _bci(block->bci()), | |
148 _state(block->current_state()->copy()), | |
149 _check_block(builder()->GetInsertBlock()), | |
150 _continue_block(function()->CreateBlock("not_zero")) { | |
151 builder()->SetInsertPoint(continue_block()); | |
152 } | |
153 | |
154 private: | |
155 SharkTopLevelBlock* _block; | |
156 SharkValue* _value; | |
157 int _bci; | |
158 SharkState* _state; | |
159 BasicBlock* _check_block; | |
160 BasicBlock* _continue_block; | |
161 | |
162 public: | |
163 SharkTopLevelBlock* block() const { | |
164 return _block; | |
165 } | |
166 SharkValue* value() const { | |
167 return _value; | |
168 } | |
169 int bci() const { | |
170 return _bci; | |
171 } | |
172 SharkState* state() const { | |
173 return _state; | |
174 } | |
175 BasicBlock* check_block() const { | |
176 return _check_block; | |
177 } | |
178 BasicBlock* continue_block() const { | |
179 return _continue_block; | |
180 } | |
181 | |
182 public: | |
183 SharkFunction* function() const { | |
184 return block()->function(); | |
185 } | |
186 | |
187 public: | |
188 void process() const { | |
189 builder()->SetInsertPoint(check_block()); | |
190 block()->do_deferred_zero_check(value(), bci(), state(), continue_block()); | |
191 } | |
192 }; | |
193 | |
194 void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block, | |
195 SharkValue* value) { | |
196 deferred_zero_checks()->append(new DeferredZeroCheck(block, value)); | |
197 } | |
198 | |
199 void SharkFunction::do_deferred_zero_checks() { | |
200 for (int i = 0; i < deferred_zero_checks()->length(); i++) | |
201 deferred_zero_checks()->at(i)->process(); | |
202 } |