Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e1af249a
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看板
提交
e1af249a
编写于
10月 25, 2010
作者:
A
acorn
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
f9bc752b
6a30097f
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
1043 addition
and
0 deletion
+1043
-0
src/share/vm/classfile/stackMapTableFormat.hpp
src/share/vm/classfile/stackMapTableFormat.hpp
+916
-0
src/share/vm/includeDB_core
src/share/vm/includeDB_core
+4
-0
src/share/vm/oops/methodOop.hpp
src/share/vm/oops/methodOop.hpp
+4
-0
src/share/vm/runtime/relocator.cpp
src/share/vm/runtime/relocator.cpp
+118
-0
src/share/vm/runtime/relocator.hpp
src/share/vm/runtime/relocator.hpp
+1
-0
未找到文件。
src/share/vm/classfile/stackMapTableFormat.hpp
0 → 100644
浏览文件 @
e1af249a
/*
* Copyright (c) 2010, 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.
*
*/
// These classes represent the stack-map substructures described in the JVMS
// (hence the non-conforming naming scheme).
// These classes work with the types in their compressed form in-place (as they
// would appear in the classfile). No virtual methods or fields allowed.
class
verification_type_info
{
private:
// u1 tag
// u2 cpool_index || u2 bci (for ITEM_Object & ITEM_Uninitailized only)
address
tag_addr
()
const
{
return
(
address
)
this
;
}
address
cpool_index_addr
()
const
{
return
tag_addr
()
+
sizeof
(
u1
);
}
address
bci_addr
()
const
{
return
cpool_index_addr
();
}
protected:
// No constructors - should be 'private', but GCC issues a warning if it is
verification_type_info
()
{}
verification_type_info
(
const
verification_type_info
&
)
{}
public:
static
verification_type_info
*
at
(
address
addr
)
{
return
(
verification_type_info
*
)
addr
;
}
static
verification_type_info
*
create_at
(
address
addr
,
u1
tag
)
{
verification_type_info
*
vti
=
(
verification_type_info
*
)
addr
;
vti
->
set_tag
(
tag
);
return
vti
;
}
static
verification_type_info
*
create_object_at
(
address
addr
,
u2
cp_idx
)
{
verification_type_info
*
vti
=
(
verification_type_info
*
)
addr
;
vti
->
set_tag
(
ITEM_Object
);
vti
->
set_cpool_index
(
cp_idx
);
return
vti
;
}
static
verification_type_info
*
create_uninit_at
(
address
addr
,
u2
bci
)
{
verification_type_info
*
vti
=
(
verification_type_info
*
)
addr
;
vti
->
set_tag
(
ITEM_Uninitialized
);
vti
->
set_bci
(
bci
);
return
vti
;
}
static
size_t
calculate_size
(
u1
tag
)
{
if
(
tag
==
ITEM_Object
||
tag
==
ITEM_Uninitialized
)
{
return
sizeof
(
u1
)
+
sizeof
(
u2
);
}
else
{
return
sizeof
(
u1
);
}
}
static
size_t
max_size
()
{
return
sizeof
(
u1
)
+
sizeof
(
u2
);
}
u1
tag
()
const
{
return
*
(
u1
*
)
tag_addr
();
}
void
set_tag
(
u1
tag
)
{
*
((
u1
*
)
tag_addr
())
=
tag
;
}
bool
is_object
()
const
{
return
tag
()
==
ITEM_Object
;
}
bool
is_uninitialized
()
const
{
return
tag
()
==
ITEM_Uninitialized
;
}
u2
cpool_index
()
const
{
assert
(
is_object
(),
"This type has no cp_index"
);
return
Bytes
::
get_Java_u2
(
cpool_index_addr
());
}
void
set_cpool_index
(
u2
idx
)
{
assert
(
is_object
(),
"This type has no cp_index"
);
Bytes
::
put_Java_u2
(
cpool_index_addr
(),
idx
);
}
u2
bci
()
const
{
assert
(
is_uninitialized
(),
"This type has no bci"
);
return
Bytes
::
get_Java_u2
(
bci_addr
());
}
void
set_bci
(
u2
bci
)
{
assert
(
is_uninitialized
(),
"This type has no bci"
);
Bytes
::
put_Java_u2
(
bci_addr
(),
bci
);
}
void
copy_from
(
verification_type_info
*
from
)
{
set_tag
(
from
->
tag
());
if
(
from
->
is_object
())
{
set_cpool_index
(
from
->
cpool_index
());
}
else
if
(
from
->
is_uninitialized
())
{
set_bci
(
from
->
bci
());
}
}
size_t
size
()
const
{
return
calculate_size
(
tag
());
}
verification_type_info
*
next
()
{
return
(
verification_type_info
*
)((
address
)
this
+
size
());
}
// This method is used when reading unverified data in order to ensure
// that we don't read past a particular memory limit. It returns false
// if any part of the data structure is outside the specified memory bounds.
bool
verify
(
address
start
,
address
end
)
{
return
((
address
)
this
>=
start
&&
(
address
)
this
<
end
&&
(
bci_addr
()
+
sizeof
(
u2
)
<=
end
||
!
is_object
()
&&
!
is_uninitialized
()));
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
{
switch
(
tag
())
{
case
ITEM_Top
:
st
->
print
(
"Top"
);
break
;
case
ITEM_Integer
:
st
->
print
(
"Integer"
);
break
;
case
ITEM_Float
:
st
->
print
(
"Float"
);
break
;
case
ITEM_Double
:
st
->
print
(
"Double"
);
break
;
case
ITEM_Long
:
st
->
print
(
"Long"
);
break
;
case
ITEM_Null
:
st
->
print
(
"Null"
);
break
;
case
ITEM_UninitializedThis
:
st
->
print
(
"UninitializedThis"
);
break
;
case
ITEM_Uninitialized
:
st
->
print
(
"Uninitialized[#%d]"
,
bci
());
break
;
case
ITEM_Object
:
st
->
print
(
"Object[#%d]"
,
cpool_index
());
break
;
default:
assert
(
false
,
"Bad verification_type_info"
);
}
}
#endif
};
#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
macro(same_frame, arg1, arg2) \
macro(same_frame_extended, arg1, arg2) \
macro(same_frame_1_stack_item_frame, arg1, arg2) \
macro(same_frame_1_stack_item_extended, arg1, arg2) \
macro(chop_frame, arg1, arg2) \
macro(append_frame, arg1, arg2) \
macro(full_frame, arg1, arg2)
#define SM_FORWARD_DECL(type, arg1, arg2) class type;
FOR_EACH_STACKMAP_FRAME_TYPE
(
SM_FORWARD_DECL
,
x
,
x
)
#undef SM_FORWARD_DECL
class
stack_map_frame
{
protected:
address
frame_type_addr
()
const
{
return
(
address
)
this
;
}
// No constructors - should be 'private', but GCC issues a warning if it is
stack_map_frame
()
{}
stack_map_frame
(
const
stack_map_frame
&
)
{}
public:
static
stack_map_frame
*
at
(
address
addr
)
{
return
(
stack_map_frame
*
)
addr
;
}
stack_map_frame
*
next
()
const
{
return
at
((
address
)
this
+
size
());
}
u1
frame_type
()
const
{
return
*
(
u1
*
)
frame_type_addr
();
}
void
set_frame_type
(
u1
type
)
{
*
((
u1
*
)
frame_type_addr
())
=
type
;
}
// pseudo-virtual methods
inline
size_t
size
()
const
;
inline
int
offset_delta
()
const
;
inline
void
set_offset_delta
(
int
offset_delta
);
inline
int
number_of_types
()
const
;
// number of types contained in the frame
inline
verification_type_info
*
types
()
const
;
// pointer to first type
inline
bool
is_valid_offset
(
int
offset_delta
)
const
;
// This method must be used when reading unverified data in order to ensure
// that we don't read past a particular memory limit. It returns false
// if any part of the data structure is outside the specified memory bounds.
inline
bool
verify
(
address
start
,
address
end
)
const
;
#ifdef ASSERT
inline
void
print_on
(
outputStream
*
st
)
const
;
#endif
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
inline stackmap_frame_type* as_##stackmap_frame_type() const; \
bool is_##stackmap_frame_type() { \
return as_##stackmap_frame_type() != NULL; \
}
FOR_EACH_STACKMAP_FRAME_TYPE
(
FRAME_TYPE_DECL
,
x
,
x
)
#undef FRAME_TYPE_DECL
};
class
same_frame
:
public
stack_map_frame
{
private:
static
int
frame_type_to_offset_delta
(
u1
frame_type
)
{
return
frame_type
+
1
;
}
static
u1
offset_delta_to_frame_type
(
int
offset_delta
)
{
return
(
u1
)(
offset_delta
-
1
);
}
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
tag
<
64
;
}
static
same_frame
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
same_frame
*
)
addr
;
}
static
same_frame
*
create_at
(
address
addr
,
int
offset_delta
)
{
same_frame
*
sm
=
(
same_frame
*
)
addr
;
sm
->
set_offset_delta
(
offset_delta
);
return
sm
;
}
static
size_t
calculate_size
()
{
return
sizeof
(
u1
);
}
size_t
size
()
const
{
return
calculate_size
();
}
int
offset_delta
()
const
{
return
frame_type_to_offset_delta
(
frame_type
());
}
void
set_offset_delta
(
int
offset_delta
)
{
assert
(
offset_delta
<=
64
,
"Offset too large for same_frame"
);
set_frame_type
(
offset_delta_to_frame_type
(
offset_delta
));
}
int
number_of_types
()
const
{
return
0
;
}
verification_type_info
*
types
()
const
{
return
NULL
;
}
bool
is_valid_offset
(
int
offset_delta
)
const
{
return
is_frame_type
(
offset_delta_to_frame_type
(
offset_delta
));
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
return
true
;
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"same_frame(%d)"
,
offset_delta
());
}
#endif
};
class
same_frame_extended
:
public
stack_map_frame
{
private:
enum
{
_frame_id
=
251
};
address
offset_delta_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
tag
==
_frame_id
;
}
static
same_frame_extended
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame type"
);
return
(
same_frame_extended
*
)
addr
;
}
static
same_frame_extended
*
create_at
(
address
addr
,
u2
offset_delta
)
{
same_frame_extended
*
sm
=
(
same_frame_extended
*
)
addr
;
sm
->
set_frame_type
(
_frame_id
);
sm
->
set_offset_delta
(
offset_delta
);
return
sm
;
}
static
size_t
calculate_size
()
{
return
sizeof
(
u1
)
+
sizeof
(
u2
);
}
size_t
size
()
const
{
return
calculate_size
();
}
int
offset_delta
()
const
{
return
Bytes
::
get_Java_u2
(
offset_delta_addr
())
+
1
;
}
void
set_offset_delta
(
int
offset_delta
)
{
Bytes
::
put_Java_u2
(
offset_delta_addr
(),
offset_delta
-
1
);
}
int
number_of_types
()
const
{
return
0
;
}
verification_type_info
*
types
()
const
{
return
NULL
;
}
bool
is_valid_offset
(
int
offset
)
const
{
return
true
;
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
return
frame_type_addr
()
+
size
()
<=
end
;
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"same_frame_extended(%d)"
,
offset_delta
());
}
#endif
};
class
same_frame_1_stack_item_frame
:
public
stack_map_frame
{
private:
address
type_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
static
int
frame_type_to_offset_delta
(
u1
frame_type
)
{
return
frame_type
-
63
;
}
static
u1
offset_delta_to_frame_type
(
int
offset_delta
)
{
return
(
u1
)(
offset_delta
+
63
);
}
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
tag
>=
64
&&
tag
<
128
;
}
static
same_frame_1_stack_item_frame
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
same_frame_1_stack_item_frame
*
)
addr
;
}
static
same_frame_1_stack_item_frame
*
create_at
(
address
addr
,
int
offset_delta
,
verification_type_info
*
vti
)
{
same_frame_1_stack_item_frame
*
sm
=
(
same_frame_1_stack_item_frame
*
)
addr
;
sm
->
set_offset_delta
(
offset_delta
);
if
(
vti
!=
NULL
)
{
sm
->
set_type
(
vti
);
}
return
sm
;
}
static
size_t
calculate_size
(
verification_type_info
*
vti
)
{
return
sizeof
(
u1
)
+
vti
->
size
();
}
static
size_t
max_size
()
{
return
sizeof
(
u1
)
+
verification_type_info
::
max_size
();
}
size_t
size
()
const
{
return
calculate_size
(
types
());
}
int
offset_delta
()
const
{
return
frame_type_to_offset_delta
(
frame_type
());
}
void
set_offset_delta
(
int
offset_delta
)
{
assert
(
offset_delta
>
0
&&
offset_delta
<=
64
,
"Offset too large for this frame type"
);
set_frame_type
(
offset_delta_to_frame_type
(
offset_delta
));
}
void
set_type
(
verification_type_info
*
vti
)
{
verification_type_info
*
cur
=
types
();
cur
->
copy_from
(
vti
);
}
int
number_of_types
()
const
{
return
1
;
}
verification_type_info
*
types
()
const
{
return
verification_type_info
::
at
(
type_addr
());
}
bool
is_valid_offset
(
int
offset_delta
)
const
{
return
is_frame_type
(
offset_delta_to_frame_type
(
offset_delta
));
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
return
types
()
->
verify
(
start
,
end
);
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"same_frame_1_stack_item_frame(%d,"
,
offset_delta
());
types
()
->
print_on
(
st
);
st
->
print
(
")"
);
}
#endif
};
class
same_frame_1_stack_item_extended
:
public
stack_map_frame
{
private:
address
offset_delta_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
address
type_addr
()
const
{
return
offset_delta_addr
()
+
sizeof
(
u2
);
}
enum
{
_frame_id
=
247
};
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
tag
==
_frame_id
;
}
static
same_frame_1_stack_item_extended
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
same_frame_1_stack_item_extended
*
)
addr
;
}
static
same_frame_1_stack_item_extended
*
create_at
(
address
addr
,
int
offset_delta
,
verification_type_info
*
vti
)
{
same_frame_1_stack_item_extended
*
sm
=
(
same_frame_1_stack_item_extended
*
)
addr
;
sm
->
set_frame_type
(
_frame_id
);
sm
->
set_offset_delta
(
offset_delta
);
if
(
vti
!=
NULL
)
{
sm
->
set_type
(
vti
);
}
return
sm
;
}
static
size_t
calculate_size
(
verification_type_info
*
vti
)
{
return
sizeof
(
u1
)
+
sizeof
(
u2
)
+
vti
->
size
();
}
size_t
size
()
const
{
return
calculate_size
(
types
());
}
int
offset_delta
()
const
{
return
Bytes
::
get_Java_u2
(
offset_delta_addr
())
+
1
;
}
void
set_offset_delta
(
int
offset_delta
)
{
Bytes
::
put_Java_u2
(
offset_delta_addr
(),
offset_delta
-
1
);
}
void
set_type
(
verification_type_info
*
vti
)
{
verification_type_info
*
cur
=
types
();
cur
->
copy_from
(
vti
);
}
int
number_of_types
()
const
{
return
1
;
}
verification_type_info
*
types
()
const
{
return
verification_type_info
::
at
(
type_addr
());
}
bool
is_valid_offset
(
int
offset
)
{
return
true
;
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
return
type_addr
()
<
end
&&
types
()
->
verify
(
start
,
end
);
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"same_frame_1_stack_item_extended(%d,"
,
offset_delta
());
types
()
->
print_on
(
st
);
st
->
print
(
")"
);
}
#endif
};
class
chop_frame
:
public
stack_map_frame
{
private:
address
offset_delta_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
static
int
frame_type_to_chops
(
u1
frame_type
)
{
int
chop
=
251
-
frame_type
;
return
chop
;
}
static
u1
chops_to_frame_type
(
int
chop
)
{
return
251
-
chop
;
}
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
frame_type_to_chops
(
tag
)
>
0
&&
frame_type_to_chops
(
tag
)
<
4
;
}
static
chop_frame
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
chop_frame
*
)
addr
;
}
static
chop_frame
*
create_at
(
address
addr
,
int
offset_delta
,
int
chops
)
{
chop_frame
*
sm
=
(
chop_frame
*
)
addr
;
sm
->
set_chops
(
chops
);
sm
->
set_offset_delta
(
offset_delta
);
return
sm
;
}
static
size_t
calculate_size
()
{
return
sizeof
(
u1
)
+
sizeof
(
u2
);
}
size_t
size
()
const
{
return
calculate_size
();
}
int
offset_delta
()
const
{
return
Bytes
::
get_Java_u2
(
offset_delta_addr
())
+
1
;
}
void
set_offset_delta
(
int
offset_delta
)
{
Bytes
::
put_Java_u2
(
offset_delta_addr
(),
offset_delta
-
1
);
}
int
chops
()
const
{
int
chops
=
frame_type_to_chops
(
frame_type
());
assert
(
chops
>
0
&&
chops
<
4
,
"Invalid number of chops in frame"
);
return
chops
;
}
void
set_chops
(
int
chops
)
{
assert
(
chops
>
0
&&
chops
<=
3
,
"Bad number of chops"
);
set_frame_type
(
chops_to_frame_type
(
chops
));
}
int
number_of_types
()
const
{
return
0
;
}
verification_type_info
*
types
()
const
{
return
NULL
;
}
bool
is_valid_offset
(
int
offset
)
{
return
true
;
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
return
frame_type_addr
()
+
size
()
<=
end
;
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"chop_frame(%d,%d)"
,
offset_delta
(),
chops
());
}
#endif
};
class
append_frame
:
public
stack_map_frame
{
private:
address
offset_delta_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
address
types_addr
()
const
{
return
offset_delta_addr
()
+
sizeof
(
u2
);
}
static
int
frame_type_to_appends
(
u1
frame_type
)
{
int
append
=
frame_type
-
251
;
return
append
;
}
static
u1
appends_to_frame_type
(
int
appends
)
{
assert
(
appends
>
0
&&
appends
<
4
,
"Invalid append amount"
);
return
251
+
appends
;
}
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
frame_type_to_appends
(
tag
)
>
0
&&
frame_type_to_appends
(
tag
)
<
4
;
}
static
append_frame
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
append_frame
*
)
addr
;
}
static
append_frame
*
create_at
(
address
addr
,
int
offset_delta
,
int
appends
,
verification_type_info
*
types
)
{
append_frame
*
sm
=
(
append_frame
*
)
addr
;
sm
->
set_appends
(
appends
);
sm
->
set_offset_delta
(
offset_delta
);
if
(
types
!=
NULL
)
{
verification_type_info
*
cur
=
sm
->
types
();
for
(
int
i
=
0
;
i
<
appends
;
++
i
)
{
cur
->
copy_from
(
types
);
cur
=
cur
->
next
();
types
=
types
->
next
();
}
}
return
sm
;
}
static
size_t
calculate_size
(
int
appends
,
verification_type_info
*
types
)
{
size_t
sz
=
sizeof
(
u1
)
+
sizeof
(
u2
);
for
(
int
i
=
0
;
i
<
appends
;
++
i
)
{
sz
+=
types
->
size
();
types
=
types
->
next
();
}
return
sz
;
}
static
size_t
max_size
()
{
return
sizeof
(
u1
)
+
sizeof
(
u2
)
+
3
*
verification_type_info
::
max_size
();
}
size_t
size
()
const
{
return
calculate_size
(
number_of_types
(),
types
());
}
int
offset_delta
()
const
{
return
Bytes
::
get_Java_u2
(
offset_delta_addr
())
+
1
;
}
void
set_offset_delta
(
int
offset_delta
)
{
Bytes
::
put_Java_u2
(
offset_delta_addr
(),
offset_delta
-
1
);
}
void
set_appends
(
int
appends
)
{
assert
(
appends
>
0
&&
appends
<
4
,
"Bad number of appends"
);
set_frame_type
(
appends_to_frame_type
(
appends
));
}
int
number_of_types
()
const
{
int
appends
=
frame_type_to_appends
(
frame_type
());
assert
(
appends
>
0
&&
appends
<
4
,
"Invalid number of appends in frame"
);
return
appends
;
}
verification_type_info
*
types
()
const
{
return
verification_type_info
::
at
(
types_addr
());
}
bool
is_valid_offset
(
int
offset
)
const
{
return
true
;
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
verification_type_info
*
vti
=
types
();
if
((
address
)
vti
<
end
&&
vti
->
verify
(
start
,
end
))
{
int
nof
=
number_of_types
();
vti
=
vti
->
next
();
if
(
nof
<
2
||
vti
->
verify
(
start
,
end
))
{
vti
=
vti
->
next
();
if
(
nof
<
3
||
vti
->
verify
(
start
,
end
))
{
return
true
;
}
}
}
return
false
;
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"append_frame(%d,"
,
offset_delta
());
verification_type_info
*
vti
=
types
();
for
(
int
i
=
0
;
i
<
number_of_types
();
++
i
)
{
vti
->
print_on
(
st
);
if
(
i
!=
number_of_types
()
-
1
)
{
st
->
print
(
","
);
}
vti
=
vti
->
next
();
}
st
->
print
(
")"
);
}
#endif
};
class
full_frame
:
public
stack_map_frame
{
private:
address
offset_delta_addr
()
const
{
return
frame_type_addr
()
+
sizeof
(
u1
);
}
address
num_locals_addr
()
const
{
return
offset_delta_addr
()
+
sizeof
(
u2
);
}
address
locals_addr
()
const
{
return
num_locals_addr
()
+
sizeof
(
u2
);
}
address
stack_slots_addr
(
address
end_of_locals
)
const
{
return
end_of_locals
;
}
address
stack_addr
(
address
end_of_locals
)
const
{
return
stack_slots_addr
(
end_of_locals
)
+
sizeof
(
u2
);
}
enum
{
_frame_id
=
255
};
public:
static
bool
is_frame_type
(
u1
tag
)
{
return
tag
==
_frame_id
;
}
static
full_frame
*
at
(
address
addr
)
{
assert
(
is_frame_type
(
*
addr
),
"Wrong frame id"
);
return
(
full_frame
*
)
addr
;
}
static
full_frame
*
create_at
(
address
addr
,
int
offset_delta
,
int
num_locals
,
verification_type_info
*
locals
,
int
stack_slots
,
verification_type_info
*
stack
)
{
full_frame
*
sm
=
(
full_frame
*
)
addr
;
sm
->
set_frame_type
(
_frame_id
);
sm
->
set_offset_delta
(
offset_delta
);
sm
->
set_num_locals
(
num_locals
);
if
(
locals
!=
NULL
)
{
verification_type_info
*
cur
=
sm
->
locals
();
for
(
int
i
=
0
;
i
<
num_locals
;
++
i
)
{
cur
->
copy_from
(
locals
);
cur
=
cur
->
next
();
locals
=
locals
->
next
();
}
address
end_of_locals
=
(
address
)
cur
;
sm
->
set_stack_slots
(
end_of_locals
,
stack_slots
);
cur
=
sm
->
stack
(
end_of_locals
);
for
(
int
i
=
0
;
i
<
stack_slots
;
++
i
)
{
cur
->
copy_from
(
stack
);
cur
=
cur
->
next
();
stack
=
stack
->
next
();
}
}
return
sm
;
}
static
size_t
calculate_size
(
int
num_locals
,
verification_type_info
*
locals
,
int
stack_slots
,
verification_type_info
*
stack
)
{
size_t
sz
=
sizeof
(
u1
)
+
sizeof
(
u2
)
+
sizeof
(
u2
)
+
sizeof
(
u2
);
verification_type_info
*
vti
=
locals
;
for
(
int
i
=
0
;
i
<
num_locals
;
++
i
)
{
sz
+=
vti
->
size
();
vti
=
vti
->
next
();
}
vti
=
stack
;
for
(
int
i
=
0
;
i
<
stack_slots
;
++
i
)
{
sz
+=
vti
->
size
();
vti
=
vti
->
next
();
}
return
sz
;
}
static
size_t
max_size
(
int
locals
,
int
stack
)
{
return
sizeof
(
u1
)
+
3
*
sizeof
(
u2
)
+
(
locals
+
stack
)
*
verification_type_info
::
max_size
();
}
size_t
size
()
const
{
address
eol
=
end_of_locals
();
return
calculate_size
(
num_locals
(),
locals
(),
stack_slots
(
eol
),
stack
(
eol
));
}
int
offset_delta
()
const
{
return
Bytes
::
get_Java_u2
(
offset_delta_addr
())
+
1
;
}
int
num_locals
()
const
{
return
Bytes
::
get_Java_u2
(
num_locals_addr
());
}
verification_type_info
*
locals
()
const
{
return
verification_type_info
::
at
(
locals_addr
());
}
address
end_of_locals
()
const
{
verification_type_info
*
vti
=
locals
();
for
(
int
i
=
0
;
i
<
num_locals
();
++
i
)
{
vti
=
vti
->
next
();
}
return
(
address
)
vti
;
}
int
stack_slots
(
address
end_of_locals
)
const
{
return
Bytes
::
get_Java_u2
(
stack_slots_addr
(
end_of_locals
));
}
verification_type_info
*
stack
(
address
end_of_locals
)
const
{
return
verification_type_info
::
at
(
stack_addr
(
end_of_locals
));
}
void
set_offset_delta
(
int
offset_delta
)
{
Bytes
::
put_Java_u2
(
offset_delta_addr
(),
offset_delta
-
1
);
}
void
set_num_locals
(
int
num_locals
)
{
Bytes
::
put_Java_u2
(
num_locals_addr
(),
num_locals
);
}
void
set_stack_slots
(
address
end_of_locals
,
int
stack_slots
)
{
Bytes
::
put_Java_u2
(
stack_slots_addr
(
end_of_locals
),
stack_slots
);
}
// These return only the locals. Extra processing is required for stack
// types of full frames.
int
number_of_types
()
const
{
return
num_locals
();
}
verification_type_info
*
types
()
const
{
return
locals
();
}
bool
is_valid_offset
(
int
offset
)
{
return
true
;
}
bool
verify_subtype
(
address
start
,
address
end
)
const
{
verification_type_info
*
vti
=
types
();
if
((
address
)
vti
>=
end
)
{
return
false
;
}
int
count
=
number_of_types
();
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
vti
->
verify
(
start
,
end
))
{
return
false
;
}
vti
=
vti
->
next
();
}
address
eol
=
(
address
)
vti
;
if
(
eol
+
sizeof
(
u2
)
>
end
)
{
return
false
;
}
count
=
stack_slots
(
eol
);
vti
=
stack
(
eol
);
for
(
int
i
=
0
;
i
<
stack_slots
(
eol
);
++
i
)
{
if
(
!
vti
->
verify
(
start
,
end
))
{
return
false
;
}
vti
=
vti
->
next
();
}
return
true
;
}
#ifdef ASSERT
void
print_on
(
outputStream
*
st
)
const
{
st
->
print
(
"full_frame(%d,{"
,
offset_delta
());
verification_type_info
*
vti
=
locals
();
for
(
int
i
=
0
;
i
<
num_locals
();
++
i
)
{
vti
->
print_on
(
st
);
if
(
i
!=
num_locals
()
-
1
)
{
st
->
print
(
","
);
}
vti
=
vti
->
next
();
}
st
->
print
(
"},{"
);
address
end_of_locals
=
(
address
)
vti
;
vti
=
stack
(
end_of_locals
);
int
ss
=
stack_slots
(
end_of_locals
);
for
(
int
i
=
0
;
i
<
ss
;
++
i
)
{
vti
->
print_on
(
st
);
if
(
i
!=
ss
-
1
)
{
st
->
print
(
","
);
}
vti
=
vti
->
next
();
}
st
->
print
(
"})"
);
}
#endif
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
if (item_##stack_frame_type != NULL) { \
return item_##stack_frame_type->func_name args; \
}
#define VOID_VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \
if (item_##stack_frame_type != NULL) { \
item_##stack_frame_type->func_name args; \
return; \
}
size_t
stack_map_frame
::
size
()
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
size
,
());
return
0
;
}
int
stack_map_frame
::
offset_delta
()
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
offset_delta
,
());
return
0
;
}
void
stack_map_frame
::
set_offset_delta
(
int
offset_delta
)
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VOID_VIRTUAL_DISPATCH
,
set_offset_delta
,
(
offset_delta
));
}
int
stack_map_frame
::
number_of_types
()
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
number_of_types
,
());
return
0
;
}
verification_type_info
*
stack_map_frame
::
types
()
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
types
,
());
return
NULL
;
}
bool
stack_map_frame
::
is_valid_offset
(
int
offset
)
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
is_valid_offset
,
(
offset
));
return
true
;
}
bool
stack_map_frame
::
verify
(
address
start
,
address
end
)
const
{
if
(
frame_type_addr
()
>=
start
&&
frame_type_addr
()
<
end
)
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VIRTUAL_DISPATCH
,
verify_subtype
,
(
start
,
end
));
}
return
false
;
}
#ifdef ASSERT
void
stack_map_frame
::
print_on
(
outputStream
*
st
)
const
{
FOR_EACH_STACKMAP_FRAME_TYPE
(
VOID_VIRTUAL_DISPATCH
,
print_on
,
(
st
));
}
#endif
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
#define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \
stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \
if (stack_frame_type::is_frame_type(frame_type())) { \
return (stack_frame_type*)this; \
} else { \
return NULL; \
} \
}
FOR_EACH_STACKMAP_FRAME_TYPE
(
AS_SUBTYPE_DEF
,
x
,
x
)
#undef AS_SUBTYPE_DEF
class
stack_map_table_attribute
{
private:
address
name_index_addr
()
const
{
return
(
address
)
this
;
}
address
attribute_length_addr
()
const
{
return
name_index_addr
()
+
sizeof
(
u2
);
}
address
number_of_entries_addr
()
const
{
return
attribute_length_addr
()
+
sizeof
(
u4
);
}
address
entries_addr
()
const
{
return
number_of_entries_addr
()
+
sizeof
(
u2
);
}
protected:
// No constructors - should be 'private', but GCC issues a warning if it is
stack_map_table_attribute
()
{}
stack_map_table_attribute
(
const
stack_map_table_attribute
&
)
{}
public:
static
stack_map_table_attribute
*
at
(
address
addr
)
{
return
(
stack_map_table_attribute
*
)
addr
;
}
u2
name_index
()
const
{
return
Bytes
::
get_Java_u2
(
name_index_addr
());
}
u4
attribute_length
()
const
{
return
Bytes
::
get_Java_u4
(
attribute_length_addr
());
}
u2
number_of_entries
()
const
{
return
Bytes
::
get_Java_u2
(
number_of_entries_addr
());
}
stack_map_frame
*
entries
()
const
{
return
stack_map_frame
::
at
(
entries_addr
());
}
static
size_t
header_size
()
{
return
sizeof
(
u2
)
+
sizeof
(
u4
);
}
void
set_name_index
(
u2
idx
)
{
Bytes
::
put_Java_u2
(
name_index_addr
(),
idx
);
}
void
set_attribute_length
(
u4
len
)
{
Bytes
::
put_Java_u4
(
attribute_length_addr
(),
len
);
}
void
set_number_of_entries
(
u2
num
)
{
Bytes
::
put_Java_u2
(
number_of_entries_addr
(),
num
);
}
};
src/share/vm/includeDB_core
浏览文件 @
e1af249a
...
...
@@ -3614,7 +3614,9 @@ relocInfo_<arch>.hpp generate_platform_dependent_include
relocator.cpp bytecodes.hpp
relocator.cpp handles.inline.hpp
relocator.cpp oop.inline.hpp
relocator.cpp oopFactory.hpp
relocator.cpp relocator.hpp
relocator.cpp stackMapTableFormat.hpp
relocator.cpp universe.inline.hpp
relocator.hpp bytecodes.hpp
...
...
@@ -3921,6 +3923,8 @@ stackMapTable.hpp globalDefinitions.hpp
stackMapTable.hpp methodOop.hpp
stackMapTable.hpp stackMapFrame.hpp
stackMapTableFormat.hpp verificationType.hpp
stackValue.cpp debugInfo.hpp
stackValue.cpp frame.inline.hpp
stackValue.cpp handles.inline.hpp
...
...
src/share/vm/oops/methodOop.hpp
浏览文件 @
e1af249a
...
...
@@ -247,6 +247,10 @@ class methodOopDesc : public oopDesc {
return
constMethod
()
->
stackmap_data
();
}
void
set_stackmap_data
(
typeArrayOop
sd
)
{
constMethod
()
->
set_stackmap_data
(
sd
);
}
// exception handler table
typeArrayOop
exception_table
()
const
{
return
constMethod
()
->
exception_table
();
}
...
...
src/share/vm/runtime/relocator.cpp
浏览文件 @
e1af249a
...
...
@@ -435,6 +435,120 @@ void Relocator::adjust_local_var_table(int bci, int delta) {
}
}
// Create a new array, copying the src array but adding a hole at
// the specified location
static
typeArrayOop
insert_hole_at
(
size_t
where
,
int
hole_sz
,
typeArrayOop
src
)
{
Thread
*
THREAD
=
Thread
::
current
();
Handle
src_hnd
(
THREAD
,
src
);
typeArrayOop
dst
=
oopFactory
::
new_permanent_byteArray
(
src
->
length
()
+
hole_sz
,
CHECK_NULL
);
src
=
(
typeArrayOop
)
src_hnd
();
address
src_addr
=
(
address
)
src
->
byte_at_addr
(
0
);
address
dst_addr
=
(
address
)
dst
->
byte_at_addr
(
0
);
memcpy
(
dst_addr
,
src_addr
,
where
);
memcpy
(
dst_addr
+
where
+
hole_sz
,
src_addr
+
where
,
src
->
length
()
-
where
);
return
dst
;
}
// The width of instruction at "bci" is changing by "delta". Adjust the stack
// map frames.
void
Relocator
::
adjust_stack_map_table
(
int
bci
,
int
delta
)
{
if
(
method
()
->
has_stackmap_table
())
{
typeArrayOop
data
=
method
()
->
stackmap_data
();
// The data in the array is a classfile representation of the stackmap
// table attribute, less the initial u2 tag and u4 attribute_length fields.
stack_map_table_attribute
*
attr
=
stack_map_table_attribute
::
at
(
(
address
)
data
->
byte_at_addr
(
0
)
-
(
sizeof
(
u2
)
+
sizeof
(
u4
)));
int
count
=
attr
->
number_of_entries
();
stack_map_frame
*
frame
=
attr
->
entries
();
int
bci_iter
=
-
1
;
bool
offset_adjusted
=
false
;
// only need to adjust one offset
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
int
offset_delta
=
frame
->
offset_delta
();
bci_iter
+=
offset_delta
;
if
(
!
offset_adjusted
&&
bci_iter
>
bci
)
{
int
new_offset_delta
=
offset_delta
+
delta
;
if
(
frame
->
is_valid_offset
(
new_offset_delta
))
{
frame
->
set_offset_delta
(
new_offset_delta
);
}
else
{
assert
(
frame
->
is_same_frame
()
||
frame
->
is_same_frame_1_stack_item_frame
(),
"Frame must be one of the compressed forms"
);
// The new delta exceeds the capacity of the 'same_frame' or
// 'same_frame_1_stack_item_frame' frame types. We need to
// convert these frames to the extended versions, but the extended
// version is bigger and requires more room. So we allocate a
// new array and copy the data, being sure to leave u2-sized hole
// right after the 'frame_type' for the new offset field.
//
// We can safely ignore the reverse situation as a small delta
// can still be used in an extended version of the frame.
size_t
frame_offset
=
(
address
)
frame
-
(
address
)
data
->
byte_at_addr
(
0
);
data
=
insert_hole_at
(
frame_offset
+
1
,
2
,
data
);
if
(
data
==
NULL
)
{
return
;
// out-of-memory?
}
address
frame_addr
=
(
address
)(
data
->
byte_at_addr
(
0
)
+
frame_offset
);
frame
=
stack_map_frame
::
at
(
frame_addr
);
// Now convert the frames in place
if
(
frame
->
is_same_frame
())
{
same_frame_extended
::
create_at
(
frame_addr
,
new_offset_delta
);
}
else
{
same_frame_1_stack_item_extended
::
create_at
(
frame_addr
,
new_offset_delta
,
NULL
);
// the verification_info_type should already be at the right spot
}
}
offset_adjusted
=
true
;
// needs to be done only once, since subsequent
// values are offsets from the current
}
// The stack map frame may contain verification types, if so we need to
// check and update any Uninitialized type's bci (no matter where it is).
int
number_of_types
=
frame
->
number_of_types
();
verification_type_info
*
types
=
frame
->
types
();
for
(
int
i
=
0
;
i
<
number_of_types
;
++
i
)
{
if
(
types
->
is_uninitialized
()
&&
types
->
bci
()
>
bci
)
{
types
->
set_bci
(
types
->
bci
()
+
delta
);
}
types
=
types
->
next
();
}
// Full frame has stack values too
full_frame
*
ff
=
frame
->
as_full_frame
();
if
(
ff
!=
NULL
)
{
address
eol
=
(
address
)
types
;
number_of_types
=
ff
->
stack_slots
(
eol
);
types
=
ff
->
stack
(
eol
);
for
(
int
i
=
0
;
i
<
number_of_types
;
++
i
)
{
if
(
types
->
is_uninitialized
()
&&
types
->
bci
()
>
bci
)
{
types
->
set_bci
(
types
->
bci
()
+
delta
);
}
types
=
types
->
next
();
}
}
frame
=
frame
->
next
();
}
method
()
->
set_stackmap_data
(
data
);
// in case it has changed
}
}
bool
Relocator
::
expand_code_array
(
int
delta
)
{
int
length
=
MAX2
(
code_length
()
+
delta
,
code_length
()
*
(
100
+
code_slop_pct
())
/
100
);
...
...
@@ -499,6 +613,9 @@ bool Relocator::relocate_code(int bci, int ilen, int delta) {
// And local variable table...
adjust_local_var_table
(
bci
,
delta
);
// Adjust stack maps
adjust_stack_map_table
(
bci
,
delta
);
// Relocate the pending change stack...
for
(
int
j
=
0
;
j
<
_changes
->
length
();
j
++
)
{
ChangeItem
*
ci
=
_changes
->
at
(
j
);
...
...
@@ -641,6 +758,7 @@ bool Relocator::handle_switch_pad(int bci, int old_pad, bool is_lookup_switch) {
memmove
(
addr_at
(
bci
+
1
+
new_pad
),
addr_at
(
bci
+
1
+
old_pad
),
len
*
4
);
memset
(
addr_at
(
bci
+
1
),
0
,
new_pad
);
// pad must be 0
}
}
return
true
;
...
...
src/share/vm/runtime/relocator.hpp
浏览文件 @
e1af249a
...
...
@@ -105,6 +105,7 @@ class Relocator : public ResourceObj {
void
adjust_exception_table
(
int
bci
,
int
delta
);
void
adjust_line_no_table
(
int
bci
,
int
delta
);
void
adjust_local_var_table
(
int
bci
,
int
delta
);
void
adjust_stack_map_table
(
int
bci
,
int
delta
);
int
get_orig_switch_pad
(
int
bci
,
bool
is_lookup_switch
);
int
rc_instr_len
(
int
bci
);
bool
expand_code_array
(
int
delta
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录