Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
074d68f2
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看板
提交
074d68f2
编写于
3月 27, 2012
作者:
A
acorn
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
6f1c59c7
8613a1c5
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
677 addition
and
139 deletion
+677
-139
make/bsd/makefiles/wb.make
make/bsd/makefiles/wb.make
+1
-1
make/linux/makefiles/wb.make
make/linux/makefiles/wb.make
+1
-1
make/solaris/makefiles/wb.make
make/solaris/makefiles/wb.make
+1
-1
make/windows/create_obj_files.sh
make/windows/create_obj_files.sh
+2
-0
make/windows/makefiles/projectcreator.make
make/windows/makefiles/projectcreator.make
+1
-0
make/windows/makefiles/vm.make
make/windows/makefiles/vm.make
+7
-0
make/windows/makefiles/wb.make
make/windows/makefiles/wb.make
+1
-1
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
+2
-0
src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
.../tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
+43
-0
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+7
-7
src/share/vm/classfile/classFileParser.hpp
src/share/vm/classfile/classFileParser.hpp
+4
-3
src/share/vm/classfile/symbolTable.cpp
src/share/vm/classfile/symbolTable.cpp
+65
-51
src/share/vm/classfile/symbolTable.hpp
src/share/vm/classfile/symbolTable.hpp
+24
-11
src/share/vm/classfile/vmSymbols.cpp
src/share/vm/classfile/vmSymbols.cpp
+4
-4
src/share/vm/memory/dump.cpp
src/share/vm/memory/dump.cpp
+4
-5
src/share/vm/oops/objArrayKlassKlass.cpp
src/share/vm/oops/objArrayKlassKlass.cpp
+2
-2
src/share/vm/oops/symbol.cpp
src/share/vm/oops/symbol.cpp
+15
-26
src/share/vm/oops/symbol.hpp
src/share/vm/oops/symbol.hpp
+35
-15
src/share/vm/oops/typeArrayKlass.cpp
src/share/vm/oops/typeArrayKlass.cpp
+1
-1
src/share/vm/prims/wbtestmethods/parserTests.cpp
src/share/vm/prims/wbtestmethods/parserTests.cpp
+148
-0
src/share/vm/prims/wbtestmethods/parserTests.hpp
src/share/vm/prims/wbtestmethods/parserTests.hpp
+32
-0
src/share/vm/prims/whitebox.cpp
src/share/vm/prims/whitebox.cpp
+57
-9
src/share/vm/prims/whitebox.hpp
src/share/vm/prims/whitebox.hpp
+17
-0
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+1
-1
src/share/vm/services/diagnosticArgument.cpp
src/share/vm/services/diagnosticArgument.cpp
+41
-0
src/share/vm/services/diagnosticArgument.hpp
src/share/vm/services/diagnosticArgument.hpp
+9
-0
test/serviceability/ParserTest.java
test/serviceability/ParserTest.java
+152
-0
未找到文件。
make/bsd/makefiles/wb.make
浏览文件 @
074d68f2
...
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/linux/makefiles/wb.make
浏览文件 @
074d68f2
...
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/solaris/makefiles/wb.make
浏览文件 @
074d68f2
...
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/windows/create_obj_files.sh
浏览文件 @
074d68f2
...
...
@@ -80,6 +80,8 @@ if [ -d "${ALTSRC}/share/vm/jfr" ]; then
BASE_PATHS
=
"
${
BASE_PATHS
}
${
ALTSRC
}
/share/vm/jfr"
fi
BASE_PATHS
=
"
${
BASE_PATHS
}
${
COMMONSRC
}
/share/vm/prims/wbtestmethods"
CORE_PATHS
=
"
${
BASE_PATHS
}
"
# shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
if
[
-d
"
${
ALTSRC
}
/share/vm/gc_implementation"
]
;
then
...
...
make/windows/makefiles/projectcreator.make
浏览文件 @
074d68f2
...
...
@@ -51,6 +51,7 @@ ProjectCreatorIncludesPRIVATE=\
-relativeInclude
src
\c
losed
\c
pu
\$
(
Platform_arch
)
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\p
recompiled
\
-relativeInclude
src
\s
hare
\v
m
\p
rims
\w
btestmethods
\
-relativeInclude
src
\s
hare
\v
m
\p
rims
\
-relativeInclude
src
\o
s
\w
indows
\v
m
\
-relativeInclude
src
\o
s_cpu
\w
indows_
$(Platform_arch)
\v
m
\
...
...
make/windows/makefiles/vm.make
浏览文件 @
074d68f2
...
...
@@ -172,6 +172,7 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/asm
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/memory
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/oops
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/prims
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/prims/wbtestmethods
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/runtime
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/services
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/trace
...
...
@@ -269,6 +270,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(COMMONSRC)\share\vm\prims}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(COMMONSRC)\share\vm\prims\wbtestmethods}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(COMMONSRC)\share\vm\runtime}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
...
...
@@ -349,6 +353,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(ALTSRC)\share\vm\prims}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(ALTSRC)\share\vm\prims\wbtestmethods}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(ALTSRC)\share\vm\runtime}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
...
...
make/windows/makefiles/wb.make
浏览文件 @
074d68f2
...
...
@@ -40,7 +40,7 @@ wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLAS
{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class
::
$(COMPILE_JAVAC)
-d
$(WB_CLASSES)
$<
$(COMPILE_JAVAC)
-
sourcepath
$(WBSRCDIR)
-
d
$(WB_CLASSES)
$<
$(WB_JAR)
:
wb_java_srcs
$(RUN_JAR)
cf
$@
-C
$(WB_CLASSES)
.
...
...
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
浏览文件 @
074d68f2
...
...
@@ -24,6 +24,7 @@
package
sun.hotspot
;
import
java.security.BasicPermission
;
import
sun.hotspot.parser.DiagnosticCommand
;
public
class
WhiteBox
{
...
...
@@ -67,4 +68,5 @@ public class WhiteBox {
public
native
boolean
g1IsHumongous
(
Object
o
);
public
native
long
g1NumFreeRegions
();
public
native
int
g1RegionSize
();
public
native
Object
[]
parseCommandLine
(
String
commandline
,
DiagnosticCommand
[]
args
);
}
src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
0 → 100644
浏览文件 @
074d68f2
package
sun.hotspot.parser
;
public
class
DiagnosticCommand
{
public
enum
DiagnosticArgumentType
{
JLONG
,
BOOLEAN
,
STRING
,
NANOTIME
,
STRINGARRAY
,
MEMORYSIZE
}
private
String
name
;
private
String
desc
;
private
DiagnosticArgumentType
type
;
private
boolean
mandatory
;
private
String
defaultValue
;
public
DiagnosticCommand
(
String
name
,
String
desc
,
DiagnosticArgumentType
type
,
boolean
mandatory
,
String
defaultValue
)
{
this
.
name
=
name
;
this
.
desc
=
desc
;
this
.
type
=
type
;
this
.
mandatory
=
mandatory
;
this
.
defaultValue
=
defaultValue
;
}
public
String
getName
()
{
return
name
;
}
public
String
getDesc
()
{
return
desc
;
}
public
DiagnosticArgumentType
getType
()
{
return
type
;
}
public
boolean
isMandatory
()
{
return
mandatory
;
}
public
String
getDefaultValue
()
{
return
defaultValue
;
}
}
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -81,7 +81,7 @@
#define JAVA_7_VERSION 51
void
ClassFileParser
::
parse_constant_pool_entries
(
constantPoolHandle
cp
,
int
length
,
TRAPS
)
{
void
ClassFileParser
::
parse_constant_pool_entries
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
length
,
TRAPS
)
{
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
// this function (_current can be allocated in a register, with scalar
// replacement of aggregates). The _current pointer is copied back to
...
...
@@ -272,7 +272,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
indices
[
names_count
]
=
index
;
hashValues
[
names_count
++
]
=
hash
;
if
(
names_count
==
SymbolTable
::
symbol_alloc_batch_size
)
{
SymbolTable
::
new_symbols
(
cp
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
SymbolTable
::
new_symbols
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
names_count
=
0
;
}
}
else
{
...
...
@@ -289,7 +289,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
// Allocate the remaining symbols
if
(
names_count
>
0
)
{
SymbolTable
::
new_symbols
(
cp
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
SymbolTable
::
new_symbols
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
}
// Copy _current pointer of local copy back to stream().
...
...
@@ -318,7 +318,7 @@ class ConstantPoolCleaner : public StackObj {
bool
inline
valid_cp_range
(
int
index
,
int
length
)
{
return
(
index
>
0
&&
index
<
length
);
}
constantPoolHandle
ClassFileParser
::
parse_constant_pool
(
TRAPS
)
{
constantPoolHandle
ClassFileParser
::
parse_constant_pool
(
Handle
class_loader
,
TRAPS
)
{
ClassFileStream
*
cfs
=
stream
();
constantPoolHandle
nullHandle
;
...
...
@@ -337,7 +337,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ConstantPoolCleaner
cp_in_error
(
cp
);
// set constant pool to be cleaned up.
// parsing constant pool entries
parse_constant_pool_entries
(
cp
,
length
,
CHECK_
(
nullHandle
));
parse_constant_pool_entries
(
c
lass_loader
,
c
p
,
length
,
CHECK_
(
nullHandle
));
int
index
=
1
;
// declared outside of loops for portability
...
...
@@ -2758,7 +2758,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
_relax_verify
=
Verifier
::
relax_verify_for
(
class_loader
());
// Constant pool
constantPoolHandle
cp
=
parse_constant_pool
(
CHECK_
(
nullHandle
));
constantPoolHandle
cp
=
parse_constant_pool
(
class_loader
,
CHECK_
(
nullHandle
));
ConstantPoolCleaner
error_handler
(
cp
);
// set constant pool to be cleaned up.
int
cp_size
=
cp
->
length
();
...
...
src/share/vm/classfile/classFileParser.hpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -68,9 +68,10 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void
set_stream
(
ClassFileStream
*
st
)
{
_stream
=
st
;
}
// Constant pool parsing
void
parse_constant_pool_entries
(
constantPoolHandle
cp
,
int
length
,
TRAPS
);
void
parse_constant_pool_entries
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
length
,
TRAPS
);
constantPoolHandle
parse_constant_pool
(
TRAPS
);
constantPoolHandle
parse_constant_pool
(
Handle
class_loader
,
TRAPS
);
// Interface parsing
objArrayHandle
parse_interfaces
(
constantPoolHandle
cp
,
...
...
src/share/vm/classfile/symbolTable.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -27,6 +27,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
...
...
@@ -37,34 +38,35 @@
// --------------------------------------------------------------------------
SymbolTable
*
SymbolTable
::
_the_table
=
NULL
;
// Static arena for symbols that are not deallocated
Arena
*
SymbolTable
::
_arena
=
NULL
;
Symbol
*
SymbolTable
::
allocate_symbol
(
const
u1
*
name
,
int
len
,
TRAPS
)
{
Symbol
*
SymbolTable
::
allocate_symbol
(
const
u1
*
name
,
int
len
,
bool
c_heap
,
TRAPS
)
{
// Don't allow symbols to be created which cannot fit in a Symbol*.
if
(
len
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
}
Symbol
*
sym
=
new
(
len
)
Symbol
(
name
,
len
);
Symbol
*
sym
;
// Allocate symbols in the C heap when dumping shared spaces in case there
// are temporary symbols we can remove.
if
(
c_heap
||
DumpSharedSpaces
)
{
// refcount starts as 1
sym
=
new
(
len
,
THREAD
)
Symbol
(
name
,
len
,
1
);
}
else
{
sym
=
new
(
len
,
arena
(),
THREAD
)
Symbol
(
name
,
len
,
-
1
);
}
assert
(
sym
!=
NULL
,
"new should call vm_exit_out_of_memory if C_HEAP is exhausted"
);
return
sym
;
}
bool
SymbolTable
::
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
int
*
lengths
,
Symbol
**
syms
,
TRAPS
)
{
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
}
}
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
int
len
=
lengths
[
i
];
syms
[
i
]
=
new
(
len
)
Symbol
(
names
[
i
],
len
);
assert
(
syms
[
i
]
!=
NULL
,
"new should call vm_exit_out_of_memory if "
"C_HEAP is exhausted"
);
void
SymbolTable
::
initialize_symbols
(
int
arena_alloc_size
)
{
// Initialize the arena for global symbols, size passed in depends on CDS.
if
(
arena_alloc_size
==
0
)
{
_arena
=
new
Arena
();
}
else
{
_arena
=
new
Arena
(
arena_alloc_size
);
}
return
true
;
}
// Call function for all symbols in the symbol table.
...
...
@@ -83,8 +85,7 @@ int SymbolTable::symbols_removed = 0;
int
SymbolTable
::
symbols_counted
=
0
;
// Remove unreferenced symbols from the symbol table
// This is done late during GC. This doesn't use the hash table unlink because
// it assumes that the literals are oops.
// This is done late during GC.
void
SymbolTable
::
unlink
()
{
int
removed
=
0
;
int
total
=
0
;
...
...
@@ -156,7 +157,7 @@ Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
if
(
s
!=
NULL
)
return
s
;
// Otherwise, add to symbol to table
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
name
,
len
,
hashValue
,
CHECK_NULL
);
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
name
,
len
,
hashValue
,
true
,
CHECK_NULL
);
}
Symbol
*
SymbolTable
::
lookup
(
const
Symbol
*
sym
,
int
begin
,
int
end
,
TRAPS
)
{
...
...
@@ -192,7 +193,7 @@ Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
// We can't include the code in No_Safepoint_Verifier because of the
// ResourceMark.
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
buffer
,
len
,
hashValue
,
CHECK_NULL
);
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
buffer
,
len
,
hashValue
,
true
,
CHECK_NULL
);
}
Symbol
*
SymbolTable
::
lookup_only
(
const
char
*
name
,
int
len
,
...
...
@@ -256,71 +257,81 @@ Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
}
}
void
SymbolTable
::
add
(
constantPoolHandle
cp
,
int
names_count
,
void
SymbolTable
::
add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
SymbolTable
*
table
=
the_table
();
bool
added
=
table
->
basic_add
(
cp
,
names_count
,
names
,
lengths
,
bool
added
=
table
->
basic_add
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
cp_indices
,
hashValues
,
CHECK
);
if
(
!
added
)
{
// do it the hard way
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
int
index
=
table
->
hash_to_index
(
hashValues
[
i
]);
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
hashValues
[
i
]
,
CHECK
);
bool
c_heap
=
class_loader
()
!=
NULL
;
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
hashValues
[
i
],
c_heap
,
CHECK
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
}
}
}
Symbol
*
SymbolTable
::
new_permanent_symbol
(
const
char
*
name
,
TRAPS
)
{
unsigned
int
hash
;
Symbol
*
result
=
SymbolTable
::
lookup_only
((
char
*
)
name
,
(
int
)
strlen
(
name
),
hash
);
if
(
result
!=
NULL
)
{
return
result
;
}
SymbolTable
*
table
=
the_table
();
int
index
=
table
->
hash_to_index
(
hash
);
return
table
->
basic_add
(
index
,
(
u1
*
)
name
,
(
int
)
strlen
(
name
),
hash
,
false
,
THREAD
);
}
Symbol
*
SymbolTable
::
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
TRAPS
)
{
unsigned
int
hashValue
,
bool
c_heap
,
TRAPS
)
{
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
(),
"proposed name of symbol must be stable"
);
// We assume that lookup() has been called already, that it failed,
// and symbol was not found. We create the symbol here.
Symbol
*
sym
=
allocate_symbol
(
name
,
len
,
CHECK_NULL
);
// Allocation must be done before grabbing the SymbolTable_lock lock
// Grab SymbolTable_lock first.
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
assert
(
sym
->
equals
((
char
*
)
name
,
len
),
"symbol must be properly initialized"
);
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
Symbol
*
test
=
lookup
(
index
,
(
char
*
)
name
,
len
,
hashValue
);
if
(
test
!=
NULL
)
{
// A race occurred and another thread introduced the symbol, this one
// will be dropped and collected.
delete
sym
;
// A race occurred and another thread introduced the symbol.
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
return
test
;
}
// Create a new symbol.
Symbol
*
sym
=
allocate_symbol
(
name
,
len
,
c_heap
,
CHECK_NULL
);
assert
(
sym
->
equals
((
char
*
)
name
,
len
),
"symbol must be properly initialized"
);
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValue
,
sym
);
sym
->
increment_refcount
();
add_entry
(
index
,
entry
);
return
sym
;
}
bool
SymbolTable
::
basic_add
(
constantPoolHandle
cp
,
int
names_count
,
// This version of basic_add adds symbols in batch from the constant pool
// parsing.
bool
SymbolTable
::
basic_add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
Symbol
*
syms
[
symbol_alloc_batch_size
];
bool
allocated
=
allocate_symbols
(
names_count
,
(
const
u1
**
)
names
,
lengths
,
syms
,
CHECK_false
);
if
(
!
allocated
)
{
return
false
;
// Check symbol names are not too long. If any are too long, don't add any.
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
}
}
//
Allocation must be done before grabbing the SymbolTable_lock lock
//
Hold SymbolTable_lock through the symbol creation
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
assert
(
syms
[
i
]
->
equals
(
names
[
i
],
lengths
[
i
]),
"symbol must be properly initialized"
);
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
int
index
=
hash_to_index
(
hashValues
[
i
]);
...
...
@@ -330,16 +341,17 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
// will be dropped and collected. Use test instead.
cp
->
symbol_at_put
(
cp_indices
[
i
],
test
);
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
delete
syms
[
i
];
}
else
{
Symbol
*
sym
=
syms
[
i
];
// Create a new symbol. The null class loader is never unloaded so these
// are allocated specially in a permanent arena.
bool
c_heap
=
class_loader
()
!=
NULL
;
Symbol
*
sym
=
allocate_symbol
((
const
u1
*
)
names
[
i
],
lengths
[
i
],
c_heap
,
CHECK_
(
false
));
assert
(
sym
->
equals
(
names
[
i
],
lengths
[
i
]),
"symbol must be properly initialized"
);
// why wouldn't it be???
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValues
[
i
],
sym
);
sym
->
increment_refcount
();
// increment refcount in external hashtable
add_entry
(
index
,
entry
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
}
}
return
true
;
}
...
...
@@ -406,6 +418,8 @@ void SymbolTable::print_histogram() {
((
float
)
symbols_removed
/
(
float
)
symbols_counted
)
*
100
);
}
tty
->
print_cr
(
"Reference counts %5d"
,
Symbol
::
_total_count
);
tty
->
print_cr
(
"Symbol arena size %5d used %5d"
,
arena
()
->
size_in_bytes
(),
arena
()
->
used
());
tty
->
print_cr
(
"Histogram of symbol length:"
);
tty
->
print_cr
(
"%8s %5d"
,
"Total "
,
total
);
tty
->
print_cr
(
"%8s %5d"
,
"Maximum"
,
max_symbols
);
...
...
src/share/vm/classfile/symbolTable.hpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -82,24 +82,24 @@ private:
static
int
symbols_removed
;
static
int
symbols_counted
;
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
TRAPS
);
// Assumes no characters larger than 0x7F
bool
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
int
*
lengths
,
Symbol
**
syms
,
TRAPS
);
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
bool
c_heap
,
TRAPS
);
// Assumes no characters larger than 0x7F
// Adding elements
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
TRAPS
);
bool
basic_add
(
constantPoolHandle
cp
,
int
names_count
,
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
bool
c_heap
,
TRAPS
);
bool
basic_add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
);
static
void
new_symbols
(
constantPoolHandle
cp
,
int
names_count
,
static
void
new_symbols
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
name
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
add
(
cp
,
names_count
,
name
,
lengths
,
cp_indices
,
hashValues
,
THREAD
);
add
(
c
lass_loader
,
c
p
,
names_count
,
name
,
lengths
,
cp_indices
,
hashValues
,
THREAD
);
}
// Table size
enum
{
symbol_table_size
=
20011
...
...
@@ -114,10 +114,16 @@ private:
:
Hashtable
<
Symbol
*>
(
symbol_table_size
,
sizeof
(
HashtableEntry
<
Symbol
*>
),
t
,
number_of_entries
)
{}
// Arena for permanent symbols (null class loader) that are never unloaded
static
Arena
*
_arena
;
static
Arena
*
arena
()
{
return
_arena
;
}
// called for statistics
static
void
initialize_symbols
(
int
arena_alloc_size
=
0
);
public:
enum
{
symbol_alloc_batch_size
=
8
symbol_alloc_batch_size
=
8
,
// Pick initial size based on java -version size measurements
symbol_alloc_arena_size
=
360
*
K
};
// The symbol table
...
...
@@ -126,6 +132,7 @@ public:
static
void
create_table
()
{
assert
(
_the_table
==
NULL
,
"One symbol table allowed."
);
_the_table
=
new
SymbolTable
();
initialize_symbols
(
symbol_alloc_arena_size
);
}
static
void
create_table
(
HashtableBucket
*
t
,
int
length
,
...
...
@@ -134,6 +141,9 @@ public:
assert
(
length
==
symbol_table_size
*
sizeof
(
HashtableBucket
),
"bad shared symbol size."
);
_the_table
=
new
SymbolTable
(
t
,
number_of_entries
);
// if CDS give symbol table a default arena size since most symbols
// are already allocated in the shared misc section.
initialize_symbols
();
}
static
Symbol
*
lookup
(
const
char
*
name
,
int
len
,
TRAPS
);
...
...
@@ -151,7 +161,7 @@ public:
static
Symbol
*
lookup_unicode
(
const
jchar
*
name
,
int
len
,
TRAPS
);
static
Symbol
*
lookup_only_unicode
(
const
jchar
*
name
,
int
len
,
unsigned
int
&
hash
);
static
void
add
(
constantPoolHandle
cp
,
int
names_count
,
static
void
add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
);
...
...
@@ -174,6 +184,9 @@ public:
return
lookup
(
sym
,
begin
,
end
,
THREAD
);
}
// Create a symbol in the arena for symbols that are not deleted
static
Symbol
*
new_permanent_symbol
(
const
char
*
name
,
TRAPS
);
// Symbol lookup
static
Symbol
*
lookup
(
int
index
,
const
char
*
name
,
int
len
,
TRAPS
);
...
...
src/share/vm/classfile/vmSymbols.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -79,7 +79,7 @@ void vmSymbols::initialize(TRAPS) {
if
(
!
UseSharedSpaces
)
{
const
char
*
string
=
&
vm_symbol_bodies
[
0
];
for
(
int
index
=
(
int
)
FIRST_SID
;
index
<
(
int
)
SID_LIMIT
;
index
++
)
{
Symbol
*
sym
=
SymbolTable
::
new_symbol
(
string
,
CHECK
);
Symbol
*
sym
=
SymbolTable
::
new_
permanent_
symbol
(
string
,
CHECK
);
_symbols
[
index
]
=
sym
;
string
+=
strlen
(
string
);
// skip string body
string
+=
1
;
// skip trailing null
...
...
@@ -128,7 +128,7 @@ void vmSymbols::initialize(TRAPS) {
// Spot-check correspondence between strings, symbols, and enums:
assert
(
_symbols
[
NO_SID
]
==
NULL
,
"must be"
);
const
char
*
str
=
"java/lang/Object"
;
TempNewSymbol
jlo
=
SymbolTable
::
new_symbol
(
str
,
CHECK
);
TempNewSymbol
jlo
=
SymbolTable
::
new_
permanent_
symbol
(
str
,
CHECK
);
assert
(
strncmp
(
str
,
(
char
*
)
jlo
->
base
(),
jlo
->
utf8_length
())
==
0
,
""
);
assert
(
jlo
==
java_lang_Object
(),
""
);
SID
sid
=
VM_SYMBOL_ENUM_NAME
(
java_lang_Object
);
...
...
@@ -147,7 +147,7 @@ void vmSymbols::initialize(TRAPS) {
// The string "format" happens (at the moment) not to be a vmSymbol,
// though it is a method name in java.lang.String.
str
=
"format"
;
TempNewSymbol
fmt
=
SymbolTable
::
new_symbol
(
str
,
CHECK
);
TempNewSymbol
fmt
=
SymbolTable
::
new_
permanent_
symbol
(
str
,
CHECK
);
sid
=
find_sid
(
fmt
);
assert
(
sid
==
NO_SID
,
"symbol index works (negative test)"
);
}
...
...
src/share/vm/memory/dump.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 2003, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
2
, 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
...
...
@@ -1490,12 +1490,11 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
// sun.io.Converters
static
const
char
obj_array_sig
[]
=
"[[Ljava/lang/Object;"
;
SymbolTable
::
lookup
(
obj_array_sig
,
(
int
)
strlen
(
obj_array_sig
)
,
THREAD
);
(
void
)
SymbolTable
::
new_permanent_symbol
(
obj_array_sig
,
THREAD
);
// java.util.HashMap
static
const
char
map_entry_array_sig
[]
=
"[Ljava/util/Map$Entry;"
;
SymbolTable
::
lookup
(
map_entry_array_sig
,
(
int
)
strlen
(
map_entry_array_sig
),
THREAD
);
(
void
)
SymbolTable
::
new_permanent_symbol
(
map_entry_array_sig
,
THREAD
);
tty
->
print
(
"Loading classes to share ... "
);
while
((
fgets
(
class_name
,
sizeof
class_name
,
file
))
!=
NULL
)
{
...
...
@@ -1514,7 +1513,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
computed_jsum
=
jsum
(
computed_jsum
,
class_name
,
(
const
int
)
name_len
-
1
);
// Got a class name - load it.
TempNewSymbol
class_name_symbol
=
SymbolTable
::
new
_symbol
(
class_name
,
THREAD
);
Symbol
*
class_name_symbol
=
SymbolTable
::
new_permanent
_symbol
(
class_name
,
THREAD
);
guarantee
(
!
HAS_PENDING_EXCEPTION
,
"Exception creating a symbol."
);
klassOop
klass
=
SystemDictionary
::
resolve_or_null
(
class_name_symbol
,
THREAD
);
...
...
src/share/vm/oops/objArrayKlassKlass.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -137,7 +137,7 @@ klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHand
new_str
[
idx
++
]
=
';'
;
}
new_str
[
idx
++
]
=
'\0'
;
name
=
SymbolTable
::
new_symbol
(
new_str
,
CHECK_0
);
name
=
SymbolTable
::
new_
permanent_
symbol
(
new_str
,
CHECK_0
);
if
(
element_klass
->
oop_is_instance
())
{
instanceKlass
*
ik
=
instanceKlass
::
cast
(
element_klass
());
ik
->
set_array_name
(
name
);
...
...
src/share/vm/oops/symbol.cpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -29,15 +29,25 @@
#include "runtime/os.hpp"
#include "memory/allocation.inline.hpp"
Symbol
::
Symbol
(
const
u1
*
name
,
int
length
)
:
_refcount
(
0
),
_length
(
length
)
{
Symbol
::
Symbol
(
const
u1
*
name
,
int
length
,
int
refcount
)
:
_refcount
(
refcount
),
_length
(
length
)
{
_identity_hash
=
os
::
random
();
for
(
int
i
=
0
;
i
<
_length
;
i
++
)
{
byte_at_put
(
i
,
name
[
i
]);
}
}
void
*
Symbol
::
operator
new
(
size_t
size
,
int
len
)
{
return
(
void
*
)
AllocateHeap
(
object_size
(
len
)
*
HeapWordSize
,
"symbol"
);
void
*
Symbol
::
operator
new
(
size_t
sz
,
int
len
,
TRAPS
)
{
int
alloc_size
=
object_size
(
len
)
*
HeapWordSize
;
address
res
=
(
address
)
AllocateHeap
(
alloc_size
,
"symbol"
);
DEBUG_ONLY
(
set_allocation_type
(
res
,
ResourceObj
::
C_HEAP
);)
return
res
;
}
void
*
Symbol
::
operator
new
(
size_t
sz
,
int
len
,
Arena
*
arena
,
TRAPS
)
{
int
alloc_size
=
object_size
(
len
)
*
HeapWordSize
;
address
res
=
(
address
)
arena
->
Amalloc
(
alloc_size
);
DEBUG_ONLY
(
set_allocation_type
(
res
,
ResourceObj
::
ARENA
);)
return
res
;
}
// ------------------------------------------------------------------
...
...
@@ -206,26 +216,5 @@ void Symbol::print_value_on(outputStream* st) const {
}
}
void
Symbol
::
increment_refcount
()
{
// Only increment the refcount if positive. If negative either
// overflow has occurred or it is a permanent symbol in a read only
// shared archive.
if
(
_refcount
>=
0
)
{
Atomic
::
inc
(
&
_refcount
);
NOT_PRODUCT
(
Atomic
::
inc
(
&
_total_count
);)
}
}
void
Symbol
::
decrement_refcount
()
{
if
(
_refcount
>=
0
)
{
Atomic
::
dec
(
&
_refcount
);
#ifdef ASSERT
if
(
_refcount
<
0
)
{
print
();
assert
(
false
,
"reference count underflow for symbol"
);
}
#endif
}
}
// SymbolTable prints this in its statistics
NOT_PRODUCT
(
int
Symbol
::
_total_count
=
0
;)
src/share/vm/oops/symbol.hpp
浏览文件 @
074d68f2
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
...
@@ -27,6 +27,7 @@
#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
...
...
@@ -95,7 +96,7 @@
// TempNewSymbol (passed in as a parameter) so the reference count on its symbol
// will be decremented when it goes out of scope.
class
Symbol
:
public
CHeap
Obj
{
class
Symbol
:
public
Resource
Obj
{
friend
class
VMStructs
;
friend
class
SymbolTable
;
friend
class
MoveSymbols
;
...
...
@@ -111,7 +112,7 @@ class Symbol : public CHeapObj {
};
static
int
object_size
(
int
length
)
{
size_t
size
=
heap_word_size
(
sizeof
(
Symbol
)
+
length
);
size_t
size
=
heap_word_size
(
sizeof
(
Symbol
)
+
(
length
>
0
?
length
-
1
:
0
)
);
return
align_object_size
(
size
);
}
...
...
@@ -120,28 +121,25 @@ class Symbol : public CHeapObj {
_body
[
index
]
=
value
;
}
Symbol
(
const
u1
*
name
,
int
length
);
void
*
operator
new
(
size_t
size
,
int
len
);
Symbol
(
const
u1
*
name
,
int
length
,
int
refcount
);
void
*
operator
new
(
size_t
size
,
int
len
,
TRAPS
);
void
*
operator
new
(
size_t
size
,
int
len
,
Arena
*
arena
,
TRAPS
);
public:
// Low-level access (used with care, since not GC-safe)
const
jbyte
*
base
()
const
{
return
&
_body
[
0
];
}
int
object_size
()
{
return
object_size
(
utf8_length
());
}
int
object_size
()
{
return
object_size
(
utf8_length
());
}
// Returns the largest size symbol we can safely hold.
static
int
max_length
()
{
return
max_symbol_length
;
}
static
int
max_length
()
{
return
max_symbol_length
;
}
int
identity_hash
()
{
return
_identity_hash
;
}
int
identity_hash
()
{
return
_identity_hash
;
}
// Reference counting. See comments above this class for when to use.
int
refcount
()
const
{
return
_refcount
;
}
void
increment_refcount
();
void
decrement_refcount
();
int
refcount
()
const
{
return
_refcount
;
}
inline
void
increment_refcount
();
inline
void
decrement_refcount
();
int
byte_at
(
int
index
)
const
{
assert
(
index
>=
0
&&
index
<
_length
,
"symbol index overflow"
);
...
...
@@ -220,4 +218,26 @@ int Symbol::fast_compare(Symbol* other) const {
return
(((
uintptr_t
)
this
<
(
uintptr_t
)
other
)
?
-
1
:
((
uintptr_t
)
this
==
(
uintptr_t
)
other
)
?
0
:
1
);
}
inline
void
Symbol
::
increment_refcount
()
{
// Only increment the refcount if positive. If negative either
// overflow has occurred or it is a permanent symbol in a read only
// shared archive.
if
(
_refcount
>=
0
)
{
Atomic
::
inc
(
&
_refcount
);
NOT_PRODUCT
(
Atomic
::
inc
(
&
_total_count
);)
}
}
inline
void
Symbol
::
decrement_refcount
()
{
if
(
_refcount
>=
0
)
{
Atomic
::
dec
(
&
_refcount
);
#ifdef ASSERT
if
(
_refcount
<
0
)
{
print
();
assert
(
false
,
"reference count underflow for symbol"
);
}
#endif
}
}
#endif // SHARE_VM_OOPS_SYMBOL_HPP
src/share/vm/oops/typeArrayKlass.cpp
浏览文件 @
074d68f2
...
...
@@ -55,7 +55,7 @@ klassOop typeArrayKlass::create_klass(BasicType type, int scale,
Symbol
*
sym
=
NULL
;
if
(
name_str
!=
NULL
)
{
sym
=
SymbolTable
::
new_symbol
(
name_str
,
CHECK_NULL
);
sym
=
SymbolTable
::
new_
permanent_
symbol
(
name_str
,
CHECK_NULL
);
}
KlassHandle
klassklass
(
THREAD
,
Universe
::
typeArrayKlassKlassObj
());
...
...
src/share/vm/prims/wbtestmethods/parserTests.cpp
0 → 100644
浏览文件 @
074d68f2
/*
* Copyright (c) 2011, 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.
*
*/
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "prims/jni.h"
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/interfaceSupport.hpp"
#include "memory/oopFactory.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticFramework.hpp"
//There's no way of beforeahnd knowing an upper size
//Of the length of a string representation of
//the value of an argument.
#define VALUE_MAXLEN 256
// DiagnosticFramework test utility methods
/*
* The DiagnosticArgumentType class contains an enum that says which type
* this argument represents. (JLONG, BOOLEAN etc).
* This method Returns a char* representation of that enum value.
*/
static
const
char
*
lookup_diagnosticArgumentEnum
(
const
char
*
field_name
,
oop
object
)
{
Thread
*
THREAD
=
Thread
::
current
();
const
char
*
enum_sig
=
"Lsun/hotspot/parser/DiagnosticCommand$DiagnosticArgumentType;"
;
TempNewSymbol
enumSigSymbol
=
SymbolTable
::
lookup
(
enum_sig
,
(
int
)
strlen
(
enum_sig
),
THREAD
);
int
offset
=
WhiteBox
::
offset_for_field
(
field_name
,
object
,
enumSigSymbol
);
oop
enumOop
=
object
->
obj_field
(
offset
);
const
char
*
ret
=
WhiteBox
::
lookup_jstring
(
"name"
,
enumOop
);
return
ret
;
}
/*
* Takes an oop to a DiagnosticArgumentType-instance and
* reads the fields from it. Fills an native DCmdParser with
* this info.
*/
static
void
fill_in_parser
(
DCmdParser
*
parser
,
oop
argument
)
{
const
char
*
name
=
WhiteBox
::
lookup_jstring
(
"name"
,
argument
);
const
char
*
desc
=
WhiteBox
::
lookup_jstring
(
"desc"
,
argument
);
const
char
*
default_value
=
WhiteBox
::
lookup_jstring
(
"defaultValue"
,
argument
);
bool
mandatory
=
WhiteBox
::
lookup_bool
(
"mandatory"
,
argument
);
const
char
*
type
=
lookup_diagnosticArgumentEnum
(
"type"
,
argument
);
if
(
strcmp
(
type
,
"STRING"
)
==
0
)
{
DCmdArgument
<
char
*>*
argument
=
new
DCmdArgument
<
char
*>
(
name
,
desc
,
"STRING"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"NANOTIME"
)
==
0
)
{
DCmdArgument
<
NanoTimeArgument
>*
argument
=
new
DCmdArgument
<
NanoTimeArgument
>
(
name
,
desc
,
"NANOTIME"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"JLONG"
)
==
0
)
{
DCmdArgument
<
jlong
>*
argument
=
new
DCmdArgument
<
jlong
>
(
name
,
desc
,
"JLONG"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"BOOLEAN"
)
==
0
)
{
DCmdArgument
<
bool
>*
argument
=
new
DCmdArgument
<
bool
>
(
name
,
desc
,
"BOOLEAN"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"MEMORYSIZE"
)
==
0
)
{
DCmdArgument
<
MemorySizeArgument
>*
argument
=
new
DCmdArgument
<
MemorySizeArgument
>
(
name
,
desc
,
"MEMORY SIZE"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"STRINGARRAY"
)
==
0
)
{
DCmdArgument
<
StringArrayArgument
*>*
argument
=
new
DCmdArgument
<
StringArrayArgument
*>
(
name
,
desc
,
"STRING SET"
,
mandatory
);
parser
->
add_dcmd_option
(
argument
);
}
}
/*
* Will Fill in a java object array with alternating names of parsed command line options and
* the value that has been parsed for it:
* { name, value, name, value ... }
* This can then be checked from java.
*/
WB_ENTRY
(
jobjectArray
,
WB_ParseCommandLine
(
JNIEnv
*
env
,
jobject
o
,
jstring
j_cmdline
,
jobjectArray
arguments
))
ResourceMark
rm
;
DCmdParser
parser
;
const
char
*
c_cmdline
=
java_lang_String
::
as_utf8_string
(
JNIHandles
::
resolve
(
j_cmdline
));
objArrayOop
argumentArray
=
objArrayOop
(
JNIHandles
::
resolve_non_null
(
arguments
));
int
length
=
argumentArray
->
length
();
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
oop
argument_oop
=
argumentArray
->
obj_at
(
i
);
fill_in_parser
(
&
parser
,
argument_oop
);
}
CmdLine
cmdline
(
c_cmdline
,
strlen
(
c_cmdline
),
true
);
parser
.
parse
(
&
cmdline
,
','
,
CHECK_NULL
);
klassOop
k
=
SystemDictionary
::
Object_klass
();
objArrayOop
returnvalue_array
=
oopFactory
::
new_objArray
(
k
,
parser
.
num_arguments
()
*
2
,
CHECK_NULL
);
GrowableArray
<
const
char
*>*
parsedArgNames
=
parser
.
argument_name_array
();
for
(
int
i
=
0
;
i
<
parser
.
num_arguments
();
i
++
)
{
oop
parsedName
=
java_lang_String
::
create_oop_from_str
(
parsedArgNames
->
at
(
i
),
CHECK_NULL
);
returnvalue_array
->
obj_at_put
(
i
*
2
,
parsedName
);
GenDCmdArgument
*
arg
=
parser
.
lookup_dcmd_option
(
parsedArgNames
->
at
(
i
),
strlen
(
parsedArgNames
->
at
(
i
)));
char
buf
[
VALUE_MAXLEN
];
arg
->
value_as_str
(
buf
,
sizeof
(
buf
));
oop
parsedValue
=
java_lang_String
::
create_oop_from_str
(
buf
,
CHECK_NULL
);
returnvalue_array
->
obj_at_put
(
i
*
2
+
1
,
parsedValue
);
}
return
(
jobjectArray
)
JNIHandles
::
make_local
(
returnvalue_array
);
WB_END
src/share/vm/prims/wbtestmethods/parserTests.hpp
0 → 100644
浏览文件 @
074d68f2
/*
* Copyright (c) 2012, 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.
*/
#ifndef SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
#define SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
#include "prims/jni.h"
#include "prims/whitebox.hpp"
WB_METHOD_DECLARE
WB_ParseCommandLine
(
JNIEnv
*
env
,
jobject
o
,
jstring
args
,
jobjectArray
arguments
);
#endif //SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
src/share/vm/prims/whitebox.cpp
浏览文件 @
074d68f2
...
...
@@ -24,11 +24,14 @@
#include "precompiled.hpp"
#include "jni.h"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
...
...
@@ -41,13 +44,6 @@
bool
WhiteBox
::
_used
=
false
;
// Entry macro to transition from JNI to VM state.
#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
#define WB_END JNI_END
// Definitions of functions exposed via Whitebox API
WB_ENTRY
(
jlong
,
WB_GetObjectAddress
(
JNIEnv
*
env
,
jobject
o
,
jobject
obj
))
return
(
jlong
)(
void
*
)
JNIHandles
::
resolve
(
obj
);
WB_END
...
...
@@ -81,11 +77,63 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
WB_END
#endif // !SERIALGC
//Some convenience methods to deal with objects from java
int
WhiteBox
::
offset_for_field
(
const
char
*
field_name
,
oop
object
,
Symbol
*
signature_symbol
)
{
assert
(
field_name
!=
NULL
&&
strlen
(
field_name
)
>
0
,
"Field name not valid"
);
Thread
*
THREAD
=
Thread
::
current
();
//Get the class of our object
klassOop
arg_klass
=
object
->
klass
();
//Turn it into an instance-klass
instanceKlass
*
ik
=
instanceKlass
::
cast
(
arg_klass
);
//Create symbols to look for in the class
TempNewSymbol
name_symbol
=
SymbolTable
::
lookup
(
field_name
,
(
int
)
strlen
(
field_name
),
THREAD
);
//To be filled in with an offset of the field we're looking for
fieldDescriptor
fd
;
klassOop
res
=
ik
->
find_field
(
name_symbol
,
signature_symbol
,
&
fd
);
if
(
res
==
NULL
)
{
tty
->
print_cr
(
"Invalid layout of %s at %s"
,
ik
->
external_name
(),
name_symbol
->
as_C_string
());
fatal
(
"Invalid layout of preloaded class"
);
}
//fetch the field at the offset we've found
int
dest_offset
=
fd
.
offset
();
return
dest_offset
;
}
const
char
*
WhiteBox
::
lookup_jstring
(
const
char
*
field_name
,
oop
object
)
{
int
offset
=
offset_for_field
(
field_name
,
object
,
vmSymbols
::
string_signature
());
oop
string
=
object
->
obj_field
(
offset
);
const
char
*
ret
=
java_lang_String
::
as_utf8_string
(
string
);
return
ret
;
}
bool
WhiteBox
::
lookup_bool
(
const
char
*
field_name
,
oop
object
)
{
int
offset
=
offset_for_field
(
field_name
,
object
,
vmSymbols
::
bool_signature
());
bool
ret
=
(
object
->
bool_field
(
offset
)
==
JNI_TRUE
);
return
ret
;
}
#define CC (char*)
static
JNINativeMethod
methods
[]
=
{
{
CC
"getObjectAddress"
,
CC
"(Ljava/lang/Object;)J"
,
(
void
*
)
&
WB_GetObjectAddress
},
{
CC
"getHeapOopSize"
,
CC
"()I"
,
(
void
*
)
&
WB_GetHeapOopSize
},
{
CC
"parseCommandLine"
,
CC
"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;"
,
(
void
*
)
&
WB_ParseCommandLine
},
#ifndef SERIALGC
{
CC
"g1InConcurrentMark"
,
CC
"()Z"
,
(
void
*
)
&
WB_G1InConcurrentMark
},
{
CC
"g1IsHumongous"
,
CC
"(Ljava/lang/Object;)Z"
,
(
void
*
)
&
WB_G1IsHumongous
},
...
...
src/share/vm/prims/whitebox.hpp
浏览文件 @
074d68f2
...
...
@@ -25,12 +25,29 @@
#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
#define SHARE_VM_PRIMS_WHITEBOX_HPP
#include "prims/jni.h"
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
// Entry macro to transition from JNI to VM state.
#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
#define WB_END JNI_END
#define WB_METHOD_DECLARE extern "C" jobjectArray JNICALL
class
WhiteBox
:
public
AllStatic
{
private:
static
bool
_used
;
public:
static
bool
used
()
{
return
_used
;
}
static
void
set_used
()
{
_used
=
true
;
}
static
int
offset_for_field
(
const
char
*
field_name
,
oop
object
,
Symbol
*
signature_symbol
);
static
const
char
*
lookup_jstring
(
const
char
*
field_name
,
oop
object
);
static
bool
lookup_bool
(
const
char
*
field_name
,
oop
object
);
};
#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
src/share/vm/runtime/globals.hpp
浏览文件 @
074d68f2
...
...
@@ -3807,7 +3807,7 @@ class CommandLineFlags {
product(uintx, SharedReadOnlySize, 10*M, \
"Size of read-only space in permanent generation (in bytes)") \
\
product(uintx, SharedMiscDataSize,
NOT_LP64(4*M) LP64_ONLY(5
*M), \
product(uintx, SharedMiscDataSize,
NOT_LP64(4*M) LP64_ONLY(5*M) NOT_PRODUCT(+1
*M), \
"Size of the shared data area adjacent to the heap (in bytes)") \
\
product(uintx, SharedMiscCodeSize, 4*M, \
...
...
src/share/vm/services/diagnosticArgument.cpp
浏览文件 @
074d68f2
...
...
@@ -43,6 +43,47 @@ void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
set_is_set
(
true
);
}
void
GenDCmdArgument
::
to_string
(
jlong
l
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
l
);
}
void
GenDCmdArgument
::
to_string
(
bool
b
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
b
?
"true"
:
"false"
);
}
void
GenDCmdArgument
::
to_string
(
NanoTimeArgument
n
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
n
.
_nanotime
);
}
void
GenDCmdArgument
::
to_string
(
MemorySizeArgument
m
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
m
.
_size
);
}
void
GenDCmdArgument
::
to_string
(
char
*
c
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
"%s"
,
c
);
}
void
GenDCmdArgument
::
to_string
(
StringArrayArgument
*
f
,
char
*
buf
,
size_t
len
)
{
int
length
=
f
->
array
()
->
length
();
size_t
written
=
0
;
buf
[
0
]
=
0
;
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
char
*
next_str
=
f
->
array
()
->
at
(
i
);
size_t
next_size
=
strlen
(
next_str
);
//Check if there's room left to write next element
if
(
written
+
next_size
>
len
)
{
return
;
}
//Actually write element
strcat
(
buf
,
next_str
);
written
+=
next_size
;
//Check if there's room left for the comma
if
(
i
<
length
-
1
&&
len
-
written
>
0
)
{
strcat
(
buf
,
","
);
}
}
}
template
<
>
void
DCmdArgument
<
jlong
>::
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
)
{
if
(
str
==
NULL
||
sscanf
(
str
,
INT64_FORMAT
,
&
_value
)
!=
1
)
{
...
...
src/share/vm/services/diagnosticArgument.hpp
浏览文件 @
074d68f2
...
...
@@ -110,12 +110,20 @@ public:
virtual
void
init_value
(
TRAPS
)
=
0
;
virtual
void
reset
(
TRAPS
)
=
0
;
virtual
void
cleanup
()
=
0
;
virtual
void
value_as_str
(
char
*
buf
,
size_t
len
)
=
0
;
void
set_next
(
GenDCmdArgument
*
arg
)
{
_next
=
arg
;
}
GenDCmdArgument
*
next
()
{
return
_next
;
}
void
to_string
(
jlong
l
,
char
*
buf
,
size_t
len
);
void
to_string
(
bool
b
,
char
*
buf
,
size_t
len
);
void
to_string
(
char
*
c
,
char
*
buf
,
size_t
len
);
void
to_string
(
NanoTimeArgument
n
,
char
*
buf
,
size_t
len
);
void
to_string
(
MemorySizeArgument
f
,
char
*
buf
,
size_t
len
);
void
to_string
(
StringArrayArgument
*
s
,
char
*
buf
,
size_t
len
);
};
template
<
class
ArgType
>
class
DCmdArgument
:
public
GenDCmdArgument
{
...
...
@@ -143,6 +151,7 @@ public:
void
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
);
void
init_value
(
TRAPS
);
void
destroy_value
();
void
value_as_str
(
char
*
buf
,
size_t
len
)
{
return
to_string
(
_value
,
buf
,
len
);}
};
#endif
/* SHARE_VM_SERVICES_DIAGNOSTICARGUMENT_HPP */
test/serviceability/ParserTest.java
0 → 100644
浏览文件 @
074d68f2
/*
* @test ParserTest
* @summary verify that whitebox functions can be linked and executed
* @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI ParserTest.java
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest
*/
import
java.math.BigInteger
;
import
sun.hotspot.parser.DiagnosticCommand
;
import
sun.hotspot.parser.DiagnosticCommand.DiagnosticArgumentType
;
import
sun.hotspot.WhiteBox
;
public
class
ParserTest
{
WhiteBox
wb
;
public
ParserTest
()
throws
Exception
{
wb
=
WhiteBox
.
getWhiteBox
();
testNanoTime
();
testJLong
();
testBool
();
testMemorySize
();
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
new
ParserTest
();
}
public
void
testNanoTime
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
NANOTIME
,
false
,
"0"
);
DiagnosticCommand
[]
args
=
{
arg
};
BigInteger
bi
=
new
BigInteger
(
"7"
);
//These should work
parse
(
name
,
bi
.
toString
(),
name
+
"=7ns"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7us"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7ms"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7s"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
60
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7m"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
60
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7h"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
24
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7d"
,
args
);
parse
(
name
,
"0"
,
name
+
"=0"
,
args
);
shouldFail
(
name
+
"=7xs"
,
args
);
shouldFail
(
name
+
"=7mms"
,
args
);
shouldFail
(
name
+
"=7f"
,
args
);
//Currently, only value 0 is allowed without unit
shouldFail
(
name
+
"=7"
,
args
);
}
public
void
testJLong
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
JLONG
,
false
,
"0"
);
DiagnosticCommand
[]
args
=
{
arg
};
wb
.
parseCommandLine
(
name
+
"=10"
,
args
);
parse
(
name
,
"10"
,
name
+
"=10"
,
args
);
parse
(
name
,
"-5"
,
name
+
"=-5"
,
args
);
//shouldFail(name + "=12m", args); <-- should fail, doesn't
}
public
void
testBool
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
BOOLEAN
,
false
,
"false"
);
DiagnosticCommand
[]
args
=
{
arg
};
parse
(
name
,
"true"
,
name
+
"=true"
,
args
);
parse
(
name
,
"false"
,
name
+
"=false"
,
args
);
parse
(
name
,
"true"
,
name
,
args
);
//Empty commandline to parse, tests default value
//of the parameter "name"
parse
(
name
,
"false"
,
""
,
args
);
}
public
void
testMemorySize
()
throws
Exception
{
String
name
=
"name"
;
String
defaultValue
=
"1024"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
MEMORYSIZE
,
false
,
defaultValue
);
DiagnosticCommand
[]
args
=
{
arg
};
BigInteger
bi
=
new
BigInteger
(
"7"
);
parse
(
name
,
bi
.
toString
(),
name
+
"=7b"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7k"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7m"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7g"
,
args
);
parse
(
name
,
defaultValue
,
""
,
args
);
//shouldFail(name + "=7gg", args); <---- should fail, doesn't
//shouldFail(name + "=7t", args); <----- should fail, doesn't
}
public
void
parse
(
String
searchName
,
String
expectedValue
,
String
cmdLine
,
DiagnosticCommand
[]
argumentTypes
)
throws
Exception
{
//parseCommandLine will return an object array that looks like
//{<name of parsed object>, <of parsed object> ... }
Object
[]
res
=
wb
.
parseCommandLine
(
cmdLine
,
argumentTypes
);
for
(
int
i
=
0
;
i
<
res
.
length
-
1
;
i
+=
2
)
{
String
parsedName
=
(
String
)
res
[
i
];
if
(
searchName
.
equals
(
parsedName
))
{
String
parsedValue
=
(
String
)
res
[
i
+
1
];
if
(
expectedValue
.
equals
(
parsedValue
))
{
return
;
}
else
{
throw
new
Exception
(
"Parsing of cmdline '"
+
cmdLine
+
"' failed!\n"
+
searchName
+
" parsed as "
+
parsedValue
+
"! Expected: "
+
expectedValue
);
}
}
}
throw
new
Exception
(
searchName
+
" not found as a parsed Argument!"
);
}
private
void
shouldFail
(
String
argument
,
DiagnosticCommand
[]
argumentTypes
)
throws
Exception
{
try
{
wb
.
parseCommandLine
(
argument
,
argumentTypes
);
throw
new
Exception
(
"Parser accepted argument: "
+
argument
);
}
catch
(
IllegalArgumentException
e
)
{
//expected
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录