Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
927182ae
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
927182ae
编写于
6月 20, 2014
作者:
D
dcubed
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
c4f34292
44e5192e
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
320 addition
and
187 deletion
+320
-187
hotspot/src/share/vm/ci/ciEnv.cpp
hotspot/src/share/vm/ci/ciEnv.cpp
+2
-17
hotspot/src/share/vm/ci/ciReplay.cpp
hotspot/src/share/vm/ci/ciReplay.cpp
+2
-2
hotspot/src/share/vm/classfile/classFileParser.cpp
hotspot/src/share/vm/classfile/classFileParser.cpp
+5
-5
hotspot/src/share/vm/classfile/classLoaderData.hpp
hotspot/src/share/vm/classfile/classLoaderData.hpp
+2
-2
hotspot/src/share/vm/classfile/javaClasses.cpp
hotspot/src/share/vm/classfile/javaClasses.cpp
+25
-2
hotspot/src/share/vm/classfile/javaClasses.hpp
hotspot/src/share/vm/classfile/javaClasses.hpp
+7
-1
hotspot/src/share/vm/classfile/vmSymbols.hpp
hotspot/src/share/vm/classfile/vmSymbols.hpp
+1
-0
hotspot/src/share/vm/oops/arrayKlass.cpp
hotspot/src/share/vm/oops/arrayKlass.cpp
+1
-1
hotspot/src/share/vm/oops/constantPool.cpp
hotspot/src/share/vm/oops/constantPool.cpp
+88
-134
hotspot/src/share/vm/oops/constantPool.hpp
hotspot/src/share/vm/oops/constantPool.hpp
+4
-12
hotspot/src/share/vm/oops/cpCache.cpp
hotspot/src/share/vm/oops/cpCache.cpp
+3
-1
hotspot/src/share/vm/oops/klass.cpp
hotspot/src/share/vm/oops/klass.cpp
+1
-1
hotspot/src/share/vm/oops/objArrayOop.cpp
hotspot/src/share/vm/oops/objArrayOop.cpp
+17
-1
hotspot/src/share/vm/oops/objArrayOop.hpp
hotspot/src/share/vm/oops/objArrayOop.hpp
+4
-1
hotspot/src/share/vm/prims/jvmtiEnv.cpp
hotspot/src/share/vm/prims/jvmtiEnv.cpp
+1
-6
hotspot/src/share/vm/prims/unsafe.cpp
hotspot/src/share/vm/prims/unsafe.cpp
+9
-1
hotspot/test/runtime/verifier/TestANewArray.java
hotspot/test/runtime/verifier/TestANewArray.java
+148
-0
未找到文件。
hotspot/src/share/vm/ci/ciEnv.cpp
浏览文件 @
927182ae
...
...
@@ -512,24 +512,9 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
}
else
{
// Check if it's resolved if it's not a symbol constant pool entry.
klass
=
KlassHandle
(
THREAD
,
ConstantPool
::
klass_at_if_loaded
(
cpool
,
index
));
if
(
klass
.
is_null
())
{
// The klass has not been inserted into the constant pool.
// Try to look it up by name.
{
// We have to lock the cpool to keep the oop from being resolved
// while we are accessing it.
MonitorLockerEx
ml
(
cpool
->
lock
());
constantTag
tag
=
cpool
->
tag_at
(
index
);
if
(
tag
.
is_klass
())
{
// The klass has been inserted into the constant pool
// very recently.
klass
=
KlassHandle
(
THREAD
,
cpool
->
resolved_klass_at
(
index
));
}
else
{
assert
(
cpool
->
tag_at
(
index
).
is_unresolved_klass
(),
"wrong tag"
);
klass_name
=
cpool
->
unresolved_klass_at
(
index
);
}
}
if
(
klass
.
is_null
())
{
klass_name
=
cpool
->
klass_name_at
(
index
);
}
}
...
...
hotspot/src/share/vm/ci/ciReplay.cpp
浏览文件 @
927182ae
/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2013,
2014,
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
...
...
@@ -686,7 +686,7 @@ class CompileReplay : public StackObj {
switch
(
cp
->
tag_at
(
i
).
value
())
{
case
JVM_CONSTANT_UnresolvedClass
:
{
if
(
tag
==
JVM_CONSTANT_Class
)
{
tty
->
print_cr
(
"Resolving klass %s at %d"
,
cp
->
unresolved_klass
_at
(
i
)
->
as_utf8
(),
i
);
tty
->
print_cr
(
"Resolving klass %s at %d"
,
cp
->
klass_name
_at
(
i
)
->
as_utf8
(),
i
);
Klass
*
k
=
cp
->
klass_at
(
i
,
CHECK
);
}
break
;
...
...
hotspot/src/share/vm/classfile/classFileParser.cpp
浏览文件 @
927182ae
...
...
@@ -510,7 +510,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
jbyte
tag
=
cp
->
tag_at
(
index
).
value
();
switch
(
tag
)
{
case
JVM_CONSTANT_UnresolvedClass
:
{
Symbol
*
class_name
=
cp
->
unresolved_klass
_at
(
index
);
Symbol
*
class_name
=
cp
->
klass_name
_at
(
index
);
// check the name, even if _cp_patches will overwrite it
verify_legal_class_name
(
class_name
,
CHECK_
(
nullHandle
));
break
;
...
...
@@ -3161,7 +3161,7 @@ instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index,
if
(
_need_verify
)
is_array
=
super_klass
->
oop_is_array
();
}
else
if
(
_need_verify
)
{
is_array
=
(
_cp
->
unresolved_klass
_at
(
super_class_index
)
->
byte_at
(
0
)
==
JVM_SIGNATURE_ARRAY
);
is_array
=
(
_cp
->
klass_name
_at
(
super_class_index
)
->
byte_at
(
0
)
==
JVM_SIGNATURE_ARRAY
);
}
if
(
_need_verify
)
{
guarantee_property
(
!
is_array
,
...
...
@@ -3855,7 +3855,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
"Invalid this class index %u in constant pool in class file %s"
,
this_class_index
,
CHECK_
(
nullHandle
));
Symbol
*
class_name
=
cp
->
unresolved_klass
_at
(
this_class_index
);
Symbol
*
class_name
=
cp
->
klass_name
_at
(
this_class_index
);
assert
(
class_name
!=
NULL
,
"class_name can't be null"
);
// It's important to set parsed_name *before* resolving the super class.
...
...
@@ -4139,8 +4139,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
// Allocate mirror and initialize static fields
java_lang_Class
::
create_mirror
(
this_klass
,
protection_domain
,
CHECK_
(
nullHandle
));
java_lang_Class
::
create_mirror
(
this_klass
,
class_loader
,
protection_domain
,
CHECK_
(
nullHandle
));
// Generate any default methods - default methods are interface methods
// that have a default implementation. This is new with Lambda project.
...
...
hotspot/src/share/vm/classfile/classLoaderData.hpp
浏览文件 @
927182ae
...
...
@@ -187,8 +187,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
JNIHandleBlock
*
handles
()
const
;
void
set_handles
(
JNIHandleBlock
*
handles
);
Mutex
*
metaspace_lock
()
const
{
return
_metaspace_lock
;
}
// GC interface.
void
clear_claimed
()
{
_claimed
=
0
;
}
bool
claimed
()
const
{
return
_claimed
==
1
;
}
...
...
@@ -216,6 +214,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
return
_the_null_class_loader_data
;
}
Mutex
*
metaspace_lock
()
const
{
return
_metaspace_lock
;
}
bool
is_anonymous
()
const
{
return
_is_anonymous
;
}
static
void
init_null_class_loader_data
()
{
...
...
hotspot/src/share/vm/classfile/javaClasses.cpp
浏览文件 @
927182ae
...
...
@@ -558,7 +558,7 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
}
}
}
create_mirror
(
k
,
Handle
(
NULL
),
CHECK
);
create_mirror
(
k
,
Handle
(
NULL
),
Handle
(
NULL
),
CHECK
);
}
void
java_lang_Class
::
initialize_mirror_fields
(
KlassHandle
k
,
...
...
@@ -578,7 +578,8 @@ void java_lang_Class::initialize_mirror_fields(KlassHandle k,
InstanceKlass
::
cast
(
k
())
->
do_local_static_fields
(
&
initialize_static_field
,
mirror
,
CHECK
);
}
void
java_lang_Class
::
create_mirror
(
KlassHandle
k
,
Handle
protection_domain
,
TRAPS
)
{
void
java_lang_Class
::
create_mirror
(
KlassHandle
k
,
Handle
class_loader
,
Handle
protection_domain
,
TRAPS
)
{
assert
(
k
->
java_mirror
()
==
NULL
,
"should only assign mirror once"
);
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
...
...
@@ -633,6 +634,9 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRA
}
}
// set the classLoader field in the java_lang_Class instance
set_class_loader
(
mirror
(),
class_loader
());
// Setup indirection from klass->mirror last
// after any exceptions can happen during allocations.
if
(
!
k
.
is_null
())
{
...
...
@@ -694,6 +698,18 @@ void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
}
void
java_lang_Class
::
set_class_loader
(
oop
java_class
,
oop
loader
)
{
// jdk7 runs Queens in bootstrapping and jdk8-9 has no coordinated pushes yet.
if
(
_class_loader_offset
!=
0
)
{
java_class
->
obj_field_put
(
_class_loader_offset
,
loader
);
}
}
oop
java_lang_Class
::
class_loader
(
oop
java_class
)
{
assert
(
_class_loader_offset
!=
0
,
"must be set"
);
return
java_class
->
obj_field
(
_class_loader_offset
);
}
oop
java_lang_Class
::
create_basic_type_mirror
(
const
char
*
basic_type_name
,
BasicType
type
,
TRAPS
)
{
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
...
...
@@ -853,6 +869,12 @@ void java_lang_Class::compute_offsets() {
compute_optional_offset
(
classRedefinedCount_offset
,
klass_oop
,
vmSymbols
::
classRedefinedCount_name
(),
vmSymbols
::
int_signature
());
// Needs to be optional because the old build runs Queens during bootstrapping
// and jdk8-9 doesn't have coordinated pushes yet.
compute_optional_offset
(
_class_loader_offset
,
klass_oop
,
vmSymbols
::
classLoader_name
(),
vmSymbols
::
classloader_signature
());
CLASS_INJECTED_FIELDS
(
INJECTED_FIELD_COMPUTE_OFFSET
);
}
...
...
@@ -3073,6 +3095,7 @@ int java_lang_Class::_klass_offset;
int
java_lang_Class
::
_array_klass_offset
;
int
java_lang_Class
::
_oop_size_offset
;
int
java_lang_Class
::
_static_oop_field_count_offset
;
int
java_lang_Class
::
_class_loader_offset
;
int
java_lang_Class
::
_protection_domain_offset
;
int
java_lang_Class
::
_init_lock_offset
;
int
java_lang_Class
::
_signers_offset
;
...
...
hotspot/src/share/vm/classfile/javaClasses.hpp
浏览文件 @
927182ae
...
...
@@ -240,19 +240,23 @@ class java_lang_Class : AllStatic {
static
int
_protection_domain_offset
;
static
int
_init_lock_offset
;
static
int
_signers_offset
;
static
int
_class_loader_offset
;
static
bool
offsets_computed
;
static
int
classRedefinedCount_offset
;
static
GrowableArray
<
Klass
*>*
_fixup_mirror_list
;
static
void
set_init_lock
(
oop
java_class
,
oop
init_lock
);
static
void
set_protection_domain
(
oop
java_class
,
oop
protection_domain
);
static
void
set_class_loader
(
oop
java_class
,
oop
class_loader
);
static
void
initialize_mirror_fields
(
KlassHandle
k
,
Handle
mirror
,
Handle
protection_domain
,
TRAPS
);
public:
static
void
compute_offsets
();
// Instance creation
static
void
create_mirror
(
KlassHandle
k
,
Handle
protection_domain
,
TRAPS
);
static
void
create_mirror
(
KlassHandle
k
,
Handle
class_loader
,
Handle
protection_domain
,
TRAPS
);
static
void
fixup_mirror
(
KlassHandle
k
,
TRAPS
);
static
oop
create_basic_type_mirror
(
const
char
*
basic_type_name
,
BasicType
type
,
TRAPS
);
// Conversion
...
...
@@ -290,6 +294,8 @@ class java_lang_Class : AllStatic {
static
objArrayOop
signers
(
oop
java_class
);
static
void
set_signers
(
oop
java_class
,
objArrayOop
signers
);
static
oop
class_loader
(
oop
java_class
);
static
int
oop_size
(
oop
java_class
);
static
void
set_oop_size
(
oop
java_class
,
int
size
);
static
int
static_oop_field_count
(
oop
java_class
);
...
...
hotspot/src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
927182ae
...
...
@@ -572,6 +572,7 @@
template(serializePropertiesToByteArray_signature, "()[B") \
template(serializeAgentPropertiesToByteArray_name, "serializeAgentPropertiesToByteArray") \
template(classRedefinedCount_name, "classRedefinedCount") \
template(classLoader_name, "classLoader") \
\
/* trace signatures */
\
TRACE_TEMPLATES(template) \
...
...
hotspot/src/share/vm/oops/arrayKlass.cpp
浏览文件 @
927182ae
...
...
@@ -93,7 +93,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_kl
ResourceMark
rm
(
THREAD
);
k
->
initialize_supers
(
super_klass
(),
CHECK
);
k
->
vtable
()
->
initialize_vtable
(
false
,
CHECK
);
java_lang_Class
::
create_mirror
(
k
,
Handle
(
NULL
),
CHECK
);
java_lang_Class
::
create_mirror
(
k
,
Handle
(
NULL
),
Handle
(
NULL
),
CHECK
);
}
GrowableArray
<
Klass
*>*
ArrayKlass
::
compute_secondary_supers
(
int
num_extra_slots
)
{
...
...
hotspot/src/share/vm/oops/constantPool.cpp
浏览文件 @
927182ae
...
...
@@ -71,7 +71,6 @@ ConstantPool::ConstantPool(Array<u1>* tags) {
// only set to non-zero if constant pool is merged by RedefineClasses
set_version
(
0
);
set_lock
(
new
Monitor
(
Monitor
::
nonleaf
+
2
,
"A constant pool lock"
));
// initialize tag array
int
length
=
tags
->
length
();
...
...
@@ -100,9 +99,6 @@ void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) {
void
ConstantPool
::
release_C_heap_structures
()
{
// walk constant pool and decrement symbol reference counts
unreference_symbols
();
delete
_lock
;
set_lock
(
NULL
);
}
objArrayOop
ConstantPool
::
resolved_references
()
const
{
...
...
@@ -146,8 +142,7 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
// CDS support. Create a new resolved_references array.
void
ConstantPool
::
restore_unshareable_info
(
TRAPS
)
{
// Only create the new resolved references array and lock if it hasn't been
// attempted before
// Only create the new resolved references array if it hasn't been attempted before
if
(
resolved_references
()
!=
NULL
)
return
;
// restore the C++ vtable from the shared archive
...
...
@@ -163,9 +158,6 @@ void ConstantPool::restore_unshareable_info(TRAPS) {
ClassLoaderData
*
loader_data
=
pool_holder
()
->
class_loader_data
();
set_resolved_references
(
loader_data
->
add_handle
(
refs_handle
));
}
// Also need to recreate the mutex. Make sure this matches the constructor
set_lock
(
new
Monitor
(
Monitor
::
nonleaf
+
2
,
"A constant pool lock"
));
}
}
...
...
@@ -176,7 +168,6 @@ void ConstantPool::remove_unshareable_info() {
set_resolved_reference_length
(
resolved_references
()
!=
NULL
?
resolved_references
()
->
length
()
:
0
);
set_resolved_references
(
NULL
);
set_lock
(
NULL
);
}
int
ConstantPool
::
cp_to_object_index
(
int
cp_index
)
{
...
...
@@ -186,11 +177,41 @@ int ConstantPool::cp_to_object_index(int cp_index) {
return
(
i
<
0
)
?
_no_index_sentinel
:
i
;
}
void
ConstantPool
::
trace_class_resolution
(
constantPoolHandle
this_cp
,
KlassHandle
k
)
{
ResourceMark
rm
;
int
line_number
=
-
1
;
const
char
*
source_file
=
NULL
;
if
(
JavaThread
::
current
()
->
has_last_Java_frame
())
{
// try to identify the method which called this function.
vframeStream
vfst
(
JavaThread
::
current
());
if
(
!
vfst
.
at_end
())
{
line_number
=
vfst
.
method
()
->
line_number_from_bci
(
vfst
.
bci
());
Symbol
*
s
=
vfst
.
method
()
->
method_holder
()
->
source_file_name
();
if
(
s
!=
NULL
)
{
source_file
=
s
->
as_C_string
();
}
}
}
if
(
k
()
!=
this_cp
->
pool_holder
())
{
// only print something if the classes are different
if
(
source_file
!=
NULL
)
{
tty
->
print
(
"RESOLVE %s %s %s:%d
\n
"
,
this_cp
->
pool_holder
()
->
external_name
(),
InstanceKlass
::
cast
(
k
())
->
external_name
(),
source_file
,
line_number
);
}
else
{
tty
->
print
(
"RESOLVE %s %s
\n
"
,
this_cp
->
pool_holder
()
->
external_name
(),
InstanceKlass
::
cast
(
k
())
->
external_name
());
}
}
}
Klass
*
ConstantPool
::
klass_at_impl
(
constantPoolHandle
this_cp
,
int
which
,
TRAPS
)
{
// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
// tag is not updated atomicly.
assert
(
THREAD
->
is_Java_thread
(),
"must be a Java thread"
);
// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
// It is not safe to rely on the tag bit's here, since we don't have a lock, and
// the entry and tag is not updated atomicly.
CPSlot
entry
=
this_cp
->
slot_at
(
which
);
if
(
entry
.
is_resolved
())
{
assert
(
entry
.
get_klass
()
->
is_klass
(),
"must be"
);
...
...
@@ -198,115 +219,51 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS)
return
entry
.
get_klass
();
}
// Acquire lock on constant oop while doing update. After we get the lock, we check if another object
// already has updated the object
assert
(
THREAD
->
is_Java_thread
(),
"must be a Java thread"
);
bool
do_resolve
=
false
;
bool
in_error
=
false
;
// Create a handle for the mirror. This will preserve the resolved class
// until the loader_data is registered.
Handle
mirror_handle
;
Symbol
*
name
=
NULL
;
Handle
loader
;
{
MonitorLockerEx
ml
(
this_cp
->
lock
());
if
(
this_cp
->
tag_at
(
which
).
is_unresolved_klass
())
{
if
(
this_cp
->
tag_at
(
which
).
is_unresolved_klass_in_error
())
{
in_error
=
true
;
}
else
{
do_resolve
=
true
;
name
=
this_cp
->
unresolved_klass_at
(
which
);
loader
=
Handle
(
THREAD
,
this_cp
->
pool_holder
()
->
class_loader
());
}
}
}
// unlocking constantPool
// The original attempt to resolve this constant pool entry failed so find the
// class of the original error and throw another error of the same class (JVMS 5.4.3).
// If there is a detail message, pass that detail message to the error constructor.
// The JVMS does not strictly require us to duplicate the same detail message,
// or any internal exception fields such as cause or stacktrace. But since the
// detail message is often a class name or other literal string, we will repeat it if
// we can find it in the symbol table.
if
(
in_error
)
{
// This tag doesn't change back to unresolved class unless at a safepoint.
if
(
this_cp
->
tag_at
(
which
).
is_unresolved_klass_in_error
())
{
// The original attempt to resolve this constant pool entry failed so find the
// class of the original error and throw another error of the same class
// (JVMS 5.4.3).
// If there is a detail message, pass that detail message to the error.
// The JVMS does not strictly require us to duplicate the same detail message,
// or any internal exception fields such as cause or stacktrace. But since the
// detail message is often a class name or other literal string, we will repeat it
// if we can find it in the symbol table.
throw_resolution_error
(
this_cp
,
which
,
CHECK_0
);
ShouldNotReachHere
();
}
if
(
do_resolve
)
{
// this_cp must be unlocked during resolve_or_fail
oop
protection_domain
=
this_cp
->
pool_holder
()
->
protection_domain
();
Handle
h_prot
(
THREAD
,
protection_domain
);
Klass
*
kk
=
SystemDictionary
::
resolve_or_fail
(
name
,
loader
,
h_prot
,
true
,
THREAD
);
KlassHandle
k
;
if
(
!
HAS_PENDING_EXCEPTION
)
{
k
=
KlassHandle
(
THREAD
,
kk
);
// preserve the resolved klass.
mirror_handle
=
Handle
(
THREAD
,
kk
->
java_mirror
());
// Do access check for klasses
verify_constant_pool_resolve
(
this_cp
,
k
,
THREAD
);
}
// Failed to resolve class. We must record the errors so that subsequent attempts
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
if
(
HAS_PENDING_EXCEPTION
)
{
MonitorLockerEx
ml
(
this_cp
->
lock
());
Handle
mirror_handle
;
Symbol
*
name
=
entry
.
get_symbol
();
Handle
loader
(
THREAD
,
this_cp
->
pool_holder
()
->
class_loader
());
Handle
protection_domain
(
THREAD
,
this_cp
->
pool_holder
()
->
protection_domain
());
Klass
*
kk
=
SystemDictionary
::
resolve_or_fail
(
name
,
loader
,
protection_domain
,
true
,
THREAD
);
KlassHandle
k
(
THREAD
,
kk
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
// preserve the resolved klass from unloading
mirror_handle
=
Handle
(
THREAD
,
kk
->
java_mirror
());
// Do access check for klasses
verify_constant_pool_resolve
(
this_cp
,
k
,
THREAD
);
}
// some other thread has beaten us and has resolved the class.
if
(
this_cp
->
tag_at
(
which
).
is_klass
())
{
CLEAR_PENDING_EXCEPTION
;
entry
=
this_cp
->
resolved_klass_at
(
which
);
return
entry
.
get_klass
();
}
// Failed to resolve class. We must record the errors so that subsequent attempts
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
if
(
HAS_PENDING_EXCEPTION
)
{
save_and_throw_exception
(
this_cp
,
which
,
constantTag
(
JVM_CONSTANT_UnresolvedClass
),
CHECK_0
);
}
// The tag could have changed to in-error before the lock but we have to
// handle that here for the class case.
save_and_throw_exception
(
this_cp
,
which
,
constantTag
(
JVM_CONSTANT_UnresolvedClass
),
CHECK_0
);
}
// Make this class loader depend upon the class loader owning the class reference
ClassLoaderData
*
this_key
=
this_cp
->
pool_holder
()
->
class_loader_data
();
this_key
->
record_dependency
(
k
(),
CHECK_NULL
);
// Can throw OOM
if
(
TraceClassResolution
&&
!
k
()
->
oop_is_array
())
{
// skip resolving the constant pool so that this code get's
// called the next time some bytecodes refer to this class.
ResourceMark
rm
;
int
line_number
=
-
1
;
const
char
*
source_file
=
NULL
;
if
(
JavaThread
::
current
()
->
has_last_Java_frame
())
{
// try to identify the method which called this function.
vframeStream
vfst
(
JavaThread
::
current
());
if
(
!
vfst
.
at_end
())
{
line_number
=
vfst
.
method
()
->
line_number_from_bci
(
vfst
.
bci
());
Symbol
*
s
=
vfst
.
method
()
->
method_holder
()
->
source_file_name
();
if
(
s
!=
NULL
)
{
source_file
=
s
->
as_C_string
();
}
}
}
if
(
k
()
!=
this_cp
->
pool_holder
())
{
// only print something if the classes are different
if
(
source_file
!=
NULL
)
{
tty
->
print
(
"RESOLVE %s %s %s:%d
\n
"
,
this_cp
->
pool_holder
()
->
external_name
(),
InstanceKlass
::
cast
(
k
())
->
external_name
(),
source_file
,
line_number
);
}
else
{
tty
->
print
(
"RESOLVE %s %s
\n
"
,
this_cp
->
pool_holder
()
->
external_name
(),
InstanceKlass
::
cast
(
k
())
->
external_name
());
}
}
if
(
TraceClassResolution
&&
!
k
->
oop_is_array
())
{
// skip resolving the constant pool so that this code gets
// called the next time some bytecodes refer to this class.
trace_class_resolution
(
this_cp
,
k
);
return
k
();
}
else
{
MonitorLockerEx
ml
(
this_cp
->
lock
());
// Only updated constant pool - if it is resolved.
do_resolve
=
this_cp
->
tag_at
(
which
).
is_unresolved_klass
();
if
(
do_resolve
)
{
ClassLoaderData
*
this_key
=
this_cp
->
pool_holder
()
->
class_loader_data
();
this_key
->
record_dependency
(
k
(),
CHECK_NULL
);
// Can throw OOM
this_cp
->
klass_at_put
(
which
,
k
());
}
}
}
entry
=
this_cp
->
resolved_klass_at
(
which
);
assert
(
entry
.
is_resolved
()
&&
entry
.
get_klass
()
->
is_klass
(),
"must be resolved at this point"
);
...
...
@@ -576,7 +533,7 @@ Symbol* ConstantPool::exception_message(constantPoolHandle this_cp, int which, c
switch
(
tag
.
value
())
{
case
JVM_CONSTANT_UnresolvedClass
:
// return the class name in the error message
message
=
this_cp
->
unresolved_klass
_at
(
which
);
message
=
this_cp
->
klass_name
_at
(
which
);
break
;
case
JVM_CONSTANT_MethodHandle
:
// return the method handle name in the error message
...
...
@@ -606,7 +563,6 @@ void ConstantPool::throw_resolution_error(constantPoolHandle this_cp, int which,
// in the resolution error table, so that the same exception is thrown again.
void
ConstantPool
::
save_and_throw_exception
(
constantPoolHandle
this_cp
,
int
which
,
constantTag
tag
,
TRAPS
)
{
assert
(
this_cp
->
lock
()
->
is_locked
(),
"constant pool lock should be held"
);
Symbol
*
error
=
PENDING_EXCEPTION
->
klass
()
->
name
();
int
error_tag
=
tag
.
error_value
();
...
...
@@ -620,7 +576,14 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int whic
}
else
if
(
this_cp
->
tag_at
(
which
).
value
()
!=
error_tag
)
{
Symbol
*
message
=
exception_message
(
this_cp
,
which
,
tag
,
PENDING_EXCEPTION
);
SystemDictionary
::
add_resolution_error
(
this_cp
,
which
,
error
,
message
);
this_cp
->
tag_at_put
(
which
,
error_tag
);
// CAS in the tag. If a thread beat us to registering this error that's fine.
// If another thread resolved the reference, this is an error. The resolution
// must deterministically get an error. So why do we save this?
// We save this because jvmti can add classes to the bootclass path after this
// error, so it needs to get the same error if the error is first.
jbyte
old_tag
=
Atomic
::
cmpxchg
((
jbyte
)
error_tag
,
(
jbyte
*
)
this_cp
->
tag_addr_at
(
which
),
(
jbyte
)
tag
.
value
());
assert
(
old_tag
==
error_tag
||
old_tag
==
tag
.
value
(),
"should not be resolved otherwise"
);
}
else
{
// some other thread put this in error state
throw_resolution_error
(
this_cp
,
which
,
CHECK
);
...
...
@@ -710,7 +673,6 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
THREAD
);
result_oop
=
value
();
if
(
HAS_PENDING_EXCEPTION
)
{
MonitorLockerEx
ml
(
this_cp
->
lock
());
// lock cpool to change tag.
save_and_throw_exception
(
this_cp
,
index
,
tag
,
CHECK_NULL
);
}
break
;
...
...
@@ -727,7 +689,6 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
Handle
value
=
SystemDictionary
::
find_method_handle_type
(
signature
,
klass
,
THREAD
);
result_oop
=
value
();
if
(
HAS_PENDING_EXCEPTION
)
{
MonitorLockerEx
ml
(
this_cp
->
lock
());
// lock cpool to change tag.
save_and_throw_exception
(
this_cp
,
index
,
tag
,
CHECK_NULL
);
}
break
;
...
...
@@ -765,22 +726,17 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
}
if
(
cache_index
>=
0
)
{
// Cache the oop here also.
Handle
result_handle
(
THREAD
,
result_oop
);
MonitorLockerEx
ml
(
this_cp
->
lock
());
// don't know if we really need this
oop
result
=
this_cp
->
resolved_references
()
->
obj_at
(
cache_index
);
// Benign race condition: resolved_references may already be filled in while we were trying to lock.
// Benign race condition: resolved_references may already be filled in.
// The important thing here is that all threads pick up the same result.
// It doesn't matter which racing thread wins, as long as only one
// result is used by all threads, and all future queries.
// That result may be either a resolved constant or a failure exception.
if
(
result
==
NULL
)
{
this_cp
->
resolved_references
()
->
obj_at_put
(
cache_index
,
result_handle
());
return
result_handle
();
oop
old_result
=
this_cp
->
resolved_references
()
->
atomic_compare_exchange_oop
(
cache_index
,
result_oop
,
NULL
);
if
(
old_result
==
NULL
)
{
return
result_oop
;
// was installed
}
else
{
// Return the winning thread's result. This can be different than
//
result_handle()
for MethodHandles.
return
result
;
//
the result here
for MethodHandles.
return
old_
result
;
}
}
else
{
return
result_oop
;
...
...
@@ -853,9 +809,8 @@ bool ConstantPool::klass_name_at_matches(instanceKlassHandle k,
}
// Iterate over symbols and decrement ones which are Symbol*s.
// This is done during GC so do not need to lock constantPool unless we
// have per-thread safepoints.
// Iterate over symbols and decrement ones which are Symbol*s
// This is done during GC.
// Only decrement the UTF8 symbols. Unresolved classes and strings point to
// these symbols but didn't increment the reference count.
void
ConstantPool
::
unreference_symbols
()
{
...
...
@@ -987,8 +942,8 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
case
JVM_CONSTANT_UnresolvedClass
:
{
Symbol
*
k1
=
unresolved_klass
_at
(
index1
);
Symbol
*
k2
=
cp2
->
unresolved_klass
_at
(
index2
);
Symbol
*
k1
=
klass_name
_at
(
index1
);
Symbol
*
k2
=
cp2
->
klass_name
_at
(
index2
);
if
(
k1
==
k2
)
{
return
true
;
}
...
...
@@ -1970,7 +1925,6 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) {
break
;
case
JVM_CONSTANT_UnresolvedClass
:
// fall-through
case
JVM_CONSTANT_UnresolvedClassInError
:
{
// unresolved_klass_at requires lock or safe world.
CPSlot
entry
=
slot_at
(
index
);
if
(
entry
.
is_resolved
())
{
entry
.
get_klass
()
->
print_value_on
(
st
);
...
...
hotspot/src/share/vm/oops/constantPool.hpp
浏览文件 @
927182ae
...
...
@@ -112,12 +112,12 @@ class ConstantPool : public Metadata {
int
_version
;
}
_saved
;
Monitor
*
_lock
;
void
set_tags
(
Array
<
u1
>*
tags
)
{
_tags
=
tags
;
}
void
tag_at_put
(
int
which
,
jbyte
t
)
{
tags
()
->
at_put
(
which
,
t
);
}
void
release_tag_at_put
(
int
which
,
jbyte
t
)
{
tags
()
->
release_at_put
(
which
,
t
);
}
u1
*
tag_addr_at
(
int
which
)
const
{
return
tags
()
->
adr_at
(
which
);
}
void
set_operands
(
Array
<
u2
>*
operands
)
{
_operands
=
operands
;
}
int
flags
()
const
{
return
_flags
;
}
...
...
@@ -362,14 +362,6 @@ class ConstantPool : public Metadata {
return
CPSlot
((
Klass
*
)
OrderAccess
::
load_ptr_acquire
(
obj_at_addr_raw
(
which
))).
get_klass
();
}
// This method should only be used with a cpool lock or during parsing or gc
Symbol
*
unresolved_klass_at
(
int
which
)
{
// Temporary until actual use
Symbol
*
s
=
CPSlot
((
Symbol
*
)
OrderAccess
::
load_ptr_acquire
(
obj_at_addr_raw
(
which
))).
get_symbol
();
// check that the klass is still unresolved.
assert
(
tag_at
(
which
).
is_unresolved_klass
(),
"Corrupted constant pool"
);
return
s
;
}
// RedefineClasses() API support:
Symbol
*
klass_at_noresolve
(
int
which
)
{
return
klass_name_at
(
which
);
}
...
...
@@ -818,6 +810,8 @@ class ConstantPool : public Metadata {
static
Klass
*
klass_at_impl
(
constantPoolHandle
this_cp
,
int
which
,
TRAPS
);
static
oop
string_at_impl
(
constantPoolHandle
this_cp
,
int
which
,
int
obj_index
,
TRAPS
);
static
void
trace_class_resolution
(
constantPoolHandle
this_cp
,
KlassHandle
k
);
// Resolve string constants (to prevent allocation during compilation)
static
void
resolve_string_constants_impl
(
constantPoolHandle
this_cp
,
TRAPS
);
...
...
@@ -848,8 +842,6 @@ class ConstantPool : public Metadata {
void
set_resolved_reference_length
(
int
length
)
{
_saved
.
_resolved_reference_length
=
length
;
}
int
resolved_reference_length
()
const
{
return
_saved
.
_resolved_reference_length
;
}
void
set_lock
(
Monitor
*
lock
)
{
_lock
=
lock
;
}
Monitor
*
lock
()
{
return
_lock
;
}
// Decrease ref counts of symbols that are in the constant pool
// when the holder class is unloaded
...
...
hotspot/src/share/vm/oops/cpCache.cpp
浏览文件 @
927182ae
...
...
@@ -286,7 +286,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
// the lock, so that when the losing writer returns, he can use the linked
// cache entry.
MonitorLockerEx
ml
(
cpool
->
lock
());
// Use the lock from the metaspace for this, which cannot stop for safepoint.
Mutex
*
metaspace_lock
=
cpool
->
pool_holder
()
->
class_loader_data
()
->
metaspace_lock
();
MutexLockerEx
ml
(
metaspace_lock
,
Mutex
::
_no_safepoint_check_flag
);
if
(
!
is_f1_null
())
{
return
;
}
...
...
hotspot/src/share/vm/oops/klass.cpp
浏览文件 @
927182ae
...
...
@@ -508,7 +508,7 @@ void Klass::restore_unshareable_info(TRAPS) {
// Only recreate it if not present. A previous attempt to restore may have
// gotten an OOM later but keep the mirror if it was created.
if
(
java_mirror
()
==
NULL
)
{
java_lang_Class
::
create_mirror
(
this
,
Handle
(
NULL
),
CHECK
);
java_lang_Class
::
create_mirror
(
this
,
Handle
(
NULL
),
Handle
(
NULL
),
CHECK
);
}
}
...
...
hotspot/src/share/vm/oops/objArrayOop.cpp
浏览文件 @
927182ae
/*
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
4
, 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,22 @@
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
oop
objArrayOopDesc
::
atomic_compare_exchange_oop
(
int
index
,
oop
exchange_value
,
oop
compare_value
)
{
volatile
HeapWord
*
dest
;
if
(
UseCompressedOops
)
{
dest
=
(
HeapWord
*
)
obj_at_addr
<
narrowOop
>
(
index
);
}
else
{
dest
=
(
HeapWord
*
)
obj_at_addr
<
oop
>
(
index
);
}
oop
res
=
oopDesc
::
atomic_compare_exchange_oop
(
exchange_value
,
dest
,
compare_value
,
true
);
// update card mark if success
if
(
res
==
compare_value
)
{
update_barrier_set
((
void
*
)
dest
,
exchange_value
);
}
return
res
;
}
#define ObjArrayOop_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
\
int objArrayOopDesc::oop_iterate_range(OopClosureType* blk, int start, int end) { \
...
...
hotspot/src/share/vm/oops/objArrayOop.hpp
浏览文件 @
927182ae
/*
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
4
, 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
...
...
@@ -95,6 +95,9 @@ private:
oop_store
(
obj_at_addr
<
oop
>
(
index
),
value
);
}
}
oop
atomic_compare_exchange_oop
(
int
index
,
oop
exchange_value
,
oop
compare_value
);
// Sizing
static
int
header_size
()
{
return
arrayOopDesc
::
header_size
(
T_OBJECT
);
}
int
object_size
()
{
return
object_size
(
length
());
}
...
...
hotspot/src/share/vm/prims/jvmtiEnv.cpp
浏览文件 @
927182ae
...
...
@@ -258,9 +258,6 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
// VM representation. We don't attach the reconstituted class
// bytes to the InstanceKlass here because they have not been
// validated and we're not at a safepoint.
constantPoolHandle
constants
(
current_thread
,
ikh
->
constants
());
MonitorLockerEx
ml
(
constants
->
lock
());
// lock constant pool while we query it
JvmtiClassFileReconstituter
reconstituter
(
ikh
);
if
(
reconstituter
.
get_error
()
!=
JVMTI_ERROR_NONE
)
{
return
reconstituter
.
get_error
();
...
...
@@ -2445,9 +2442,6 @@ JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* con
}
instanceKlassHandle
ikh
(
thread
,
k_oop
);
constantPoolHandle
constants
(
thread
,
ikh
->
constants
());
MonitorLockerEx
ml
(
constants
->
lock
());
// lock constant pool while we query it
JvmtiConstantPoolReconstituter
reconstituter
(
ikh
);
if
(
reconstituter
.
get_error
()
!=
JVMTI_ERROR_NONE
)
{
return
reconstituter
.
get_error
();
...
...
@@ -2467,6 +2461,7 @@ JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* con
return
reconstituter
.
get_error
();
}
constantPoolHandle
constants
(
thread
,
ikh
->
constants
());
*
constant_pool_count_ptr
=
constants
->
length
();
*
constant_pool_byte_count_ptr
=
cpool_size
;
*
constant_pool_bytes_ptr
=
cpool_bytes
;
...
...
hotspot/src/share/vm/prims/unsafe.cpp
浏览文件 @
927182ae
...
...
@@ -891,6 +891,14 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineClass(JNIEnv *env, jobject unsafe, jstring nam
}
UNSAFE_END
static
jobject
get_class_loader
(
JNIEnv
*
env
,
jclass
cls
)
{
if
(
java_lang_Class
::
is_primitive
(
JNIHandles
::
resolve_non_null
(
cls
)))
{
return
NULL
;
}
Klass
*
k
=
java_lang_Class
::
as_Klass
(
JNIHandles
::
resolve_non_null
(
cls
));
oop
loader
=
k
->
class_loader
();
return
JNIHandles
::
make_local
(
env
,
loader
);
}
UNSAFE_ENTRY
(
jclass
,
Unsafe_DefineClass0
(
JNIEnv
*
env
,
jobject
unsafe
,
jstring
name
,
jbyteArray
data
,
int
offset
,
int
length
))
UnsafeWrapper
(
"Unsafe_DefineClass"
);
...
...
@@ -899,7 +907,7 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring na
int
depthFromDefineClass0
=
1
;
jclass
caller
=
JVM_GetCallerClass
(
env
,
depthFromDefineClass0
);
jobject
loader
=
(
caller
==
NULL
)
?
NULL
:
JVM_GetClassL
oader
(
env
,
caller
);
jobject
loader
=
(
caller
==
NULL
)
?
NULL
:
get_class_l
oader
(
env
,
caller
);
jobject
pd
=
(
caller
==
NULL
)
?
NULL
:
JVM_GetProtectionDomain
(
env
,
caller
);
return
Unsafe_DefineClass_impl
(
env
,
name
,
data
,
offset
,
length
,
loader
,
pd
);
...
...
hotspot/test/runtime/verifier/TestANewArray.java
0 → 100644
浏览文件 @
927182ae
/*
* Copyright (c) 2014, 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.
*/
import
java.io.File
;
import
java.io.FileOutputStream
;
import
jdk.internal.org.objectweb.asm.ClassWriter
;
import
jdk.internal.org.objectweb.asm.MethodVisitor
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.*;
import
com.oracle.java.testlibrary.*
;
/*
* @test
* @summary Test that anewarray bytecode is valid only if it specifies 255 or fewer dimensions.
* @library /testlibrary
* @compile -XDignore.symbol.file TestANewArray.java
* @run main/othervm TestANewArray 49
* @run main/othervm TestANewArray 50
* @run main/othervm TestANewArray 51
* @run main/othervm TestANewArray 52
*/
/*
* Testing anewarray instruction with 254, 255 & 264 dimensions to verify JVMS 8,
* Section 4.9.1, Static Constraints that states the following:
*
* "No anewarray instruction may be used to create an array of more than 255 dimensions."
*
*/
public
class
TestANewArray
{
static
String
classCName
=
null
;
// the generated class name
static
final
int
test_Dimension_254
=
254
;
// should always pass
static
final
int
test_Dimension_255
=
255
;
// should always pass, except for cfv 49
static
final
int
test_Dimension_264
=
264
;
// should always fail
static
final
String
array_Dimension_254
=
genArrayDim
(
test_Dimension_254
);
static
final
String
array_Dimension_255
=
genArrayDim
(
test_Dimension_255
);
static
final
String
array_Dimension_264
=
genArrayDim
(
test_Dimension_264
);
public
static
void
main
(
String
...
args
)
throws
Exception
{
int
cfv
=
Integer
.
parseInt
(
args
[
0
]);
// 254 array dimensions
byte
[]
classFile_254
=
dumpClassFile
(
cfv
,
test_Dimension_254
,
array_Dimension_254
);
writeClassFileFromByteArray
(
classFile_254
);
System
.
err
.
println
(
"Running with cfv: "
+
cfv
+
", test_Dimension_254"
);
ProcessBuilder
pb
=
ProcessTools
.
createJavaProcessBuilder
(
true
,
"-verify"
,
"-cp"
,
"."
,
classCName
);
OutputAnalyzer
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldNotContain
(
"java.lang.VerifyError"
);
output
.
shouldHaveExitValue
(
0
);
// 255 array dimensions
byte
[]
classFile_255
=
dumpClassFile
(
cfv
,
test_Dimension_255
,
array_Dimension_255
);
writeClassFileFromByteArray
(
classFile_255
);
System
.
err
.
println
(
"Running with cfv: "
+
cfv
+
", test_Dimension_255"
);
pb
=
ProcessTools
.
createJavaProcessBuilder
(
true
,
"-verify"
,
"-cp"
,
"."
,
classCName
);
output
=
new
OutputAnalyzer
(
pb
.
start
());
if
(
cfv
==
49
)
{
// The type-inferencing verifier used for <=49.0 ClassFiles detects an anewarray instruction
// with exactly 255 dimensions and incorrectly issues the "Array with too many dimensions" VerifyError.
output
.
shouldContain
(
"Array with too many dimensions"
);
output
.
shouldHaveExitValue
(
1
);
}
else
{
// 255 dimensions should always pass, except for cfv 49
output
.
shouldNotContain
(
"java.lang.VerifyError"
);
output
.
shouldNotContain
(
"java.lang.ClassFormatError"
);
output
.
shouldHaveExitValue
(
0
);
}
// 264 array dimensions
byte
[]
classFile_264
=
dumpClassFile
(
cfv
,
test_Dimension_264
,
array_Dimension_264
);
writeClassFileFromByteArray
(
classFile_264
);
System
.
err
.
println
(
"Running with cfv: "
+
cfv
+
", test_Dimension_264"
);
pb
=
ProcessTools
.
createJavaProcessBuilder
(
true
,
"-verify"
,
"-cp"
,
"."
,
classCName
);
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldContain
(
"java.lang.ClassFormatError"
);
output
.
shouldHaveExitValue
(
1
);
}
public
static
byte
[]
dumpClassFile
(
int
cfv
,
int
testDimension264
,
String
arrayDim
)
throws
Exception
{
ClassWriter
cw
=
new
ClassWriter
(
ClassWriter
.
COMPUTE_FRAMES
);
MethodVisitor
mv
;
classCName
=
"classCName_"
+
cfv
+
"_"
+
testDimension264
;
cw
.
visit
(
cfv
,
ACC_PUBLIC
+
ACC_SUPER
,
classCName
,
null
,
"java/lang/Object"
,
null
);
{
mv
=
cw
.
visitMethod
(
ACC_PUBLIC
,
"<init>"
,
"()V"
,
null
,
null
);
mv
.
visitCode
();
mv
.
visitVarInsn
(
ALOAD
,
0
);
mv
.
visitMethodInsn
(
INVOKESPECIAL
,
"java/lang/Object"
,
"<init>"
,
"()V"
,
false
);
mv
.
visitInsn
(
RETURN
);
mv
.
visitMaxs
(
1
,
1
);
mv
.
visitEnd
();
}
{
// classCName main method
mv
=
cw
.
visitMethod
(
ACC_PUBLIC
+
ACC_STATIC
,
"main"
,
"([Ljava/lang/String;)V"
,
null
,
null
);
mv
.
visitCode
();
mv
.
visitIntInsn
(
BIPUSH
,
1
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
arrayDim
);
// Test ANEWARRAY bytecode with various dimensions
mv
.
visitInsn
(
RETURN
);
mv
.
visitMaxs
(
2
,
2
);
mv
.
visitEnd
();
}
cw
.
visitEnd
();
return
cw
.
toByteArray
();
}
public
static
FileOutputStream
writeClassFileFromByteArray
(
byte
[]
classFileByteArray
)
throws
Exception
{
FileOutputStream
fos
=
new
FileOutputStream
(
new
File
(
classCName
+
".class"
));
fos
.
write
(
classFileByteArray
);
fos
.
close
();
return
fos
;
}
private
static
String
genArrayDim
(
int
testDim
)
{
StringBuilder
array_Dimension
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
testDim
;
i
++)
{
array_Dimension
.
append
(
"["
);
}
return
array_Dimension
.
append
(
"Ljava/lang/Object;"
).
toString
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录