Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
7ba5bd69
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7ba5bd69
编写于
7月 19, 2013
作者:
M
morris
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
90e550d0
c09dfc63
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
368 addition
and
67 deletion
+368
-67
src/cpu/x86/vm/stubGenerator_x86_64.cpp
src/cpu/x86/vm/stubGenerator_x86_64.cpp
+29
-5
src/cpu/x86/vm/stubRoutines_x86_64.cpp
src/cpu/x86/vm/stubRoutines_x86_64.cpp
+0
-1
src/cpu/x86/vm/stubRoutines_x86_64.hpp
src/cpu/x86/vm/stubRoutines_x86_64.hpp
+0
-6
src/share/vm/ci/bcEscapeAnalyzer.cpp
src/share/vm/ci/bcEscapeAnalyzer.cpp
+15
-0
src/share/vm/ci/bcEscapeAnalyzer.hpp
src/share/vm/ci/bcEscapeAnalyzer.hpp
+1
-0
src/share/vm/opto/matcher.cpp
src/share/vm/opto/matcher.cpp
+35
-36
src/share/vm/opto/parse3.cpp
src/share/vm/opto/parse3.cpp
+1
-19
test/compiler/EscapeAnalysis/Test8020215.java
test/compiler/EscapeAnalysis/Test8020215.java
+82
-0
test/compiler/cpuflags/RestoreMXCSR.java
test/compiler/cpuflags/RestoreMXCSR.java
+42
-0
test/compiler/membars/DekkerTest.java
test/compiler/membars/DekkerTest.java
+163
-0
未找到文件。
src/cpu/x86/vm/stubGenerator_x86_64.cpp
浏览文件 @
7ba5bd69
...
...
@@ -279,7 +279,7 @@ class StubGenerator: public StubCodeGenerator {
__
stmxcsr
(
mxcsr_save
);
__
movl
(
rax
,
mxcsr_save
);
__
andl
(
rax
,
MXCSR_MASK
);
// Only check control and mask bits
ExternalAddress
mxcsr_std
(
StubRoutines
::
x86
::
mxcsr_std
());
ExternalAddress
mxcsr_std
(
StubRoutines
::
addr_
mxcsr_std
());
__
cmp32
(
rax
,
mxcsr_std
);
__
jcc
(
Assembler
::
equal
,
skip_ldmx
);
__
ldmxcsr
(
mxcsr_std
);
...
...
@@ -729,17 +729,18 @@ class StubGenerator: public StubCodeGenerator {
if
(
CheckJNICalls
)
{
Label
ok_ret
;
ExternalAddress
mxcsr_std
(
StubRoutines
::
addr_mxcsr_std
());
__
push
(
rax
);
__
subptr
(
rsp
,
wordSize
);
// allocate a temp location
__
stmxcsr
(
mxcsr_save
);
__
movl
(
rax
,
mxcsr_save
);
__
andl
(
rax
,
MXCSR_MASK
);
// Only check control and mask bits
__
cmp
l
(
rax
,
*
(
int
*
)(
StubRoutines
::
x86
::
mxcsr_std
())
);
__
cmp
32
(
rax
,
mxcsr_std
);
__
jcc
(
Assembler
::
equal
,
ok_ret
);
__
warn
(
"MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"
);
__
ldmxcsr
(
ExternalAddress
(
StubRoutines
::
x86
::
mxcsr_std
())
);
__
ldmxcsr
(
mxcsr_std
);
__
bind
(
ok_ret
);
__
addptr
(
rsp
,
wordSize
);
...
...
@@ -3767,12 +3768,35 @@ class StubGenerator: public StubCodeGenerator {
return
stub
->
entry_point
();
}
void
create_control_words
()
{
// Round to nearest, 53-bit mode, exceptions masked
StubRoutines
::
_fpu_cntrl_wrd_std
=
0x027F
;
// Round to zero, 53-bit mode, exception mased
StubRoutines
::
_fpu_cntrl_wrd_trunc
=
0x0D7F
;
// Round to nearest, 24-bit mode, exceptions masked
StubRoutines
::
_fpu_cntrl_wrd_24
=
0x007F
;
// Round to nearest, 64-bit mode, exceptions masked
StubRoutines
::
_fpu_cntrl_wrd_64
=
0x037F
;
// Round to nearest, 64-bit mode, exceptions masked
StubRoutines
::
_mxcsr_std
=
0x1F80
;
// Note: the following two constants are 80-bit values
// layout is critical for correct loading by FPU.
// Bias for strict fp multiply/divide
StubRoutines
::
_fpu_subnormal_bias1
[
0
]
=
0x00000000
;
// 2^(-15360) == 0x03ff 8000 0000 0000 0000
StubRoutines
::
_fpu_subnormal_bias1
[
1
]
=
0x80000000
;
StubRoutines
::
_fpu_subnormal_bias1
[
2
]
=
0x03ff
;
// Un-Bias for strict fp multiply/divide
StubRoutines
::
_fpu_subnormal_bias2
[
0
]
=
0x00000000
;
// 2^(+15360) == 0x7bff 8000 0000 0000 0000
StubRoutines
::
_fpu_subnormal_bias2
[
1
]
=
0x80000000
;
StubRoutines
::
_fpu_subnormal_bias2
[
2
]
=
0x7bff
;
}
// Initialization
void
generate_initial
()
{
// Generates all stubs and initializes the entry points
// This platform-specific s
tub is
needed by generate_call_stub()
StubRoutines
::
x86
::
_mxcsr_std
=
generate_fp_mask
(
"mxcsr_std"
,
0x0000000000001F80
);
// This platform-specific s
ettings are
needed by generate_call_stub()
create_control_words
(
);
// entry points that exist in all platforms Note: This is code
// that could be shared among different platforms - however the
...
...
src/cpu/x86/vm/stubRoutines_x86_64.cpp
浏览文件 @
7ba5bd69
...
...
@@ -42,4 +42,3 @@ address StubRoutines::x86::_float_sign_mask = NULL;
address
StubRoutines
::
x86
::
_float_sign_flip
=
NULL
;
address
StubRoutines
::
x86
::
_double_sign_mask
=
NULL
;
address
StubRoutines
::
x86
::
_double_sign_flip
=
NULL
;
address
StubRoutines
::
x86
::
_mxcsr_std
=
NULL
;
src/cpu/x86/vm/stubRoutines_x86_64.hpp
浏览文件 @
7ba5bd69
...
...
@@ -52,7 +52,6 @@ class x86 {
static
address
_float_sign_flip
;
static
address
_double_sign_mask
;
static
address
_double_sign_flip
;
static
address
_mxcsr_std
;
public:
...
...
@@ -106,11 +105,6 @@ class x86 {
return
_double_sign_flip
;
}
static
address
mxcsr_std
()
{
return
_mxcsr_std
;
}
# include "stubRoutines_x86.hpp"
};
...
...
src/share/vm/ci/bcEscapeAnalyzer.cpp
浏览文件 @
7ba5bd69
...
...
@@ -138,6 +138,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
return
false
;
}
// return true if all argument elements of vars are returned
bool
BCEscapeAnalyzer
::
returns_all
(
ArgumentMap
vars
)
{
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
vars
.
contains
(
i
)
&&
!
_arg_returned
.
test
(
i
))
{
return
false
;
}
}
return
true
;
}
void
BCEscapeAnalyzer
::
clear_bits
(
ArgumentMap
vars
,
VectorSet
&
bm
)
{
for
(
int
i
=
0
;
i
<
_arg_size
;
i
++
)
{
if
(
vars
.
contains
(
i
))
{
...
...
@@ -166,6 +176,11 @@ void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
if
(
vars
.
contains_unknown
()
||
vars
.
contains_vars
())
{
_return_allocated
=
false
;
}
if
(
_return_local
&&
vars
.
contains_vars
()
&&
!
returns_all
(
vars
))
{
// Return result should be invalidated if args in new
// state are not recorded in return state.
_return_local
=
false
;
}
}
}
...
...
src/share/vm/ci/bcEscapeAnalyzer.hpp
浏览文件 @
7ba5bd69
...
...
@@ -80,6 +80,7 @@ class BCEscapeAnalyzer : public ResourceObj {
void
set_returned
(
ArgumentMap
vars
);
bool
is_argument
(
ArgumentMap
vars
);
bool
is_arg_stack
(
ArgumentMap
vars
);
bool
returns_all
(
ArgumentMap
vars
);
void
clear_bits
(
ArgumentMap
vars
,
VectorSet
&
bs
);
void
set_method_escape
(
ArgumentMap
vars
);
void
set_global_escape
(
ArgumentMap
vars
,
bool
merge
=
false
);
...
...
src/share/vm/opto/matcher.cpp
浏览文件 @
7ba5bd69
...
...
@@ -2305,26 +2305,26 @@ void Matcher::validate_null_checks( ) {
// atomic instruction acting as a store_load barrier without any
// intervening volatile load, and thus we don't need a barrier here.
// We retain the Node to act as a compiler ordering barrier.
bool
Matcher
::
post_store_load_barrier
(
const
Node
*
vmb
)
{
Compile
*
C
=
Compile
::
current
();
assert
(
vmb
->
is_MemBar
(),
""
);
assert
(
vmb
->
Opcode
()
!=
Op_MemBarAcquire
,
""
);
const
MemBarNode
*
mem
=
(
const
MemBarNode
*
)
vmb
;
// Get the Proj node, ctrl, that can be used to iterate forward
Node
*
ctrl
=
NULL
;
DUIterator_Fast
imax
,
i
=
mem
->
fast_outs
(
imax
);
while
(
true
)
{
ctrl
=
mem
->
fast_out
(
i
);
// Throw out-of-bounds if proj not found
assert
(
ctrl
->
is_Proj
(),
"only projections here"
);
ProjNode
*
proj
=
(
ProjNode
*
)
ctrl
;
if
(
proj
->
_con
==
TypeFunc
::
Control
&&
!
C
->
node_arena
()
->
contains
(
ctrl
)
)
// Unmatched old-space only
bool
Matcher
::
post_store_load_barrier
(
const
Node
*
vmb
)
{
Compile
*
C
=
Compile
::
current
();
assert
(
vmb
->
is_MemBar
(),
""
);
assert
(
vmb
->
Opcode
()
!=
Op_MemBarAcquire
,
""
);
const
MemBarNode
*
membar
=
vmb
->
as_MemBar
();
// Get the Ideal Proj node, ctrl, that can be used to iterate forward
Node
*
ctrl
=
NULL
;
for
(
DUIterator_Fast
imax
,
i
=
membar
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
p
=
membar
->
fast_out
(
i
);
assert
(
p
->
is_Proj
(),
"only projections here"
);
if
((
p
->
as_Proj
()
->
_con
==
TypeFunc
::
Control
)
&&
!
C
->
node_arena
()
->
contains
(
p
))
{
// Unmatched old-space only
ctrl
=
p
;
break
;
i
++
;
}
}
assert
((
ctrl
!=
NULL
),
"missing control projection"
);
for
(
DUIterator_Fast
jmax
,
j
=
ctrl
->
fast_outs
(
jmax
);
j
<
jmax
;
j
++
)
{
for
(
DUIterator_Fast
jmax
,
j
=
ctrl
->
fast_outs
(
jmax
);
j
<
jmax
;
j
++
)
{
Node
*
x
=
ctrl
->
fast_out
(
j
);
int
xop
=
x
->
Opcode
();
...
...
@@ -2336,37 +2336,36 @@ bool Matcher::post_store_load_barrier(const Node *vmb) {
// that a monitor exit operation contains a serializing instruction.
if
(
xop
==
Op_MemBarVolatile
||
xop
==
Op_FastLock
||
xop
==
Op_CompareAndSwapL
||
xop
==
Op_CompareAndSwapP
||
xop
==
Op_CompareAndSwapN
||
xop
==
Op_CompareAndSwapI
)
xop
==
Op_CompareAndSwapI
)
{
return
true
;
}
// Op_FastLock previously appeared in the Op_* list above.
// With biased locking we're no longer guaranteed that a monitor
// enter operation contains a serializing instruction.
if
((
xop
==
Op_FastLock
)
&&
!
UseBiasedLocking
)
{
return
true
;
}
if
(
x
->
is_MemBar
())
{
// We must retain this membar if there is an upcoming volatile
// load, which will be
preced
ed by acquire membar.
if
(
xop
==
Op_MemBarAcquire
)
// load, which will be
follow
ed by acquire membar.
if
(
xop
==
Op_MemBarAcquire
)
{
return
false
;
// For other kinds of barriers, check by pretending we
// are them, and seeing if we can be removed.
else
return
post_store_load_barrier
((
const
MemBarNode
*
)
x
);
}
else
{
// For other kinds of barriers, check by pretending we
// are them, and seeing if we can be removed.
return
post_store_load_barrier
(
x
->
as_MemBar
());
}
}
// Delicate code to detect case of an upcoming fastlock block
if
(
x
->
is_If
()
&&
x
->
req
()
>
1
&&
!
C
->
node_arena
()
->
contains
(
x
)
)
{
// Unmatched old-space only
Node
*
iff
=
x
;
Node
*
bol
=
iff
->
in
(
1
);
// The iff might be some random subclass of If or bol might be Con-Top
if
(
!
bol
->
is_Bool
())
return
false
;
assert
(
bol
->
req
()
>
1
,
""
);
return
(
bol
->
in
(
1
)
->
Opcode
()
==
Op_FastUnlock
);
}
// probably not necessary to check for these
if
(
x
->
is_Call
()
||
x
->
is_SafePoint
()
||
x
->
is_block_proj
())
if
(
x
->
is_Call
()
||
x
->
is_SafePoint
()
||
x
->
is_block_proj
())
{
return
false
;
}
}
return
false
;
}
...
...
src/share/vm/opto/parse3.cpp
浏览文件 @
7ba5bd69
...
...
@@ -294,25 +294,7 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
// If reference is volatile, prevent following volatiles ops from
// floating up before the volatile write.
if
(
is_vol
)
{
// First place the specific membar for THIS volatile index. This first
// membar is dependent on the store, keeping any other membars generated
// below from floating up past the store.
int
adr_idx
=
C
->
get_alias_index
(
adr_type
);
insert_mem_bar_volatile
(
Op_MemBarVolatile
,
adr_idx
,
store
);
// Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
// volatile alias indices. Skip this if the membar is redundant.
if
(
adr_idx
!=
Compile
::
AliasIdxBot
)
{
insert_mem_bar_volatile
(
Op_MemBarVolatile
,
Compile
::
AliasIdxBot
,
store
);
}
// Finally, place alias-index-specific membars for each volatile index
// that isn't the adr_idx membar. Typically there's only 1 or 2.
for
(
int
i
=
Compile
::
AliasIdxRaw
;
i
<
C
->
num_alias_types
();
i
++
)
{
if
(
i
!=
adr_idx
&&
C
->
alias_type
(
i
)
->
is_volatile
())
{
insert_mem_bar_volatile
(
Op_MemBarVolatile
,
i
,
store
);
}
}
insert_mem_bar
(
Op_MemBarVolatile
);
// Use fat membar
}
// If the field is final, the rules of Java say we are in <init> or <clinit>.
...
...
test/compiler/EscapeAnalysis/Test8020215.java
0 → 100644
浏览文件 @
7ba5bd69
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8020215
* @summary Different execution plan when using JIT vs interpreter
* @run main Test8020215
*/
import
java.util.ArrayList
;
import
java.util.List
;
public
class
Test8020215
{
public
static
class
NamedObject
{
public
int
id
;
public
String
name
;
public
NamedObject
(
int
id
,
String
name
)
{
this
.
id
=
id
;
this
.
name
=
name
;
}
}
public
static
class
NamedObjectList
{
public
List
<
NamedObject
>
namedObjectList
=
new
ArrayList
<
NamedObject
>();
public
NamedObject
getBest
(
int
id
)
{
NamedObject
bestObject
=
null
;
for
(
NamedObject
o
:
namedObjectList
)
{
bestObject
=
id
==
o
.
id
?
getBetter
(
bestObject
,
o
)
:
bestObject
;
}
return
(
bestObject
!=
null
)
?
bestObject
:
null
;
}
private
static
NamedObject
getBetter
(
NamedObject
p1
,
NamedObject
p2
)
{
return
(
p1
==
null
)
?
p2
:
(
p2
==
null
)
?
p1
:
(
p2
.
name
.
compareTo
(
p1
.
name
)
>=
0
)
?
p2
:
p1
;
}
}
static
void
test
(
NamedObjectList
b
,
int
i
)
{
NamedObject
x
=
b
.
getBest
(
2
);
// test
if
(
x
==
null
)
{
throw
new
RuntimeException
(
"x should never be null here! (i="
+
i
+
")"
);
}
}
public
static
void
main
(
String
[]
args
)
{
// setup
NamedObjectList
b
=
new
NamedObjectList
();
for
(
int
i
=
0
;
i
<
10000
;
i
++)
{
b
.
namedObjectList
.
add
(
new
NamedObject
(
1
,
"2012-12-31"
));
}
b
.
namedObjectList
.
add
(
new
NamedObject
(
2
,
"2013-12-31"
));
// execution
for
(
int
i
=
0
;
i
<
12000
;
i
++)
{
test
(
b
,
i
);
}
System
.
out
.
println
(
"PASSED"
);
}
}
test/compiler/cpuflags/RestoreMXCSR.java
0 → 100644
浏览文件 @
7ba5bd69
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8020433
* @summary Crash when using -XX:+RestoreMXCSROnJNICalls
* @library /testlibrary
*
*/
import
com.oracle.java.testlibrary.*
;
public
class
RestoreMXCSR
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ProcessBuilder
pb
;
OutputAnalyzer
out
;
pb
=
ProcessTools
.
createJavaProcessBuilder
(
"-XX:+RestoreMXCSROnJNICalls"
,
"-version"
);
out
=
new
OutputAnalyzer
(
pb
.
start
());
out
.
shouldHaveExitValue
(
0
);
}
}
test/compiler/membars/DekkerTest.java
0 → 100644
浏览文件 @
7ba5bd69
/*
* Copyright 2013 SAP AG. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8007898
* @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @author Martin Doerr martin DOT doerr AT sap DOT com
*
* Run 3 times since the failure is intermittent.
*/
public
class
DekkerTest
{
/*
Read After Write Test (basically a simple Dekker test with volatile variables)
Derived from the original jcstress test, available at:
http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/
tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
*/
static
final
int
ITERATIONS
=
1000000
;
static
class
TestData
{
public
volatile
int
a
;
public
volatile
int
b
;
}
static
class
ResultData
{
public
int
a
;
public
int
b
;
}
TestData
[]
testDataArray
;
ResultData
[]
results
;
volatile
boolean
start
;
public
DekkerTest
()
{
testDataArray
=
new
TestData
[
ITERATIONS
];
results
=
new
ResultData
[
ITERATIONS
];
for
(
int
i
=
0
;
i
<
ITERATIONS
;
++
i
)
{
testDataArray
[
i
]
=
new
TestData
();
results
[
i
]
=
new
ResultData
();
}
start
=
false
;
}
public
void
reset
()
{
for
(
int
i
=
0
;
i
<
ITERATIONS
;
++
i
)
{
testDataArray
[
i
].
a
=
0
;
testDataArray
[
i
].
b
=
0
;
results
[
i
].
a
=
0
;
results
[
i
].
b
=
0
;
}
start
=
false
;
}
int
actor1
(
TestData
t
)
{
t
.
a
=
1
;
return
t
.
b
;
}
int
actor2
(
TestData
t
)
{
t
.
b
=
1
;
return
t
.
a
;
}
class
Runner1
extends
Thread
{
public
void
run
()
{
do
{}
while
(!
start
);
for
(
int
i
=
0
;
i
<
ITERATIONS
;
++
i
)
{
results
[
i
].
a
=
actor1
(
testDataArray
[
i
]);
}
}
}
class
Runner2
extends
Thread
{
public
void
run
()
{
do
{}
while
(!
start
);
for
(
int
i
=
0
;
i
<
ITERATIONS
;
++
i
)
{
results
[
i
].
b
=
actor2
(
testDataArray
[
i
]);
}
}
}
void
testRunner
()
{
Thread
thread1
=
new
Runner1
();
Thread
thread2
=
new
Runner2
();
thread1
.
start
();
thread2
.
start
();
do
{}
while
(!
thread1
.
isAlive
());
do
{}
while
(!
thread2
.
isAlive
());
start
=
true
;
Thread
.
yield
();
try
{
thread1
.
join
();
thread2
.
join
();
}
catch
(
InterruptedException
e
)
{
System
.
out
.
println
(
"interrupted!"
);
System
.
exit
(
1
);
}
}
boolean
printResult
()
{
int
[]
count
=
new
int
[
4
];
for
(
int
i
=
0
;
i
<
ITERATIONS
;
++
i
)
{
int
event_kind
=
(
results
[
i
].
a
<<
1
)
+
results
[
i
].
b
;
++
count
[
event_kind
];
}
if
(
count
[
0
]
==
0
&&
count
[
3
]
==
0
)
{
System
.
out
.
println
(
"[not interesting]"
);
return
false
;
// not interesting
}
String
error
=
(
count
[
0
]
==
0
)
?
" ok"
:
" disallowed!"
;
System
.
out
.
println
(
"[0,0] "
+
count
[
0
]
+
error
);
System
.
out
.
println
(
"[0,1] "
+
count
[
1
]);
System
.
out
.
println
(
"[1,0] "
+
count
[
2
]);
System
.
out
.
println
(
"[1,1] "
+
count
[
3
]);
return
(
count
[
0
]
!=
0
);
}
public
static
void
main
(
String
args
[])
{
DekkerTest
test
=
new
DekkerTest
();
final
int
runs
=
30
;
int
failed
=
0
;
for
(
int
c
=
0
;
c
<
runs
;
++
c
)
{
test
.
testRunner
();
if
(
test
.
printResult
())
{
failed
++;
}
test
.
reset
();
}
if
(
failed
>
0
)
{
throw
new
InternalError
(
"FAILED. Got "
+
failed
+
" failed ITERATIONS"
);
}
System
.
out
.
println
(
"PASSED."
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录