Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
14ead889
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看板
提交
14ead889
编写于
11月 02, 2012
作者:
K
kamg
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
9d011274
6437332e
变更
27
展开全部
隐藏空白更改
内联
并排
Showing
27 changed file
with
4298 addition
and
200 deletion
+4298
-200
src/share/vm/classfile/bytecodeAssembler.cpp
src/share/vm/classfile/bytecodeAssembler.cpp
+269
-0
src/share/vm/classfile/bytecodeAssembler.hpp
src/share/vm/classfile/bytecodeAssembler.hpp
+214
-0
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+102
-34
src/share/vm/classfile/classFileParser.hpp
src/share/vm/classfile/classFileParser.hpp
+2
-0
src/share/vm/classfile/defaultMethods.cpp
src/share/vm/classfile/defaultMethods.cpp
+1387
-0
src/share/vm/classfile/defaultMethods.hpp
src/share/vm/classfile/defaultMethods.hpp
+58
-0
src/share/vm/classfile/genericSignatures.cpp
src/share/vm/classfile/genericSignatures.cpp
+1272
-0
src/share/vm/classfile/genericSignatures.hpp
src/share/vm/classfile/genericSignatures.hpp
+467
-0
src/share/vm/classfile/systemDictionary.hpp
src/share/vm/classfile/systemDictionary.hpp
+1
-0
src/share/vm/classfile/verifier.cpp
src/share/vm/classfile/verifier.cpp
+18
-7
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+1
-0
src/share/vm/code/dependencies.cpp
src/share/vm/code/dependencies.cpp
+5
-1
src/share/vm/interpreter/linkResolver.cpp
src/share/vm/interpreter/linkResolver.cpp
+42
-13
src/share/vm/oops/constMethod.cpp
src/share/vm/oops/constMethod.cpp
+16
-14
src/share/vm/oops/constMethod.hpp
src/share/vm/oops/constMethod.hpp
+33
-12
src/share/vm/oops/constantPool.cpp
src/share/vm/oops/constantPool.cpp
+7
-2
src/share/vm/oops/instanceKlass.cpp
src/share/vm/oops/instanceKlass.cpp
+80
-28
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlass.hpp
+18
-1
src/share/vm/oops/klassVtable.cpp
src/share/vm/oops/klassVtable.cpp
+48
-47
src/share/vm/oops/klassVtable.hpp
src/share/vm/oops/klassVtable.hpp
+15
-10
src/share/vm/oops/method.cpp
src/share/vm/oops/method.cpp
+26
-22
src/share/vm/oops/method.hpp
src/share/vm/oops/method.hpp
+14
-8
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+9
-0
src/share/vm/runtime/reflection.cpp
src/share/vm/runtime/reflection.cpp
+12
-0
src/share/vm/utilities/growableArray.hpp
src/share/vm/utilities/growableArray.hpp
+6
-1
src/share/vm/utilities/pair.hpp
src/share/vm/utilities/pair.hpp
+42
-0
src/share/vm/utilities/resourceHash.hpp
src/share/vm/utilities/resourceHash.hpp
+134
-0
未找到文件。
src/share/vm/classfile/bytecodeAssembler.cpp
0 → 100644
浏览文件 @
14ead889
/*
* 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.
*
*/
#include "precompiled.hpp"
#include "classfile/bytecodeAssembler.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constantPool.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
u2
BytecodeConstantPool
::
find_or_add
(
BytecodeCPEntry
const
&
bcpe
)
{
u2
index
;
u2
*
probe
=
_indices
.
get
(
bcpe
);
if
(
probe
==
NULL
)
{
index
=
_entries
.
length
();
_entries
.
append
(
bcpe
);
_indices
.
put
(
bcpe
,
index
);
}
else
{
index
=
*
probe
;
}
return
index
+
_orig
->
length
();
}
ConstantPool
*
BytecodeConstantPool
::
create_constant_pool
(
TRAPS
)
const
{
if
(
_entries
.
length
()
==
0
)
{
return
_orig
;
}
ConstantPool
*
cp
=
ConstantPool
::
allocate
(
_orig
->
pool_holder
()
->
class_loader_data
(),
_orig
->
length
()
+
_entries
.
length
(),
CHECK_NULL
);
cp
->
set_pool_holder
(
_orig
->
pool_holder
());
_orig
->
copy_cp_to
(
1
,
_orig
->
length
()
-
1
,
cp
,
1
,
CHECK_NULL
);
for
(
int
i
=
0
;
i
<
_entries
.
length
();
++
i
)
{
BytecodeCPEntry
entry
=
_entries
.
at
(
i
);
int
idx
=
i
+
_orig
->
length
();
switch
(
entry
.
_tag
)
{
case
BytecodeCPEntry
::
UTF8
:
cp
->
symbol_at_put
(
idx
,
entry
.
_u
.
utf8
);
entry
.
_u
.
utf8
->
increment_refcount
();
break
;
case
BytecodeCPEntry
::
KLASS
:
cp
->
unresolved_klass_at_put
(
idx
,
cp
->
symbol_at
(
entry
.
_u
.
klass
));
break
;
case
BytecodeCPEntry
::
STRING
:
cp
->
unresolved_string_at_put
(
idx
,
cp
->
symbol_at
(
entry
.
_u
.
string
));
break
;
case
BytecodeCPEntry
::
NAME_AND_TYPE
:
cp
->
name_and_type_at_put
(
idx
,
entry
.
_u
.
name_and_type
.
name_index
,
entry
.
_u
.
name_and_type
.
type_index
);
break
;
case
BytecodeCPEntry
::
METHODREF
:
cp
->
method_at_put
(
idx
,
entry
.
_u
.
methodref
.
class_index
,
entry
.
_u
.
methodref
.
name_and_type_index
);
break
;
default:
ShouldNotReachHere
();
}
}
return
cp
;
}
void
BytecodeAssembler
::
append
(
u1
imm_u1
)
{
_code
->
append
(
imm_u1
);
}
void
BytecodeAssembler
::
append
(
u2
imm_u2
)
{
_code
->
append
(
0
);
_code
->
append
(
0
);
Bytes
::
put_Java_u2
(
_code
->
adr_at
(
_code
->
length
()
-
2
),
imm_u2
);
}
void
BytecodeAssembler
::
append
(
u4
imm_u4
)
{
_code
->
append
(
0
);
_code
->
append
(
0
);
_code
->
append
(
0
);
_code
->
append
(
0
);
Bytes
::
put_Java_u4
(
_code
->
adr_at
(
_code
->
length
()
-
4
),
imm_u4
);
}
void
BytecodeAssembler
::
xload
(
u4
index
,
u1
onebyteop
,
u1
twobyteop
)
{
if
(
index
<
4
)
{
_code
->
append
(
onebyteop
+
index
);
}
else
{
_code
->
append
(
twobyteop
);
_code
->
append
((
u2
)
index
);
}
}
void
BytecodeAssembler
::
dup
()
{
_code
->
append
(
Bytecodes
::
_dup
);
}
void
BytecodeAssembler
::
_new
(
Symbol
*
sym
)
{
u2
cpool_index
=
_cp
->
klass
(
sym
);
_code
->
append
(
Bytecodes
::
_new
);
append
(
cpool_index
);
}
void
BytecodeAssembler
::
load_string
(
Symbol
*
sym
)
{
u2
cpool_index
=
_cp
->
string
(
sym
);
if
(
cpool_index
<
0x100
)
{
ldc
(
cpool_index
);
}
else
{
ldc_w
(
cpool_index
);
}
}
void
BytecodeAssembler
::
ldc
(
u1
index
)
{
_code
->
append
(
Bytecodes
::
_ldc
);
append
(
index
);
}
void
BytecodeAssembler
::
ldc_w
(
u2
index
)
{
_code
->
append
(
Bytecodes
::
_ldc_w
);
append
(
index
);
}
void
BytecodeAssembler
::
athrow
()
{
_code
->
append
(
Bytecodes
::
_athrow
);
}
void
BytecodeAssembler
::
iload
(
u4
index
)
{
xload
(
index
,
Bytecodes
::
_iload_0
,
Bytecodes
::
_iload
);
}
void
BytecodeAssembler
::
lload
(
u4
index
)
{
xload
(
index
,
Bytecodes
::
_lload_0
,
Bytecodes
::
_lload
);
}
void
BytecodeAssembler
::
fload
(
u4
index
)
{
xload
(
index
,
Bytecodes
::
_fload_0
,
Bytecodes
::
_fload
);
}
void
BytecodeAssembler
::
dload
(
u4
index
)
{
xload
(
index
,
Bytecodes
::
_dload_0
,
Bytecodes
::
_dload
);
}
void
BytecodeAssembler
::
aload
(
u4
index
)
{
xload
(
index
,
Bytecodes
::
_aload_0
,
Bytecodes
::
_aload
);
}
void
BytecodeAssembler
::
load
(
BasicType
bt
,
u4
index
)
{
switch
(
bt
)
{
case
T_BOOLEAN
:
case
T_CHAR
:
case
T_BYTE
:
case
T_SHORT
:
case
T_INT
:
iload
(
index
);
break
;
case
T_FLOAT
:
fload
(
index
);
break
;
case
T_DOUBLE
:
dload
(
index
);
break
;
case
T_LONG
:
lload
(
index
);
break
;
case
T_OBJECT
:
case
T_ARRAY
:
aload
(
index
);
break
;
default:
ShouldNotReachHere
();
}
}
void
BytecodeAssembler
::
checkcast
(
Symbol
*
sym
)
{
u2
cpool_index
=
_cp
->
klass
(
sym
);
_code
->
append
(
Bytecodes
::
_checkcast
);
append
(
cpool_index
);
}
void
BytecodeAssembler
::
invokespecial
(
Method
*
method
)
{
invokespecial
(
method
->
klass_name
(),
method
->
name
(),
method
->
signature
());
}
void
BytecodeAssembler
::
invokespecial
(
Symbol
*
klss
,
Symbol
*
name
,
Symbol
*
sig
)
{
u2
methodref_index
=
_cp
->
methodref
(
klss
,
name
,
sig
);
_code
->
append
(
Bytecodes
::
_invokespecial
);
append
(
methodref_index
);
}
void
BytecodeAssembler
::
invokevirtual
(
Method
*
method
)
{
invokevirtual
(
method
->
klass_name
(),
method
->
name
(),
method
->
signature
());
}
void
BytecodeAssembler
::
invokevirtual
(
Symbol
*
klss
,
Symbol
*
name
,
Symbol
*
sig
)
{
u2
methodref_index
=
_cp
->
methodref
(
klss
,
name
,
sig
);
_code
->
append
(
Bytecodes
::
_invokevirtual
);
append
(
methodref_index
);
}
void
BytecodeAssembler
::
ireturn
()
{
_code
->
append
(
Bytecodes
::
_ireturn
);
}
void
BytecodeAssembler
::
lreturn
()
{
_code
->
append
(
Bytecodes
::
_lreturn
);
}
void
BytecodeAssembler
::
freturn
()
{
_code
->
append
(
Bytecodes
::
_freturn
);
}
void
BytecodeAssembler
::
dreturn
()
{
_code
->
append
(
Bytecodes
::
_dreturn
);
}
void
BytecodeAssembler
::
areturn
()
{
_code
->
append
(
Bytecodes
::
_areturn
);
}
void
BytecodeAssembler
::
_return
()
{
_code
->
append
(
Bytecodes
::
_return
);
}
void
BytecodeAssembler
::
_return
(
BasicType
bt
)
{
switch
(
bt
)
{
case
T_BOOLEAN
:
case
T_CHAR
:
case
T_BYTE
:
case
T_SHORT
:
case
T_INT
:
ireturn
();
break
;
case
T_FLOAT
:
freturn
();
break
;
case
T_DOUBLE
:
dreturn
();
break
;
case
T_LONG
:
lreturn
();
break
;
case
T_OBJECT
:
case
T_ARRAY
:
areturn
();
break
;
case
T_VOID
:
_return
();
break
;
default:
ShouldNotReachHere
();
}
}
src/share/vm/classfile/bytecodeAssembler.hpp
0 → 100644
浏览文件 @
14ead889
/*
* 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_CLASSFILE_BYTECODEASSEMBLER_HPP
#define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
#include "memory/allocation.hpp"
#include "oops/method.hpp"
#include "oops/symbol.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
/**
* Bytecode Assembler
*
* These classes are used to synthesize code for creating new methods from
* within the VM. This is only a partial implementation of an assembler;
* only the bytecodes that are needed by clients are implemented at this time.
* This is used during default method analysis to create overpass methods
* and add them to a call during parsing. Other uses (such as creating
* bridges) may come later. Any missing bytecodes can be implemented on an
* as-need basis.
*/
class
BytecodeBuffer
:
public
GrowableArray
<
u1
>
{
public:
BytecodeBuffer
()
:
GrowableArray
<
u1
>
(
20
)
{}
};
// Entries in a yet-to-be-created constant pool. Limited types for now.
class
BytecodeCPEntry
VALUE_OBJ_CLASS_SPEC
{
public:
enum
tag
{
ERROR_TAG
,
UTF8
,
KLASS
,
STRING
,
NAME_AND_TYPE
,
METHODREF
};
u1
_tag
;
union
{
Symbol
*
utf8
;
u2
klass
;
u2
string
;
struct
{
u2
name_index
;
u2
type_index
;
}
name_and_type
;
struct
{
u2
class_index
;
u2
name_and_type_index
;
}
methodref
;
uintptr_t
hash
;
}
_u
;
BytecodeCPEntry
()
:
_tag
(
ERROR_TAG
)
{
_u
.
hash
=
0
;
}
BytecodeCPEntry
(
u1
tag
)
:
_tag
(
tag
)
{
_u
.
hash
=
0
;
}
static
BytecodeCPEntry
utf8
(
Symbol
*
symbol
)
{
BytecodeCPEntry
bcpe
(
UTF8
);
bcpe
.
_u
.
utf8
=
symbol
;
return
bcpe
;
}
static
BytecodeCPEntry
klass
(
u2
index
)
{
BytecodeCPEntry
bcpe
(
KLASS
);
bcpe
.
_u
.
klass
=
index
;
return
bcpe
;
}
static
BytecodeCPEntry
string
(
u2
index
)
{
BytecodeCPEntry
bcpe
(
STRING
);
bcpe
.
_u
.
string
=
index
;
return
bcpe
;
}
static
BytecodeCPEntry
name_and_type
(
u2
name
,
u2
type
)
{
BytecodeCPEntry
bcpe
(
NAME_AND_TYPE
);
bcpe
.
_u
.
name_and_type
.
name_index
=
name
;
bcpe
.
_u
.
name_and_type
.
type_index
=
type
;
return
bcpe
;
}
static
BytecodeCPEntry
methodref
(
u2
class_index
,
u2
nat
)
{
BytecodeCPEntry
bcpe
(
METHODREF
);
bcpe
.
_u
.
methodref
.
class_index
=
class_index
;
bcpe
.
_u
.
methodref
.
name_and_type_index
=
nat
;
return
bcpe
;
}
static
bool
equals
(
BytecodeCPEntry
const
&
e0
,
BytecodeCPEntry
const
&
e1
)
{
return
e0
.
_tag
==
e1
.
_tag
&&
e0
.
_u
.
hash
==
e1
.
_u
.
hash
;
}
static
unsigned
hash
(
BytecodeCPEntry
const
&
e0
)
{
return
(
unsigned
)(
e0
.
_tag
^
e0
.
_u
.
hash
);
}
};
class
BytecodeConstantPool
:
ResourceObj
{
private:
typedef
ResourceHashtable
<
BytecodeCPEntry
,
u2
,
&
BytecodeCPEntry
::
hash
,
&
BytecodeCPEntry
::
equals
>
IndexHash
;
ConstantPool
*
_orig
;
GrowableArray
<
BytecodeCPEntry
>
_entries
;
IndexHash
_indices
;
u2
find_or_add
(
BytecodeCPEntry
const
&
bcpe
);
public:
BytecodeConstantPool
(
ConstantPool
*
orig
)
:
_orig
(
orig
)
{}
BytecodeCPEntry
const
&
at
(
u2
index
)
const
{
return
_entries
.
at
(
index
);
}
InstanceKlass
*
pool_holder
()
const
{
return
InstanceKlass
::
cast
(
_orig
->
pool_holder
());
}
u2
utf8
(
Symbol
*
sym
)
{
return
find_or_add
(
BytecodeCPEntry
::
utf8
(
sym
));
}
u2
klass
(
Symbol
*
class_name
)
{
return
find_or_add
(
BytecodeCPEntry
::
klass
(
utf8
(
class_name
)));
}
u2
string
(
Symbol
*
str
)
{
return
find_or_add
(
BytecodeCPEntry
::
string
(
utf8
(
str
)));
}
u2
name_and_type
(
Symbol
*
name
,
Symbol
*
sig
)
{
return
find_or_add
(
BytecodeCPEntry
::
name_and_type
(
utf8
(
name
),
utf8
(
sig
)));
}
u2
methodref
(
Symbol
*
class_name
,
Symbol
*
name
,
Symbol
*
sig
)
{
return
find_or_add
(
BytecodeCPEntry
::
methodref
(
klass
(
class_name
),
name_and_type
(
name
,
sig
)));
}
ConstantPool
*
create_constant_pool
(
TRAPS
)
const
;
};
// Partial bytecode assembler - only what we need for creating
// overpass methods for default methods is implemented
class
BytecodeAssembler
:
StackObj
{
private:
BytecodeBuffer
*
_code
;
BytecodeConstantPool
*
_cp
;
void
append
(
u1
imm_u1
);
void
append
(
u2
imm_u2
);
void
append
(
u4
imm_u4
);
void
xload
(
u4
index
,
u1
quick
,
u1
twobyte
);
public:
BytecodeAssembler
(
BytecodeBuffer
*
buffer
,
BytecodeConstantPool
*
cp
)
:
_code
(
buffer
),
_cp
(
cp
)
{}
void
aload
(
u4
index
);
void
areturn
();
void
athrow
();
void
checkcast
(
Symbol
*
sym
);
void
dload
(
u4
index
);
void
dreturn
();
void
dup
();
void
fload
(
u4
index
);
void
freturn
();
void
iload
(
u4
index
);
void
invokespecial
(
Method
*
method
);
void
invokespecial
(
Symbol
*
cls
,
Symbol
*
name
,
Symbol
*
sig
);
void
invokevirtual
(
Method
*
method
);
void
invokevirtual
(
Symbol
*
cls
,
Symbol
*
name
,
Symbol
*
sig
);
void
ireturn
();
void
ldc
(
u1
index
);
void
ldc_w
(
u2
index
);
void
lload
(
u4
index
);
void
lreturn
();
void
_new
(
Symbol
*
sym
);
void
_return
();
void
load_string
(
Symbol
*
sym
);
void
load
(
BasicType
bt
,
u4
index
);
void
_return
(
BasicType
bt
);
};
#endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
14ead889
...
...
@@ -27,6 +27,8 @@
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/genericSignatures.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
...
...
@@ -84,6 +86,9 @@
// - to check NameAndType_info signatures more aggressively
#define JAVA_7_VERSION 51
// Extension method support.
#define JAVA_8_VERSION 52
void
ClassFileParser
::
parse_constant_pool_entries
(
ClassLoaderData
*
loader_data
,
constantPoolHandle
cp
,
int
length
,
TRAPS
)
{
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
...
...
@@ -785,6 +790,7 @@ Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
ClassLoaderData
*
loader_data
,
Handle
protection_domain
,
Symbol
*
class_name
,
bool
*
has_default_methods
,
TRAPS
)
{
ClassFileStream
*
cfs
=
stream
();
assert
(
length
>
0
,
"only called for length>0"
);
...
...
@@ -821,6 +827,9 @@ Array<Klass*>* ClassFileParser::parse_interfaces(constantPoolHandle cp,
if
(
!
Klass
::
cast
(
interf
())
->
is_interface
())
{
THROW_MSG_
(
vmSymbols
::
java_lang_IncompatibleClassChangeError
(),
"Implementing class"
,
NULL
);
}
if
(
InstanceKlass
::
cast
(
interf
())
->
has_default_methods
())
{
*
has_default_methods
=
true
;
}
interfaces
->
at_put
(
index
,
interf
());
}
...
...
@@ -1928,7 +1937,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
if
(
method_attribute_name
==
vmSymbols
::
tag_code
())
{
// Parse Code attribute
if
(
_need_verify
)
{
guarantee_property
(
!
access_flags
.
is_native
()
&&
!
access_flags
.
is_abstract
(),
guarantee_property
(
!
access_flags
.
is_native
()
&&
!
access_flags
.
is_abstract
(),
"Code attribute in native or abstract methods in class file %s"
,
CHECK_
(
nullHandle
));
}
...
...
@@ -2125,7 +2135,9 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
runtime_visible_annotations_length
=
method_attribute_length
;
runtime_visible_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_annotations
!=
NULL
,
"null visible annotations"
);
parse_annotations
(
runtime_visible_annotations
,
runtime_visible_annotations_length
,
cp
,
&
parsed_annotations
,
CHECK_
(
nullHandle
));
parse_annotations
(
runtime_visible_annotations
,
runtime_visible_annotations_length
,
cp
,
&
parsed_annotations
,
CHECK_
(
nullHandle
));
cfs
->
skip_u1
(
runtime_visible_annotations_length
,
CHECK_
(
nullHandle
));
}
else
if
(
PreserveAllAnnotations
&&
method_attribute_name
==
vmSymbols
::
tag_runtime_invisible_annotations
())
{
runtime_invisible_annotations_length
=
method_attribute_length
;
...
...
@@ -2169,12 +2181,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
}
// All sizing information for a Method* is finally available, now create it
Method
*
m
=
Method
::
allocate
(
loader_data
,
code_length
,
access_flags
,
linenumber_table_length
,
total_lvt_length
,
exception_table_length
,
checked_exceptions_length
,
CHECK_
(
nullHandle
));
Method
*
m
=
Method
::
allocate
(
loader_data
,
code_length
,
access_flags
,
linenumber_table_length
,
total_lvt_length
,
exception_table_length
,
checked_exceptions_length
,
ConstMethod
::
NORMAL
,
CHECK_
(
nullHandle
));
ClassLoadingService
::
add_class_method_size
(
m
->
size
()
*
HeapWordSize
);
...
...
@@ -2204,7 +2214,6 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
// Fill in code attribute information
m
->
set_max_stack
(
max_stack
);
m
->
set_max_locals
(
max_locals
);
m
->
constMethod
()
->
set_stackmap_data
(
stackmap_data
);
// Copy byte codes
...
...
@@ -2356,6 +2365,7 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
Array
<
AnnotationArray
*>**
methods_annotations
,
Array
<
AnnotationArray
*>**
methods_parameter_annotations
,
Array
<
AnnotationArray
*>**
methods_default_annotations
,
bool
*
has_default_methods
,
TRAPS
)
{
ClassFileStream
*
cfs
=
stream
();
AnnotationArray
*
method_annotations
=
NULL
;
...
...
@@ -2382,6 +2392,10 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
if
(
method
->
is_final
())
{
*
has_final_method
=
true
;
}
if
(
is_interface
&&
!
method
->
is_abstract
()
&&
!
method
->
is_static
())
{
// default method
*
has_default_methods
=
true
;
}
methods
->
at_put
(
index
,
method
());
if
(
*
methods_annotations
==
NULL
)
{
*
methods_annotations
=
...
...
@@ -2907,6 +2921,34 @@ AnnotationArray* ClassFileParser::assemble_annotations(ClassLoaderData* loader_d
}
#ifndef PRODUCT
static
void
parseAndPrintGenericSignatures
(
instanceKlassHandle
this_klass
,
TRAPS
)
{
assert
(
ParseAllGenericSignatures
==
true
,
"Shouldn't call otherwise"
);
ResourceMark
rm
;
if
(
this_klass
->
generic_signature
()
!=
NULL
)
{
using
namespace
generic
;
ClassDescriptor
*
spec
=
ClassDescriptor
::
parse_generic_signature
(
this_klass
(),
CHECK
);
tty
->
print_cr
(
"Parsing %s"
,
this_klass
->
generic_signature
()
->
as_C_string
());
spec
->
print_on
(
tty
);
for
(
int
i
=
0
;
i
<
this_klass
->
methods
()
->
length
();
++
i
)
{
Method
*
m
=
this_klass
->
methods
()
->
at
(
i
);
MethodDescriptor
*
method_spec
=
MethodDescriptor
::
parse_generic_signature
(
m
,
spec
);
Symbol
*
sig
=
m
->
generic_signature
();
if
(
sig
==
NULL
)
{
sig
=
m
->
signature
();
}
tty
->
print_cr
(
"Parsing %s"
,
sig
->
as_C_string
());
method_spec
->
print_on
(
tty
);
}
}
}
#endif // ndef PRODUCT
instanceKlassHandle
ClassFileParser
::
parseClassFile
(
Symbol
*
name
,
Handle
class_loader
,
Handle
protection_domain
,
...
...
@@ -2923,6 +2965,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
unsigned
char
*
cached_class_file_bytes
=
NULL
;
jint
cached_class_file_length
;
ClassLoaderData
*
loader_data
=
ClassLoaderData
::
class_loader_data
(
class_loader
());
bool
has_default_methods
=
false
;
ResourceMark
rm
(
THREAD
);
ClassFileStream
*
cfs
=
stream
();
// Timing
...
...
@@ -3138,7 +3182,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
if
(
itfs_len
==
0
)
{
local_interfaces
=
Universe
::
the_empty_klass_array
();
}
else
{
local_interfaces
=
parse_interfaces
(
cp
,
itfs_len
,
loader_data
,
protection_domain
,
_class_name
,
CHECK_
(
nullHandle
));
local_interfaces
=
parse_interfaces
(
cp
,
itfs_len
,
loader_data
,
protection_domain
,
_class_name
,
&
has_default_methods
,
CHECK_
(
nullHandle
));
}
u2
java_fields_count
=
0
;
...
...
@@ -3164,6 +3210,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
&
methods_annotations
,
&
methods_parameter_annotations
,
&
methods_default_annotations
,
&
has_default_methods
,
CHECK_
(
nullHandle
));
// Additional attributes
...
...
@@ -3193,6 +3240,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
super_klass
=
instanceKlassHandle
(
THREAD
,
kh
());
}
if
(
super_klass
.
not_null
())
{
if
(
super_klass
->
has_default_methods
())
{
has_default_methods
=
true
;
}
if
(
super_klass
->
is_interface
())
{
ResourceMark
rm
(
THREAD
);
Exceptions
::
fthrow
(
...
...
@@ -3229,14 +3281,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
int
itable_size
=
0
;
int
num_miranda_methods
=
0
;
klassVtable
::
compute_vtable_size_and_num_mirandas
(
vtable_size
,
num_miranda_methods
,
super_klass
(),
methods
,
access_flags
,
class_loader
,
class_name
,
local_interfaces
,
GrowableArray
<
Method
*>
all_mirandas
(
20
);
klassVtable
::
compute_vtable_size_and_num_mirandas
(
&
vtable_size
,
&
num_miranda_methods
,
&
all_mirandas
,
super_klass
(),
methods
,
access_flags
,
class_loader
,
class_name
,
local_interfaces
,
CHECK_
(
nullHandle
));
// Size of Java itable (in words)
...
...
@@ -3656,6 +3705,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass
->
set_minor_version
(
minor_version
);
this_klass
->
set_major_version
(
major_version
);
this_klass
->
set_has_default_methods
(
has_default_methods
);
// Set up Method*::intrinsic_id as soon as we know the names of methods.
// (We used to do this lazily, but now we query it in Rewriter,
...
...
@@ -3673,19 +3723,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
cached_class_file_length
);
}
// Miranda methods
if
((
num_miranda_methods
>
0
)
||
// if this class introduced new miranda methods or
(
super_klass
.
not_null
()
&&
(
super_klass
->
has_miranda_methods
()))
// super class exists and this class inherited miranda methods
)
{
this_klass
->
set_has_miranda_methods
();
// then set a flag
}
// Fill in field values obtained by parse_classfile_attributes
if
(
parsed_annotations
.
has_any_annotations
())
{
if
(
parsed_annotations
.
has_any_annotations
())
parsed_annotations
.
apply_to
(
this_klass
);
}
// Create annotations
if
(
_annotations
!=
NULL
&&
this_klass
->
annotations
()
==
NULL
)
{
Annotations
*
anno
=
Annotations
::
allocate
(
loader_data
,
CHECK_NULL
);
...
...
@@ -3693,7 +3733,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
apply_parsed_class_attributes
(
this_klass
);
// Compute transitive closure of interfaces this class implements
// Miranda methods
if
((
num_miranda_methods
>
0
)
||
// if this class introduced new miranda methods or
(
super_klass
.
not_null
()
&&
(
super_klass
->
has_miranda_methods
()))
// super class exists and this class inherited miranda methods
)
{
this_klass
->
set_has_miranda_methods
();
// then set a flag
}
this_klass
->
set_transitive_interfaces
(
transitive_interfaces
);
// Fill in information needed to compute superclasses.
...
...
@@ -3702,6 +3750,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// Initialize itable offset tables
klassItable
::
setup_itable_offset_table
(
this_klass
);
// Compute transitive closure of interfaces this class implements
// Do final class setup
fill_oop_maps
(
this_klass
,
nonstatic_oop_map_count
,
nonstatic_oop_offsets
,
nonstatic_oop_counts
);
...
...
@@ -3726,6 +3775,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
check_illegal_static_method
(
this_klass
,
CHECK_
(
nullHandle
));
}
#ifdef ASSERT
if
(
ParseAllGenericSignatures
)
{
parseAndPrintGenericSignatures
(
this_klass
,
CHECK_
(
nullHandle
));
}
#endif
// Generate any default methods - default methods are interface methods
// that have a default implementation. This is new with Lambda project.
if
(
has_default_methods
&&
!
access_flags
.
is_interface
()
&&
local_interfaces
->
length
()
>
0
)
{
DefaultMethods
::
generate_default_methods
(
this_klass
(),
&
all_mirandas
,
CHECK_
(
nullHandle
));
}
// Allocate mirror and initialize static fields
java_lang_Class
::
create_mirror
(
this_klass
,
CHECK_
(
nullHandle
));
...
...
@@ -3744,6 +3808,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
false
/* not shared class */
);
if
(
TraceClassLoading
)
{
ResourceMark
rm
;
// print in a single call to reduce interleaving of output
if
(
cfs
->
source
()
!=
NULL
)
{
tty
->
print
(
"[Loaded %s from %s]
\n
"
,
this_klass
->
external_name
(),
...
...
@@ -3758,13 +3823,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
tty
->
print
(
"[Loaded %s]
\n
"
,
this_klass
->
external_name
());
}
}
else
{
ResourceMark
rm
;
tty
->
print
(
"[Loaded %s from %s]
\n
"
,
this_klass
->
external_name
(),
InstanceKlass
::
cast
(
class_loader
->
klass
())
->
external_name
());
}
}
if
(
TraceClassResolution
)
{
ResourceMark
rm
;
// print out the superclass.
const
char
*
from
=
Klass
::
cast
(
this_klass
())
->
external_name
();
if
(
this_klass
->
java_super
()
!=
NULL
)
{
...
...
@@ -3785,6 +3850,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
#ifndef PRODUCT
if
(
PrintCompactFieldsSavings
)
{
ResourceMark
rm
;
if
(
nonstatic_field_size
<
orig_nonstatic_field_size
)
{
tty
->
print
(
"[Saved %d of %d bytes in %s]
\n
"
,
(
orig_nonstatic_field_size
-
nonstatic_field_size
)
*
heapOopSize
,
...
...
@@ -3811,7 +3877,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
return
this_klass
;
}
unsigned
int
ClassFileParser
::
compute_oop_map_count
(
instanceKlassHandle
super
,
unsigned
int
nonstatic_oop_map_count
,
...
...
@@ -4263,13 +4328,16 @@ void ClassFileParser::verify_legal_method_modifiers(
const
bool
is_strict
=
(
flags
&
JVM_ACC_STRICT
)
!=
0
;
const
bool
is_synchronized
=
(
flags
&
JVM_ACC_SYNCHRONIZED
)
!=
0
;
const
bool
major_gte_15
=
_major_version
>=
JAVA_1_5_VERSION
;
const
bool
major_gte_8
=
_major_version
>=
JAVA_8_VERSION
;
const
bool
is_initializer
=
(
name
==
vmSymbols
::
object_initializer_name
());
bool
is_illegal
=
false
;
if
(
is_interface
)
{
if
(
!
is_abstract
||
!
is_public
||
is_static
||
is_final
||
is_native
||
(
major_gte_15
&&
(
is_synchronized
||
is_strict
)))
{
if
(
!
is_public
||
is_static
||
is_final
||
is_native
||
((
is_synchronized
||
is_strict
)
&&
major_gte_15
&&
(
!
major_gte_8
||
is_abstract
))
||
(
!
major_gte_8
&&
!
is_abstract
))
{
is_illegal
=
true
;
}
}
else
{
// not interface
...
...
src/share/vm/classfile/classFileParser.hpp
浏览文件 @
14ead889
...
...
@@ -151,6 +151,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
ClassLoaderData
*
loader_data
,
Handle
protection_domain
,
Symbol
*
class_name
,
bool
*
has_default_methods
,
TRAPS
);
void
record_defined_class_dependencies
(
instanceKlassHandle
defined_klass
,
TRAPS
);
...
...
@@ -188,6 +189,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array
<
AnnotationArray
*>**
methods_annotations
,
Array
<
AnnotationArray
*>**
methods_parameter_annotations
,
Array
<
AnnotationArray
*>**
methods_default_annotations
,
bool
*
has_default_method
,
TRAPS
);
Array
<
int
>*
sort_methods
(
ClassLoaderData
*
loader_data
,
Array
<
Method
*>*
methods
,
...
...
src/share/vm/classfile/defaultMethods.cpp
0 → 100644
浏览文件 @
14ead889
此差异已折叠。
点击以展开。
src/share/vm/classfile/defaultMethods.hpp
0 → 100644
浏览文件 @
14ead889
/*
* 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_CLASSFILE_DEFAULTMETHODS_HPP
#define SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/exceptions.hpp"
class
InstanceKlass
;
class
Symbol
;
class
Method
;
class
DefaultMethods
:
AllStatic
{
public:
// Analyzes class and determines which default methods are inherited
// from interfaces (and has no other implementation). For each method
// (and each different signature the method could have), create an
// "overpass" method that is an instance method that redirects to the
// default method. Overpass methods are added to the methods lists for
// the class.
static
void
generate_default_methods
(
InstanceKlass
*
klass
,
GrowableArray
<
Method
*>*
mirandas
,
TRAPS
);
// Called during linking when an invokespecial to an direct interface
// method is found. Selects and returns a method if there is a unique
// default method in the 'super_iface' part of the hierarchy which is
// also a candidate default for 'this_klass'. Otherwise throws an AME.
static
Method
*
find_super_default
(
Klass
*
this_klass
,
Klass
*
super_iface
,
Symbol
*
method_name
,
Symbol
*
method_sig
,
TRAPS
);
};
#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
src/share/vm/classfile/genericSignatures.cpp
0 → 100644
浏览文件 @
14ead889
此差异已折叠。
点击以展开。
src/share/vm/classfile/genericSignatures.hpp
0 → 100644
浏览文件 @
14ead889
/*
* 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_CLASSFILE_GENERICSIGNATURES_HPP
#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
#include "classfile/symbolTable.hpp"
#include "memory/allocation.hpp"
#include "runtime/signature.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
class
stringStream
;
namespace
generic
{
class
Identifier
;
class
ClassDescriptor
;
class
MethodDescriptor
;
class
TypeParameter
;
// a formal type parameter declared in generic signatures
class
TypeArgument
;
// The "type value" passed to fill parameters in supertypes
class
TypeVariable
;
// A usage of a type parameter as a value
/**
* Example:
*
* <T, V> class Foo extends Bar<String> { int m(V v) {} }
* ^^^^^^ ^^^^^^ ^^
* type parameters type argument type variable
*
* Note that a type variable could be passed as an argument too:
* <T, V> class Foo extends Bar<T> { int m(V v) {} }
* ^^^
* type argument's value is a type variable
*/
class
Type
;
class
ClassType
;
class
ArrayType
;
class
PrimitiveType
;
class
Context
;
class
DescriptorCache
;
class
DescriptorStream
;
class
Identifier
:
public
ResourceObj
{
private:
Symbol
*
_sym
;
int
_begin
;
int
_end
;
public:
Identifier
(
Symbol
*
sym
,
int
begin
,
int
end
)
:
_sym
(
sym
),
_begin
(
begin
),
_end
(
end
)
{}
bool
equals
(
Identifier
*
other
);
bool
equals
(
Symbol
*
sym
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif // ndef PRODUCT
};
class
Descriptor
:
public
ResourceObj
{
protected:
GrowableArray
<
TypeParameter
*>
_type_parameters
;
ClassDescriptor
*
_outer_class
;
Descriptor
(
GrowableArray
<
TypeParameter
*>&
params
,
ClassDescriptor
*
outer
)
:
_type_parameters
(
params
),
_outer_class
(
outer
)
{}
public:
ClassDescriptor
*
outer_class
()
{
return
_outer_class
;
}
void
set_outer_class
(
ClassDescriptor
*
sig
)
{
_outer_class
=
sig
;
}
virtual
ClassDescriptor
*
as_class_signature
()
{
return
NULL
;
}
virtual
MethodDescriptor
*
as_method_signature
()
{
return
NULL
;
}
bool
is_class_signature
()
{
return
as_class_signature
()
!=
NULL
;
}
bool
is_method_signature
()
{
return
as_method_signature
()
!=
NULL
;
}
GrowableArray
<
TypeParameter
*>&
type_parameters
()
{
return
_type_parameters
;
}
TypeParameter
*
find_type_parameter
(
Identifier
*
id
,
int
*
param_depth
);
virtual
void
bind_variables_to_parameters
()
=
0
;
#ifndef PRODUCT
virtual
void
print_on
(
outputStream
*
str
)
const
=
0
;
#endif
};
class
ClassDescriptor
:
public
Descriptor
{
private:
ClassType
*
_super
;
GrowableArray
<
ClassType
*>
_interfaces
;
MethodDescriptor
*
_outer_method
;
ClassDescriptor
(
GrowableArray
<
TypeParameter
*>&
ftp
,
ClassType
*
scs
,
GrowableArray
<
ClassType
*>&
sis
,
ClassDescriptor
*
outer_class
=
NULL
,
MethodDescriptor
*
outer_method
=
NULL
)
:
Descriptor
(
ftp
,
outer_class
),
_super
(
scs
),
_interfaces
(
sis
),
_outer_method
(
outer_method
)
{}
static
u2
get_outer_class_index
(
InstanceKlass
*
k
,
TRAPS
);
static
ClassDescriptor
*
parse_generic_signature
(
Klass
*
k
,
Symbol
*
original_name
,
TRAPS
);
public:
virtual
ClassDescriptor
*
as_class_signature
()
{
return
this
;
}
MethodDescriptor
*
outer_method
()
{
return
_outer_method
;
}
void
set_outer_method
(
MethodDescriptor
*
m
)
{
_outer_method
=
m
;
}
ClassType
*
super
()
{
return
_super
;
}
ClassType
*
interface_desc
(
Symbol
*
sym
);
static
ClassDescriptor
*
parse_generic_signature
(
Klass
*
k
,
TRAPS
);
static
ClassDescriptor
*
parse_generic_signature
(
Symbol
*
sym
);
// For use in superclass chains in positions where this is no generic info
static
ClassDescriptor
*
placeholder
(
InstanceKlass
*
klass
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
ClassDescriptor
*
canonicalize
(
Context
*
ctx
);
// Linking sets the position index in any contained TypeVariable type
// to correspond to the location of that identifier in the formal type
// parameters.
void
bind_variables_to_parameters
();
};
class
MethodDescriptor
:
public
Descriptor
{
private:
GrowableArray
<
Type
*>
_parameters
;
Type
*
_return_type
;
GrowableArray
<
Type
*>
_throws
;
MethodDescriptor
(
GrowableArray
<
TypeParameter
*>&
ftp
,
ClassDescriptor
*
outer
,
GrowableArray
<
Type
*>&
sigs
,
Type
*
rt
,
GrowableArray
<
Type
*>&
throws
)
:
Descriptor
(
ftp
,
outer
),
_parameters
(
sigs
),
_return_type
(
rt
),
_throws
(
throws
)
{}
public:
static
MethodDescriptor
*
parse_generic_signature
(
Method
*
m
,
ClassDescriptor
*
outer
);
static
MethodDescriptor
*
parse_generic_signature
(
Symbol
*
sym
,
ClassDescriptor
*
outer
);
MethodDescriptor
*
as_method_signature
()
{
return
this
;
}
// Performs generic analysis on the method parameters to determine
// if both methods refer to the same argument types.
bool
covariant_match
(
MethodDescriptor
*
other
,
Context
*
ctx
);
// Returns a new method descriptor with all generic variables
// removed and replaced with whatever is indicated using the Context.
MethodDescriptor
*
canonicalize
(
Context
*
ctx
);
void
bind_variables_to_parameters
();
#ifndef PRODUCT
TempNewSymbol
reify_signature
(
Context
*
ctx
,
TRAPS
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeParameter
:
public
ResourceObj
{
private:
Identifier
*
_identifier
;
ClassType
*
_class_bound
;
GrowableArray
<
ClassType
*>
_interface_bounds
;
// The position is the ordinal location of the parameter within the
// formal parameter list (excluding outer classes). It is only set for
// formal type parameters that are associated with a class -- method
// type parameters are left as -1. When resolving a generic variable to
// find the actual type, this index is used to access the generic type
// argument in the provided context object.
int
_position
;
// Assigned during variable linking
TypeParameter
(
Identifier
*
id
,
ClassType
*
class_bound
,
GrowableArray
<
ClassType
*>&
interface_bounds
)
:
_identifier
(
id
),
_class_bound
(
class_bound
),
_interface_bounds
(
interface_bounds
),
_position
(
-
1
)
{}
public:
static
TypeParameter
*
parse_generic_signature
(
DescriptorStream
*
str
);
ClassType
*
bound
();
int
position
()
{
return
_position
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
,
int
position
);
Identifier
*
identifier
()
{
return
_identifier
;
}
Type
*
resolve
(
Context
*
ctx
,
int
inner_depth
,
int
ctx_depth
);
TypeParameter
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
Type
:
public
ResourceObj
{
public:
static
Type
*
parse_generic_signature
(
DescriptorStream
*
str
);
virtual
ClassType
*
as_class
()
{
return
NULL
;
}
virtual
TypeVariable
*
as_variable
()
{
return
NULL
;
}
virtual
ArrayType
*
as_array
()
{
return
NULL
;
}
virtual
PrimitiveType
*
as_primitive
()
{
return
NULL
;
}
virtual
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
)
=
0
;
virtual
Type
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
)
=
0
;
virtual
void
bind_variables_to_parameters
(
Descriptor
*
sig
)
=
0
;
#ifndef PRODUCT
virtual
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
)
=
0
;
virtual
void
print_on
(
outputStream
*
str
)
const
=
0
;
#endif
};
class
ClassType
:
public
Type
{
friend
class
ClassDescriptor
;
protected:
Identifier
*
_identifier
;
GrowableArray
<
TypeArgument
*>
_type_arguments
;
ClassType
*
_outer_class
;
ClassType
(
Identifier
*
identifier
,
GrowableArray
<
TypeArgument
*>&
args
,
ClassType
*
outer
)
:
_identifier
(
identifier
),
_type_arguments
(
args
),
_outer_class
(
outer
)
{}
// Returns true if there are inner classes to read
static
Identifier
*
parse_generic_signature_simple
(
GrowableArray
<
TypeArgument
*>*
args
,
bool
*
has_inner
,
DescriptorStream
*
str
);
static
ClassType
*
parse_generic_signature
(
ClassType
*
outer
,
DescriptorStream
*
str
);
static
ClassType
*
from_symbol
(
Symbol
*
sym
);
public:
ClassType
*
as_class
()
{
return
this
;
}
static
ClassType
*
parse_generic_signature
(
DescriptorStream
*
str
);
static
ClassType
*
java_lang_Object
();
Identifier
*
identifier
()
{
return
_identifier
;
}
int
type_arguments_length
()
{
return
_type_arguments
.
length
();
}
TypeArgument
*
type_argument_at
(
int
i
);
virtual
ClassType
*
outer_class
()
{
return
_outer_class
;
}
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
ClassType
*
canonicalize
(
Context
*
ctx
,
int
context_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeVariable
:
public
Type
{
private:
Identifier
*
_id
;
TypeParameter
*
_parameter
;
// assigned during linking
// how many steps "out" from inner classes, -1 if method
int
_inner_depth
;
TypeVariable
(
Identifier
*
id
)
:
_id
(
id
),
_parameter
(
NULL
),
_inner_depth
(
0
)
{}
public:
TypeVariable
*
as_variable
()
{
return
this
;
}
static
TypeVariable
*
parse_generic_signature
(
DescriptorStream
*
str
);
Identifier
*
identifier
()
{
return
_id
;
}
TypeParameter
*
parameter
()
{
return
_parameter
;
}
int
inner_depth
()
{
return
_inner_depth
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
Type
*
resolve
(
Context
*
ctx
,
int
ctx_depth
);
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
Type
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
ArrayType
:
public
Type
{
private:
Type
*
_base
;
ArrayType
(
Type
*
base
)
:
_base
(
base
)
{}
public:
ArrayType
*
as_array
()
{
return
this
;
}
static
ArrayType
*
parse_generic_signature
(
DescriptorStream
*
str
);
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
ArrayType
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
PrimitiveType
:
public
Type
{
friend
class
Type
;
private:
char
_type
;
// includes V for void
PrimitiveType
(
char
&
type
)
:
_type
(
type
)
{}
public:
PrimitiveType
*
as_primitive
()
{
return
this
;
}
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
PrimitiveType
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeArgument
:
public
ResourceObj
{
private:
Type
*
_lower_bound
;
Type
*
_upper_bound
;
// may be null or == _lower_bound
TypeArgument
(
Type
*
lower_bound
,
Type
*
upper_bound
)
:
_lower_bound
(
lower_bound
),
_upper_bound
(
upper_bound
)
{}
public:
static
TypeArgument
*
parse_generic_signature
(
DescriptorStream
*
str
);
Type
*
lower_bound
()
{
return
_lower_bound
;
}
Type
*
upper_bound
()
{
return
_upper_bound
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
TypeArgument
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
bool
covariant_match
(
TypeArgument
*
a
,
Context
*
ctx
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
Context
:
public
ResourceObj
{
private:
DescriptorCache
*
_cache
;
GrowableArray
<
ClassType
*>
_type_arguments
;
void
reset_to_mark
(
int
size
);
public:
// When this object goes out of scope or 'destroy' is
// called, then the application of the type to the
// context is wound-back (unless it's been deactivated).
class
Mark
:
public
StackObj
{
private:
mutable
Context
*
_context
;
int
_marked_size
;
bool
is_active
()
const
{
return
_context
!=
NULL
;
}
void
deactivate
()
const
{
_context
=
NULL
;
}
public:
Mark
()
:
_context
(
NULL
),
_marked_size
(
0
)
{}
Mark
(
Context
*
ctx
,
int
sz
)
:
_context
(
ctx
),
_marked_size
(
sz
)
{}
Mark
(
const
Mark
&
m
)
:
_context
(
m
.
_context
),
_marked_size
(
m
.
_marked_size
)
{
m
.
deactivate
();
// Ownership is transferred
}
Mark
&
operator
=
(
const
Mark
&
cm
)
{
destroy
();
_context
=
cm
.
_context
;
_marked_size
=
cm
.
_marked_size
;
cm
.
deactivate
();
return
*
this
;
}
void
destroy
();
~
Mark
()
{
destroy
();
}
};
Context
(
DescriptorCache
*
cache
)
:
_cache
(
cache
)
{}
Mark
mark
()
{
return
Mark
(
this
,
_type_arguments
.
length
());
}
void
apply_type_arguments
(
InstanceKlass
*
current
,
InstanceKlass
*
super
,
TRAPS
);
ClassType
*
at_depth
(
int
i
)
const
;
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
/**
* Contains a cache of descriptors for classes and methods so they can be
* looked-up instead of reparsing each time they are needed.
*/
class
DescriptorCache
:
public
ResourceObj
{
private:
ResourceHashtable
<
InstanceKlass
*
,
ClassDescriptor
*>
_class_descriptors
;
ResourceHashtable
<
Method
*
,
MethodDescriptor
*>
_method_descriptors
;
public:
ClassDescriptor
*
descriptor_for
(
InstanceKlass
*
ikh
,
TRAPS
);
MethodDescriptor
*
descriptor_for
(
Method
*
mh
,
ClassDescriptor
*
cd
,
TRAPS
);
// Class descriptor derived from method holder
MethodDescriptor
*
descriptor_for
(
Method
*
mh
,
TRAPS
);
};
}
// namespace generic
#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
src/share/vm/classfile/systemDictionary.hpp
浏览文件 @
14ead889
...
...
@@ -137,6 +137,7 @@ class SymbolPropertyTable;
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */
\
/* Universe::is_gte_jdk14x_version() is not set up by this point. */
\
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */
\
do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
...
...
src/share/vm/classfile/verifier.cpp
浏览文件 @
14ead889
...
...
@@ -555,9 +555,10 @@ void ClassVerifier::verify_class(TRAPS) {
if
(
was_recursively_verified
())
return
;
Method
*
m
=
methods
->
at
(
index
);
if
(
m
->
is_native
()
||
m
->
is_abstract
())
{
if
(
m
->
is_native
()
||
m
->
is_abstract
()
||
m
->
is_overpass
()
)
{
// If m is native or abstract, skip it. It is checked in class file
// parser that methods do not override a final method.
// parser that methods do not override a final method. Overpass methods
// are trusted since the VM generates them.
continue
;
}
verify_method
(
methodHandle
(
THREAD
,
m
),
CHECK_VERIFY
(
this
));
...
...
@@ -2304,11 +2305,21 @@ void ClassVerifier::verify_invoke_instructions(
// Make sure the constant pool item is the right type
u2
index
=
bcs
->
get_index_u2
();
Bytecodes
::
Code
opcode
=
bcs
->
raw_code
();
unsigned
int
types
=
(
opcode
==
Bytecodes
::
_invokeinterface
?
1
<<
JVM_CONSTANT_InterfaceMethodref
:
opcode
==
Bytecodes
::
_invokedynamic
?
1
<<
JVM_CONSTANT_InvokeDynamic
:
1
<<
JVM_CONSTANT_Methodref
);
unsigned
int
types
;
switch
(
opcode
)
{
case
Bytecodes
::
_invokeinterface
:
types
=
1
<<
JVM_CONSTANT_InterfaceMethodref
;
break
;
case
Bytecodes
::
_invokedynamic
:
types
=
1
<<
JVM_CONSTANT_InvokeDynamic
;
break
;
case
Bytecodes
::
_invokespecial
:
types
=
(
1
<<
JVM_CONSTANT_InterfaceMethodref
)
|
(
1
<<
JVM_CONSTANT_Methodref
);
break
;
default:
types
=
1
<<
JVM_CONSTANT_Methodref
;
}
verify_cp_type
(
bcs
->
bci
(),
index
,
cp
,
types
,
CHECK_VERIFY
(
this
));
// Get method name and signature
...
...
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
14ead889
...
...
@@ -259,6 +259,7 @@
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */
\
template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
...
...
src/share/vm/code/dependencies.cpp
浏览文件 @
14ead889
...
...
@@ -1160,7 +1160,11 @@ bool Dependencies::is_concrete_method(Method* m) {
// We could also return false if m does not yet appear to be
// executed, if the VM version supports this distinction also.
return
!
m
->
is_abstract
();
return
!
m
->
is_abstract
()
&&
!
InstanceKlass
::
cast
(
m
->
method_holder
())
->
is_interface
();
// TODO: investigate whether default methods should be
// considered as "concrete" in this situation. For now they
// are not.
}
...
...
src/share/vm/interpreter/linkResolver.cpp
浏览文件 @
14ead889
...
...
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
...
...
@@ -404,21 +405,13 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
)
{
// 1. check if klass is not interface
if
(
resolved_klass
->
is_interface
())
{
ResourceMark
rm
(
THREAD
);
char
buf
[
200
];
jio_snprintf
(
buf
,
sizeof
(
buf
),
"Found interface %s, but class was expected"
,
Klass
::
cast
(
resolved_klass
())
->
external_name
());
THROW_MSG
(
vmSymbols
::
java_lang_IncompatibleClassChangeError
(),
buf
);
}
Handle
nested_exception
;
//
2
. lookup method in resolved klass and its super klasses
//
1
. lookup method in resolved klass and its super klasses
lookup_method_in_klasses
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
CHECK
);
if
(
resolved_method
.
is_null
())
{
// not found in the class hierarchy
//
3
. lookup method in all the interfaces implemented by the resolved klass
//
2
. lookup method in all the interfaces implemented by the resolved klass
lookup_method_in_interfaces
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
CHECK
);
if
(
resolved_method
.
is_null
())
{
...
...
@@ -432,7 +425,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
}
if
(
resolved_method
.
is_null
())
{
//
4
. method lookup failed
//
3
. method lookup failed
ResourceMark
rm
(
THREAD
);
THROW_MSG_CAUSE
(
vmSymbols
::
java_lang_NoSuchMethodError
(),
Method
::
name_and_sig_as_C_string
(
Klass
::
cast
(
resolved_klass
()),
...
...
@@ -442,6 +435,15 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
}
}
// 4. check if klass is not interface
if
(
resolved_klass
->
is_interface
()
&&
resolved_method
->
is_abstract
())
{
ResourceMark
rm
(
THREAD
);
char
buf
[
200
];
jio_snprintf
(
buf
,
sizeof
(
buf
),
"Found interface %s, but class was expected"
,
resolved_klass
()
->
external_name
());
THROW_MSG
(
vmSymbols
::
java_lang_IncompatibleClassChangeError
(),
buf
);
}
// 5. check if method is concrete
if
(
resolved_method
->
is_abstract
()
&&
!
resolved_klass
->
is_abstract
())
{
ResourceMark
rm
(
THREAD
);
...
...
@@ -743,6 +745,27 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
Symbol
*
method_name
,
Symbol
*
method_signature
,
KlassHandle
current_klass
,
bool
check_access
,
TRAPS
)
{
if
(
resolved_klass
->
is_interface
()
&&
current_klass
()
!=
NULL
)
{
// If the target class is a direct interface, treat this as a "super"
// default call.
//
// If the current method is an overpass that happens to call a direct
// super-interface's method, then we'll end up rerunning the default method
// analysis even though we don't need to, but that's ok since it will end
// up with the same answer.
InstanceKlass
*
ik
=
InstanceKlass
::
cast
(
current_klass
());
Array
<
Klass
*>*
interfaces
=
ik
->
local_interfaces
();
int
num_interfaces
=
interfaces
->
length
();
for
(
int
index
=
0
;
index
<
num_interfaces
;
index
++
)
{
if
(
interfaces
->
at
(
index
)
==
resolved_klass
())
{
Method
*
method
=
DefaultMethods
::
find_super_default
(
current_klass
(),
resolved_klass
(),
method_name
,
method_signature
,
CHECK
);
resolved_method
=
methodHandle
(
THREAD
,
method
);
return
;
}
}
}
resolve_method
(
resolved_method
,
resolved_klass
,
method_name
,
method_signature
,
current_klass
,
check_access
,
CHECK
);
// check if method name is <init>, that it is found in same klass as static type
...
...
@@ -784,11 +807,17 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle
{
KlassHandle
method_klass
=
KlassHandle
(
THREAD
,
resolved_method
->
method_holder
());
if
(
check_access
&&
const
bool
direct_calling_default_method
=
resolved_klass
()
!=
NULL
&&
resolved_method
()
!=
NULL
&&
resolved_klass
->
is_interface
()
&&
!
resolved_method
->
is_abstract
();
if
(
!
direct_calling_default_method
&&
check_access
&&
// a) check if ACC_SUPER flag is set for the current class
current_klass
->
is_super
()
&&
// b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
current_klass
->
is_subtype_of
(
method_klass
())
&&
current_klass
()
!=
method_klass
()
&&
current_klass
->
is_subtype_of
(
method_klass
())
&&
current_klass
()
!=
method_klass
()
&&
// c) check if the method is not <init>
resolved_method
->
name
()
!=
vmSymbols
::
object_initializer_name
())
{
// Lookup super method
...
...
src/share/vm/oops/constMethod.cpp
浏览文件 @
14ead889
...
...
@@ -34,29 +34,30 @@ const u2 ConstMethod::MAX_IDNUM = 0xFFFE;
const
u2
ConstMethod
::
UNSET_IDNUM
=
0xFFFF
;
ConstMethod
*
ConstMethod
::
allocate
(
ClassLoaderData
*
loader_data
,
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
TRAPS
)
{
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
MethodType
method_type
,
TRAPS
)
{
int
size
=
ConstMethod
::
size
(
byte_code_size
,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
,
checked_exceptions_length
);
return
new
(
loader_data
,
size
,
true
,
THREAD
)
ConstMethod
(
byte_code_size
,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
,
checked_exceptions_length
,
size
);
byte_code_size
,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
,
checked_exceptions_length
,
method_type
,
size
);
}
ConstMethod
::
ConstMethod
(
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
int
size
)
{
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
MethodType
method_type
,
int
size
)
{
No_Safepoint_Verifier
no_safepoint
;
set_interpreter_kind
(
Interpreter
::
invalid
);
...
...
@@ -69,6 +70,7 @@ ConstMethod::ConstMethod(int byte_code_size,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
);
set_method_type
(
method_type
);
assert
(
this
->
size
()
==
size
,
"wrong size for object"
);
}
...
...
src/share/vm/oops/constMethod.hpp
浏览文件 @
14ead889
...
...
@@ -108,12 +108,17 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
class
ConstMethod
:
public
MetaspaceObj
{
friend
class
VMStructs
;
public:
typedef
enum
{
NORMAL
,
OVERPASS
}
MethodType
;
private:
enum
{
_has_linenumber_table
=
1
,
_has_checked_exceptions
=
2
,
_has_localvariable_table
=
4
,
_has_exception_table
=
8
_has_exception_table
=
8
,
_is_overpass
=
16
};
// Bit vector of signature
...
...
@@ -145,19 +150,22 @@ private:
// Constructor
ConstMethod
(
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
int
size
);
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
MethodType
is_overpass
,
int
size
);
public:
static
ConstMethod
*
allocate
(
ClassLoaderData
*
loader_data
,
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
TRAPS
);
int
byte_code_size
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
MethodType
mt
,
TRAPS
);
bool
is_constMethod
()
const
{
return
true
;
}
...
...
@@ -179,6 +187,19 @@ public:
bool
has_exception_handler
()
const
{
return
(
_flags
&
_has_exception_table
)
!=
0
;
}
MethodType
method_type
()
const
{
return
((
_flags
&
_is_overpass
)
==
0
)
?
NORMAL
:
OVERPASS
;
}
void
set_method_type
(
MethodType
mt
)
{
if
(
mt
==
NORMAL
)
{
_flags
&=
~
(
_is_overpass
);
}
else
{
_flags
|=
_is_overpass
;
}
}
void
set_interpreter_kind
(
int
kind
)
{
_interpreter_kind
=
kind
;
}
int
interpreter_kind
(
void
)
const
{
return
_interpreter_kind
;
}
...
...
src/share/vm/oops/constantPool.cpp
浏览文件 @
14ead889
...
...
@@ -1143,16 +1143,21 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
int
from_oplen
=
operand_array_length
(
from_cp
->
operands
());
int
old_oplen
=
operand_array_length
(
to_cp
->
operands
());
if
(
from_oplen
!=
0
)
{
ClassLoaderData
*
loader_data
=
to_cp
->
pool_holder
()
->
class_loader_data
();
// append my operands to the target's operands array
if
(
old_oplen
==
0
)
{
to_cp
->
set_operands
(
from_cp
->
operands
());
// reuse; do not merge
// Can't just reuse from_cp's operand list because of deallocation issues
int
len
=
from_cp
->
operands
()
->
length
();
Array
<
u2
>*
new_ops
=
MetadataFactory
::
new_array
<
u2
>
(
loader_data
,
len
,
CHECK
);
Copy
::
conjoint_memory_atomic
(
from_cp
->
operands
()
->
adr_at
(
0
),
new_ops
->
adr_at
(
0
),
len
*
sizeof
(
u2
));
to_cp
->
set_operands
(
new_ops
);
}
else
{
int
old_len
=
to_cp
->
operands
()
->
length
();
int
from_len
=
from_cp
->
operands
()
->
length
();
int
old_off
=
old_oplen
*
sizeof
(
u2
);
int
from_off
=
from_oplen
*
sizeof
(
u2
);
// Use the metaspace for the destination constant pool
ClassLoaderData
*
loader_data
=
to_cp
->
pool_holder
()
->
class_loader_data
();
Array
<
u2
>*
new_operands
=
MetadataFactory
::
new_array
<
u2
>
(
loader_data
,
old_len
+
from_len
,
CHECK
);
int
fillp
=
0
,
len
=
0
;
// first part of dest
...
...
src/share/vm/oops/instanceKlass.cpp
浏览文件 @
14ead889
...
...
@@ -743,6 +743,35 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
}
}
if
(
this_oop
->
has_default_methods
())
{
// Step 7.5: initialize any interfaces which have default methods
for
(
int
i
=
0
;
i
<
this_oop
->
local_interfaces
()
->
length
();
++
i
)
{
Klass
*
iface
=
this_oop
->
local_interfaces
()
->
at
(
i
);
InstanceKlass
*
ik
=
InstanceKlass
::
cast
(
iface
);
if
(
ik
->
has_default_methods
()
&&
ik
->
should_be_initialized
())
{
ik
->
initialize
(
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
Handle
e
(
THREAD
,
PENDING_EXCEPTION
);
CLEAR_PENDING_EXCEPTION
;
{
EXCEPTION_MARK
;
// Locks object, set state, and notify all waiting threads
this_oop
->
set_initialization_state_and_notify
(
initialization_error
,
THREAD
);
// ignore any exception thrown, superclass initialization error is
// thrown below
CLEAR_PENDING_EXCEPTION
;
}
DTRACE_CLASSINIT_PROBE_WAIT
(
super__failed
,
InstanceKlass
::
cast
(
this_oop
()),
-
1
,
wait
);
THROW_OOP
(
e
());
}
}
}
}
// Step 8
{
assert
(
THREAD
->
is_Java_thread
(),
"non-JavaThread in initialize_impl"
);
...
...
@@ -1252,11 +1281,7 @@ static int linear_search(Array<Method*>* methods, Symbol* name, Symbol* signatur
}
#endif
Method
*
InstanceKlass
::
find_method
(
Symbol
*
name
,
Symbol
*
signature
)
const
{
return
InstanceKlass
::
find_method
(
methods
(),
name
,
signature
);
}
Method
*
InstanceKlass
::
find_method
(
Array
<
Method
*>*
methods
,
Symbol
*
name
,
Symbol
*
signature
)
{
static
int
binary_search
(
Array
<
Method
*>*
methods
,
Symbol
*
name
)
{
int
len
=
methods
->
length
();
// methods are sorted, so do binary search
int
l
=
0
;
...
...
@@ -1267,43 +1292,70 @@ Method* InstanceKlass::find_method(Array<Method*>* methods, Symbol* name, Symbol
assert
(
m
->
is_method
(),
"must be method"
);
int
res
=
m
->
name
()
->
fast_compare
(
name
);
if
(
res
==
0
)
{
// found matching name; do linear search to find matching signature
// first, quick check for common case
if
(
m
->
signature
()
==
signature
)
return
m
;
// search downwards through overloaded methods
int
i
;
for
(
i
=
mid
-
1
;
i
>=
l
;
i
--
)
{
return
mid
;
}
else
if
(
res
<
0
)
{
l
=
mid
+
1
;
}
else
{
h
=
mid
-
1
;
}
}
return
-
1
;
}
Method
*
InstanceKlass
::
find_method
(
Symbol
*
name
,
Symbol
*
signature
)
const
{
return
InstanceKlass
::
find_method
(
methods
(),
name
,
signature
);
}
Method
*
InstanceKlass
::
find_method
(
Array
<
Method
*>*
methods
,
Symbol
*
name
,
Symbol
*
signature
)
{
int
hit
=
binary_search
(
methods
,
name
);
if
(
hit
!=
-
1
)
{
Method
*
m
=
methods
->
at
(
hit
);
// Do linear search to find matching signature. First, quick check
// for common case
if
(
m
->
signature
()
==
signature
)
return
m
;
// search downwards through overloaded methods
int
i
;
for
(
i
=
hit
-
1
;
i
>=
0
;
--
i
)
{
Method
*
m
=
methods
->
at
(
i
);
assert
(
m
->
is_method
(),
"must be method"
);
if
(
m
->
name
()
!=
name
)
break
;
if
(
m
->
signature
()
==
signature
)
return
m
;
}
// search upwards
for
(
i
=
mid
+
1
;
i
<=
h
;
i
++
)
{
}
// search upwards
for
(
i
=
hit
+
1
;
i
<
methods
->
length
();
++
i
)
{
Method
*
m
=
methods
->
at
(
i
);
assert
(
m
->
is_method
(),
"must be method"
);
if
(
m
->
name
()
!=
name
)
break
;
if
(
m
->
signature
()
==
signature
)
return
m
;
}
// not found
#ifdef ASSERT
int
index
=
linear_search
(
methods
,
name
,
signature
);
assert
(
index
==
-
1
,
err_msg
(
"binary search should have found entry %d"
,
index
));
#endif
return
NULL
;
}
else
if
(
res
<
0
)
{
l
=
mid
+
1
;
}
else
{
h
=
mid
-
1
;
}
}
// not found
#ifdef ASSERT
int
index
=
linear_search
(
methods
,
name
,
signature
);
assert
(
index
==
-
1
,
err_msg
(
"binary search should have found entry %d"
,
index
));
int
index
=
linear_search
(
methods
,
name
,
signature
);
assert
(
index
==
-
1
,
err_msg
(
"binary search should have found entry %d"
,
index
));
#endif
}
return
NULL
;
}
int
InstanceKlass
::
find_method_by_name
(
Symbol
*
name
,
int
*
end
)
{
return
find_method_by_name
(
methods
(),
name
,
end
);
}
int
InstanceKlass
::
find_method_by_name
(
Array
<
Method
*>*
methods
,
Symbol
*
name
,
int
*
end_ptr
)
{
assert
(
end_ptr
!=
NULL
,
"just checking"
);
int
start
=
binary_search
(
methods
,
name
);
int
end
=
start
+
1
;
if
(
start
!=
-
1
)
{
while
(
start
-
1
>=
0
&&
(
methods
->
at
(
start
-
1
))
->
name
()
==
name
)
--
start
;
while
(
end
<
methods
->
length
()
&&
(
methods
->
at
(
end
))
->
name
()
==
name
)
++
end
;
*
end_ptr
=
end
;
return
start
;
}
return
-
1
;
}
Method
*
InstanceKlass
::
uncached_lookup_method
(
Symbol
*
name
,
Symbol
*
signature
)
const
{
Klass
*
klass
=
const_cast
<
InstanceKlass
*>
(
this
);
while
(
klass
!=
NULL
)
{
...
...
src/share/vm/oops/instanceKlass.hpp
浏览文件 @
14ead889
...
...
@@ -245,6 +245,10 @@ class InstanceKlass: public Klass {
unsigned
char
*
_cached_class_file_bytes
;
// JVMTI: cached class file, before retransformable agent modified it in CFLH
jint
_cached_class_file_len
;
// JVMTI: length of above
JvmtiCachedClassFieldMap
*
_jvmti_cached_class_field_map
;
// JVMTI: used during heap iteration
// true if class, superclass, or implemented interfaces have default methods
bool
_has_default_methods
;
volatile
u2
_idnum_allocated_count
;
// JNI/JVMTI: increments with the addition of methods, old ids don't change
// Method array.
Array
<
Method
*>*
_methods
;
...
...
@@ -492,6 +496,13 @@ class InstanceKlass: public Klass {
// (returns NULL if not found)
Method
*
lookup_method_in_all_interfaces
(
Symbol
*
name
,
Symbol
*
signature
)
const
;
// Find method indices by name. If a method with the specified name is
// found the index to the first method is returned, and 'end' is filled in
// with the index of first non-name-matching method. If no method is found
// -1 is returned.
int
find_method_by_name
(
Symbol
*
name
,
int
*
end
);
static
int
find_method_by_name
(
Array
<
Method
*>*
methods
,
Symbol
*
name
,
int
*
end
);
// constant pool
ConstantPool
*
constants
()
const
{
return
_constants
;
}
void
set_constants
(
ConstantPool
*
c
)
{
_constants
=
c
;
}
...
...
@@ -592,6 +603,9 @@ class InstanceKlass: public Klass {
return
_jvmti_cached_class_field_map
;
}
bool
has_default_methods
()
const
{
return
_has_default_methods
;
}
void
set_has_default_methods
(
bool
b
)
{
_has_default_methods
=
b
;
}
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline
u2
next_method_idnum
();
void
set_initial_method_idnum
(
u2
value
)
{
_idnum_allocated_count
=
value
;
}
...
...
@@ -728,7 +742,6 @@ class InstanceKlass: public Klass {
GrowableArray
<
Klass
*>*
compute_secondary_supers
(
int
num_extra_slots
);
bool
compute_is_subtype_of
(
Klass
*
k
);
bool
can_be_primary_super_slow
()
const
;
Klass
*
java_super
()
const
{
return
super
();
}
int
oop_size
(
oop
obj
)
const
{
return
size_helper
();
}
bool
oop_is_instance_slow
()
const
{
return
true
;
}
...
...
@@ -750,6 +763,10 @@ class InstanceKlass: public Klass {
return
(
InstanceKlass
*
)
k
;
}
InstanceKlass
*
java_super
()
const
{
return
(
super
()
==
NULL
)
?
NULL
:
cast
(
super
());
}
// Sizing (in words)
static
int
header_size
()
{
return
align_object_offset
(
sizeof
(
InstanceKlass
)
/
HeapWordSize
);
}
static
int
size
(
int
vtable_length
,
int
itable_length
,
...
...
src/share/vm/oops/klassVtable.cpp
浏览文件 @
14ead889
...
...
@@ -54,22 +54,16 @@ inline InstanceKlass* klassVtable::ik() const {
// the same name and signature as m), then m is a Miranda method which is
// entered as a public abstract method in C's vtable. From then on it should
// treated as any other public method in C for method over-ride purposes.
void
klassVtable
::
compute_vtable_size_and_num_mirandas
(
int
&
vtable_length
,
int
&
num_miranda_methods
,
Klass
*
super
,
Array
<
Method
*>*
methods
,
AccessFlags
class_flags
,
Handle
classloader
,
Symbol
*
classname
,
Array
<
Klass
*>*
local_interfaces
,
TRAPS
)
{
void
klassVtable
::
compute_vtable_size_and_num_mirandas
(
int
*
vtable_length_ret
,
int
*
num_new_mirandas
,
GrowableArray
<
Method
*>*
all_mirandas
,
Klass
*
super
,
Array
<
Method
*>*
methods
,
AccessFlags
class_flags
,
Handle
classloader
,
Symbol
*
classname
,
Array
<
Klass
*>*
local_interfaces
,
TRAPS
)
{
No_Safepoint_Verifier
nsv
;
// set up default result values
vtable_length
=
0
;
num_miranda_methods
=
0
;
int
vtable_length
=
0
;
// start off with super's vtable length
InstanceKlass
*
sk
=
(
InstanceKlass
*
)
super
;
...
...
@@ -86,9 +80,12 @@ void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
}
}
GrowableArray
<
Method
*>
new_mirandas
(
20
);
// compute the number of mirandas methods that must be added to the end
num_miranda_methods
=
get_num_mirandas
(
super
,
methods
,
local_interfaces
);
vtable_length
+=
(
num_miranda_methods
*
vtableEntry
::
size
());
get_mirandas
(
&
new_mirandas
,
all_mirandas
,
super
,
methods
,
local_interfaces
);
*
num_new_mirandas
=
new_mirandas
.
length
();
vtable_length
+=
*
num_new_mirandas
*
vtableEntry
::
size
();
if
(
Universe
::
is_bootstrapping
()
&&
vtable_length
==
0
)
{
// array classes don't have their superclass set correctly during
...
...
@@ -109,6 +106,8 @@ void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
"bad vtable size for class Object"
);
assert
(
vtable_length
%
vtableEntry
::
size
()
==
0
,
"bad vtable length"
);
assert
(
vtable_length
>=
Universe
::
base_vtable_size
(),
"vtable too small"
);
*
vtable_length_ret
=
vtable_length
;
}
int
klassVtable
::
index_of
(
Method
*
m
,
int
len
)
const
{
...
...
@@ -191,7 +190,7 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
}
// add miranda methods; it will also update the value of initialized
fill_in_mirandas
(
initialized
);
fill_in_mirandas
(
&
initialized
);
// In class hierarchies where the accessibility is not increasing (i.e., going from private ->
// package_private -> publicprotected), the vtable might actually be smaller than our initial
...
...
@@ -249,6 +248,11 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
return
superk
;
}
// Methods that are "effectively" final don't need vtable entries.
bool
method_is_effectively_final
(
AccessFlags
klass_flags
,
methodHandle
target
)
{
return
target
->
is_final
()
||
klass_flags
.
is_final
()
&&
!
target
->
is_overpass
();
}
// Update child's copy of super vtable for overrides
// OR return true if a new vtable entry is required
...
...
@@ -269,7 +273,7 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
return
false
;
}
if
(
klass
->
is_final
()
||
target_method
()
->
is_final
(
))
{
if
(
method_is_effectively_final
(
klass
->
access_flags
(),
target_method
))
{
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
...
...
@@ -406,7 +410,8 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
Symbol
*
classname
,
AccessFlags
class_flags
,
TRAPS
)
{
if
((
class_flags
.
is_final
()
||
target_method
()
->
is_final
())
||
if
(
method_is_effectively_final
(
class_flags
,
target_method
)
||
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
...
...
@@ -502,7 +507,7 @@ bool klassVtable::is_miranda_entry_at(int i) {
// miranda methods are interface methods in a class's vtable
if
(
mhk
->
is_interface
())
{
assert
(
m
->
is_public
()
&&
m
->
is_abstract
(),
"should be public and abstract
"
);
assert
(
m
->
is_public
()
,
"should be public
"
);
assert
(
ik
()
->
implements_interface
(
method_holder
)
,
"this class should implement the interface"
);
assert
(
is_miranda
(
m
,
ik
()
->
methods
(),
ik
()
->
super
()),
"should be a miranda_method"
);
return
true
;
...
...
@@ -532,19 +537,19 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* su
return
false
;
}
void
klassVtable
::
add_new_mirandas_to_list
(
GrowableArray
<
Method
*>*
list_of_current_mirandas
,
Array
<
Method
*>*
current_interface_method
s
,
Array
<
Method
*>*
class_methods
,
Klass
*
super
)
{
void
klassVtable
::
add_new_mirandas_to_list
s
(
GrowableArray
<
Method
*>*
new_mirandas
,
GrowableArray
<
Method
*>*
all_miranda
s
,
Array
<
Method
*>*
current_interface_methods
,
Array
<
Method
*>*
class_methods
,
Klass
*
super
)
{
// iterate thru the current interface's method to see if it a miranda
int
num_methods
=
current_interface_methods
->
length
();
for
(
int
i
=
0
;
i
<
num_methods
;
i
++
)
{
Method
*
im
=
current_interface_methods
->
at
(
i
);
bool
is_duplicate
=
false
;
int
num_of_current_mirandas
=
list_of_current
_mirandas
->
length
();
int
num_of_current_mirandas
=
new
_mirandas
->
length
();
// check for duplicate mirandas in different interfaces we implement
for
(
int
j
=
0
;
j
<
num_of_current_mirandas
;
j
++
)
{
Method
*
miranda
=
list_of_current
_mirandas
->
at
(
j
);
Method
*
miranda
=
new
_mirandas
->
at
(
j
);
if
((
im
->
name
()
==
miranda
->
name
())
&&
(
im
->
signature
()
==
miranda
->
signature
()))
{
is_duplicate
=
true
;
...
...
@@ -557,51 +562,47 @@ void klassVtable::add_new_mirandas_to_list(GrowableArray<Method*>* list_of_curre
InstanceKlass
*
sk
=
InstanceKlass
::
cast
(
super
);
// check if it is a duplicate of a super's miranda
if
(
sk
->
lookup_method_in_all_interfaces
(
im
->
name
(),
im
->
signature
())
==
NULL
)
{
list_of_current_mirandas
->
append
(
im
);
new_mirandas
->
append
(
im
);
}
if
(
all_mirandas
!=
NULL
)
{
all_mirandas
->
append
(
im
);
}
}
}
}
}
void
klassVtable
::
get_mirandas
(
GrowableArray
<
Method
*>*
mirandas
,
void
klassVtable
::
get_mirandas
(
GrowableArray
<
Method
*>*
new_mirandas
,
GrowableArray
<
Method
*>*
all_mirandas
,
Klass
*
super
,
Array
<
Method
*>*
class_methods
,
Array
<
Klass
*>*
local_interfaces
)
{
assert
((
mirandas
->
length
()
==
0
)
,
"current mirandas must be 0"
);
assert
((
new_
mirandas
->
length
()
==
0
)
,
"current mirandas must be 0"
);
// iterate thru the local interfaces looking for a miranda
int
num_local_ifs
=
local_interfaces
->
length
();
for
(
int
i
=
0
;
i
<
num_local_ifs
;
i
++
)
{
InstanceKlass
*
ik
=
InstanceKlass
::
cast
(
local_interfaces
->
at
(
i
));
add_new_mirandas_to_list
(
mirandas
,
ik
->
methods
(),
class_methods
,
super
);
add_new_mirandas_to_lists
(
new_mirandas
,
all_mirandas
,
ik
->
methods
(),
class_methods
,
super
);
// iterate thru each local's super interfaces
Array
<
Klass
*>*
super_ifs
=
ik
->
transitive_interfaces
();
int
num_super_ifs
=
super_ifs
->
length
();
for
(
int
j
=
0
;
j
<
num_super_ifs
;
j
++
)
{
InstanceKlass
*
sik
=
InstanceKlass
::
cast
(
super_ifs
->
at
(
j
));
add_new_mirandas_to_list
(
mirandas
,
sik
->
methods
(),
class_methods
,
super
);
add_new_mirandas_to_lists
(
new_mirandas
,
all_mirandas
,
sik
->
methods
(),
class_methods
,
super
);
}
}
}
// get number of mirandas
int
klassVtable
::
get_num_mirandas
(
Klass
*
super
,
Array
<
Method
*>*
class_methods
,
Array
<
Klass
*>*
local_interfaces
)
{
ResourceMark
rm
;
GrowableArray
<
Method
*>*
mirandas
=
new
GrowableArray
<
Method
*>
(
20
);
get_mirandas
(
mirandas
,
super
,
class_methods
,
local_interfaces
);
return
mirandas
->
length
();
}
// fill in mirandas
void
klassVtable
::
fill_in_mirandas
(
int
&
initialized
)
{
ResourceMark
rm
;
GrowableArray
<
Method
*>*
mirandas
=
new
GrowableArray
<
Method
*>
(
20
);
InstanceKlass
*
this_ik
=
ik
();
get_mirandas
(
mirandas
,
this_ik
->
super
(),
this_ik
->
methods
(),
this_ik
->
local_interfaces
());
int
num_mirandas
=
mirandas
->
length
();
for
(
int
i
=
0
;
i
<
num_mirandas
;
i
++
)
{
put_method_at
(
mirandas
->
at
(
i
),
initialized
);
initialized
++
;
void
klassVtable
::
fill_in_mirandas
(
int
*
initialized
)
{
GrowableArray
<
Method
*>
mirandas
(
20
);
get_mirandas
(
&
mirandas
,
NULL
,
ik
()
->
super
(),
ik
()
->
methods
(),
ik
()
->
local_interfaces
());
for
(
int
i
=
0
;
i
<
mirandas
.
length
();
i
++
)
{
put_method_at
(
mirandas
.
at
(
i
),
*
initialized
);
++
(
*
initialized
);
}
}
...
...
src/share/vm/oops/klassVtable.hpp
浏览文件 @
14ead889
...
...
@@ -84,11 +84,11 @@ class klassVtable : public ResourceObj {
bool
is_initialized
();
// computes vtable length (in words) and the number of miranda methods
static
void
compute_vtable_size_and_num_mirandas
(
int
&
vtable_length
,
int
&
num_miranda_methods
,
Klass
*
super
,
Array
<
Method
*>*
method
s
,
AccessFlags
class_flags
,
Handle
classload
er
,
Symbol
*
classname
,
Array
<
Klass
*>*
local_interfaces
,
TRAPS
);
static
void
compute_vtable_size_and_num_mirandas
(
int
*
vtable_length
,
int
*
num_new_miranda
s
,
GrowableArray
<
Method
*>*
all_mirandas
,
Klass
*
sup
er
,
Array
<
Method
*>*
methods
,
AccessFlags
class_flags
,
Handle
classloader
,
Symbol
*
classname
,
Array
<
Klass
*>*
local_interfaces
,
TRAPS
);
// RedefineClasses() API support:
// If any entry of this vtable points to any of old_methods,
...
...
@@ -125,12 +125,17 @@ class klassVtable : public ResourceObj {
// support for miranda methods
bool
is_miranda_entry_at
(
int
i
);
void
fill_in_mirandas
(
int
&
initialized
);
void
fill_in_mirandas
(
int
*
initialized
);
static
bool
is_miranda
(
Method
*
m
,
Array
<
Method
*>*
class_methods
,
Klass
*
super
);
static
void
add_new_mirandas_to_list
(
GrowableArray
<
Method
*>*
list_of_current_mirandas
,
Array
<
Method
*>*
current_interface_methods
,
Array
<
Method
*>*
class_methods
,
Klass
*
super
);
static
void
get_mirandas
(
GrowableArray
<
Method
*>*
mirandas
,
Klass
*
super
,
Array
<
Method
*>*
class_methods
,
Array
<
Klass
*>*
local_interfaces
);
static
int
get_num_mirandas
(
Klass
*
super
,
Array
<
Method
*>*
class_methods
,
Array
<
Klass
*>*
local_interfaces
);
static
void
add_new_mirandas_to_lists
(
GrowableArray
<
Method
*>*
new_mirandas
,
GrowableArray
<
Method
*>*
all_mirandas
,
Array
<
Method
*>*
current_interface_methods
,
Array
<
Method
*>*
class_methods
,
Klass
*
super
);
static
void
get_mirandas
(
GrowableArray
<
Method
*>*
new_mirandas
,
GrowableArray
<
Method
*>*
all_mirandas
,
Klass
*
super
,
Array
<
Method
*>*
class_methods
,
Array
<
Klass
*>*
local_interfaces
);
void
verify_against
(
outputStream
*
st
,
klassVtable
*
vt
,
int
index
);
inline
InstanceKlass
*
ik
()
const
;
...
...
src/share/vm/oops/method.cpp
浏览文件 @
14ead889
...
...
@@ -35,6 +35,7 @@
#include "memory/generation.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constMethod.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
...
...
@@ -57,22 +58,24 @@
// Implementation of Method
Method
*
Method
::
allocate
(
ClassLoaderData
*
loader_data
,
int
byte_code_size
,
AccessFlags
access_flags
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
TRAPS
)
{
int
byte_code_size
,
AccessFlags
access_flags
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
ConstMethod
::
MethodType
method_type
,
TRAPS
)
{
assert
(
!
access_flags
.
is_native
()
||
byte_code_size
==
0
,
"native methods should not contain byte codes"
);
ConstMethod
*
cm
=
ConstMethod
::
allocate
(
loader_data
,
byte_code_size
,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
,
checked_exceptions_length
,
CHECK_NULL
);
byte_code_size
,
compressed_line_number_size
,
localvariable_table_length
,
exception_table_length
,
checked_exceptions_length
,
method_type
,
CHECK_NULL
);
int
size
=
Method
::
size
(
access_flags
.
is_native
());
...
...
@@ -1031,7 +1034,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
methodHandle
m
;
{
Method
*
m_oop
=
Method
::
allocate
(
loader_data
,
0
,
accessFlags_from
(
flags_bits
),
0
,
0
,
0
,
0
,
CHECK_
(
empty
));
0
,
0
,
0
,
0
,
ConstMethod
::
NORMAL
,
CHECK_
(
empty
));
m
=
methodHandle
(
THREAD
,
m_oop
);
}
m
->
set_constants
(
cp
());
...
...
@@ -1083,15 +1086,16 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n
int
localvariable_len
=
m
->
localvariable_table_length
();
int
exception_table_len
=
m
->
exception_table_length
();
ClassLoaderData
*
loader_data
=
m
()
->
method_holder
()
->
class_loader_data
();
ClassLoaderData
*
loader_data
=
m
->
method_holder
()
->
class_loader_data
();
Method
*
newm_oop
=
Method
::
allocate
(
loader_data
,
new_code_length
,
flags
,
new_compressed_linenumber_size
,
localvariable_len
,
exception_table_len
,
checked_exceptions_len
,
CHECK_
(
methodHandle
()));
new_code_length
,
flags
,
new_compressed_linenumber_size
,
localvariable_len
,
exception_table_len
,
checked_exceptions_len
,
m
->
method_type
(),
CHECK_
(
methodHandle
()));
methodHandle
newm
(
THREAD
,
newm_oop
);
int
new_method_size
=
newm
->
method_size
();
...
...
src/share/vm/oops/method.hpp
浏览文件 @
14ead889
...
...
@@ -30,7 +30,6 @@
#include "compiler/oopMap.hpp"
#include "interpreter/invocationCounter.hpp"
#include "oops/annotations.hpp"
#include "oops/constMethod.hpp"
#include "oops/constantPool.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
...
...
@@ -104,6 +103,7 @@ class CheckedExceptionElement;
class
LocalVariableTableElement
;
class
AdapterHandlerEntry
;
class
MethodData
;
class
ConstMethod
;
class
Method
:
public
Metadata
{
friend
class
VMStructs
;
...
...
@@ -158,14 +158,16 @@ class Method : public Metadata {
// Constructor
Method
(
ConstMethod
*
xconst
,
AccessFlags
access_flags
,
int
size
);
public:
static
Method
*
allocate
(
ClassLoaderData
*
loader_data
,
int
byte_code_size
,
AccessFlags
access_flags
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
TRAPS
);
int
byte_code_size
,
AccessFlags
access_flags
,
int
compressed_line_number_size
,
int
localvariable_table_length
,
int
exception_table_length
,
int
checked_exceptions_length
,
ConstMethod
::
MethodType
method_type
,
TRAPS
);
Method
()
{
assert
(
DumpSharedSpaces
||
UseSharedSpaces
,
"only for CDS"
);
}
...
...
@@ -725,6 +727,10 @@ class Method : public Metadata {
void
set_dont_inline
(
bool
x
)
{
_dont_inline
=
x
;
}
bool
is_hidden
()
{
return
_hidden
;
}
void
set_hidden
(
bool
x
)
{
_hidden
=
x
;
}
ConstMethod
::
MethodType
method_type
()
const
{
return
_constMethod
->
method_type
();
}
bool
is_overpass
()
const
{
return
method_type
()
==
ConstMethod
::
OVERPASS
;
}
// On-stack replacement support
bool
has_osr_nmethod
(
int
level
,
bool
match_level
)
{
...
...
src/share/vm/runtime/globals.hpp
浏览文件 @
14ead889
...
...
@@ -3596,6 +3596,15 @@ class CommandLineFlags {
product(uintx, StringTableSize, 1009, \
"Number of buckets in the interned String table") \
\
develop(bool, TraceDefaultMethods, false, \
"Trace the default method processing steps") \
\
develop(bool, ParseAllGenericSignatures, false, \
"Parse all generic signatures while classloading") \
\
develop(bool, VerifyGenericSignatures, false, \
"Abort VM on erroneous or inconsistent generic signatures") \
\
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default value"\
...
...
src/share/vm/runtime/reflection.cpp
浏览文件 @
14ead889
...
...
@@ -472,6 +472,12 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo
return
true
;
}
// Also allow all accesses from
// java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
if
(
current_class
->
is_subclass_of
(
SystemDictionary
::
lambda_MagicLambdaImpl_klass
()))
{
return
true
;
}
return
can_relax_access_check_for
(
current_class
,
new_class
,
classloader_only
);
}
...
...
@@ -564,6 +570,12 @@ bool Reflection::verify_field_access(Klass* current_class,
return
true
;
}
// Also allow all accesses from
// java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
if
(
current_class
->
is_subclass_of
(
SystemDictionary
::
lambda_MagicLambdaImpl_klass
()))
{
return
true
;
}
return
can_relax_access_check_for
(
current_class
,
field_class
,
classloader_only
);
}
...
...
src/share/vm/utilities/growableArray.hpp
浏览文件 @
14ead889
...
...
@@ -217,7 +217,12 @@ template<class E> class GrowableArray : public GenericGrowableArray {
return
missed
;
}
E
at
(
int
i
)
const
{
E
&
at
(
int
i
)
{
assert
(
0
<=
i
&&
i
<
_len
,
"illegal index"
);
return
_data
[
i
];
}
E
const
&
at
(
int
i
)
const
{
assert
(
0
<=
i
&&
i
<
_len
,
"illegal index"
);
return
_data
[
i
];
}
...
...
src/share/vm/utilities/pair.hpp
0 → 100644
浏览文件 @
14ead889
/*
* 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_UTILITIES_PAIR_HPP
#define SHARE_VM_UTILITIES_PAIR_HPP
#include "memory/allocation.hpp"
#include "utilities/top.hpp"
template
<
typename
T
,
typename
V
,
typename
ALLOC_BASE
=
ResourceObj
>
class
Pair
:
public
ALLOC_BASE
{
public:
T
first
;
V
second
;
Pair
()
{}
Pair
(
T
t
,
V
v
)
:
first
(
t
),
second
(
v
)
{}
};
#endif // SHARE_VM_UTILITIES_PAIR_HPP
src/share/vm/utilities/resourceHash.hpp
0 → 100644
浏览文件 @
14ead889
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录