Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
8f0618ad
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看板
提交
8f0618ad
编写于
10月 23, 2014
作者:
A
asaha
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
2f258210
32f45063
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
276 addition
and
112 deletion
+276
-112
.hgtags
.hgtags
+9
-0
make/hotspot_version
make/hotspot_version
+2
-2
src/share/vm/ci/bcEscapeAnalyzer.cpp
src/share/vm/ci/bcEscapeAnalyzer.cpp
+2
-2
src/share/vm/classfile/systemDictionary.cpp
src/share/vm/classfile/systemDictionary.cpp
+2
-1
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
+46
-29
src/share/vm/classfile/verifier.hpp
src/share/vm/classfile/verifier.hpp
+5
-4
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+1
-0
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
...ion/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+7
-1
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
...ion/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+4
-0
src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
+8
-1
src/share/vm/gc_implementation/g1/ptrQueue.cpp
src/share/vm/gc_implementation/g1/ptrQueue.cpp
+7
-3
src/share/vm/gc_implementation/g1/ptrQueue.hpp
src/share/vm/gc_implementation/g1/ptrQueue.hpp
+8
-5
src/share/vm/gc_implementation/g1/satbQueue.cpp
src/share/vm/gc_implementation/g1/satbQueue.cpp
+1
-1
src/share/vm/gc_implementation/g1/satbQueue.hpp
src/share/vm/gc_implementation/g1/satbQueue.hpp
+3
-4
src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
+2
-1
src/share/vm/memory/referenceProcessor.cpp
src/share/vm/memory/referenceProcessor.cpp
+24
-0
src/share/vm/memory/referenceProcessor.hpp
src/share/vm/memory/referenceProcessor.hpp
+2
-1
src/share/vm/memory/referenceType.hpp
src/share/vm/memory/referenceType.hpp
+2
-1
src/share/vm/memory/threadLocalAllocBuffer.cpp
src/share/vm/memory/threadLocalAllocBuffer.cpp
+4
-7
src/share/vm/memory/threadLocalAllocBuffer.hpp
src/share/vm/memory/threadLocalAllocBuffer.hpp
+1
-1
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+1
-0
src/share/vm/utilities/defaultStream.hpp
src/share/vm/utilities/defaultStream.hpp
+2
-0
src/share/vm/utilities/ostream.cpp
src/share/vm/utilities/ostream.cpp
+132
-48
未找到文件。
.hgtags
浏览文件 @
8f0618ad
...
@@ -501,6 +501,8 @@ f09d1f6a401e25a54dad44bb7bea482e47558af5 jdk8u20-b23
...
@@ -501,6 +501,8 @@ f09d1f6a401e25a54dad44bb7bea482e47558af5 jdk8u20-b23
00cf2b6f51b9560b01030e8f4c28c466f0b21fe3 hs25.20-b23
00cf2b6f51b9560b01030e8f4c28c466f0b21fe3 hs25.20-b23
19408d5fd31c25ce60c43dd33e92b96e8df4a4ea jdk8u20-b25
19408d5fd31c25ce60c43dd33e92b96e8df4a4ea jdk8u20-b25
eaa4074a7e3975cd33ec55e6b584586e2ac681bd jdk8u20-b26
eaa4074a7e3975cd33ec55e6b584586e2ac681bd jdk8u20-b26
7c9925f21c2529a88eb64b8039cc080f60b85e01 jdk8u20-b31
7edb04063a423e278fe34a0006d25fee198f495e jdk8u20-b32
4828415ebbf11e205dcc08e97ad5ae7dd03522f9 jdk8u40-b00
4828415ebbf11e205dcc08e97ad5ae7dd03522f9 jdk8u40-b00
d952af8cf67dd1e7ab5fec9a299c6c6dafd1863e hs25.40-b01
d952af8cf67dd1e7ab5fec9a299c6c6dafd1863e hs25.40-b01
f0afba33c928ddaa2d5f003b90d683c143f78ea3 hs25.40-b02
f0afba33c928ddaa2d5f003b90d683c143f78ea3 hs25.40-b02
...
@@ -544,6 +546,13 @@ e62c06b887310b5bd23be9b817a9a6f0daf0d0e1 jdk8u25-b15
...
@@ -544,6 +546,13 @@ e62c06b887310b5bd23be9b817a9a6f0daf0d0e1 jdk8u25-b15
6467bdd4d22d8b140844dc847c43b9ba7cb0bbd1 jdk8u25-b16
6467bdd4d22d8b140844dc847c43b9ba7cb0bbd1 jdk8u25-b16
28b50d07f6f8c5a567b6a25e95a423948114a004 jdk8u25-b17
28b50d07f6f8c5a567b6a25e95a423948114a004 jdk8u25-b17
639abc668bfe995dba811dd35411b9ea8a9041cd jdk8u25-b18
639abc668bfe995dba811dd35411b9ea8a9041cd jdk8u25-b18
c3528699fb33fe3eb1d117504184ae7ab2507aa1 jdk8u25-b31
5bb683bbe2c74876d585b5c3232fc3aab7b23e97 jdk8u31-b00
5bb686ae3b89f8aa1c74331b2d24e2a5ebd43448 jdk8u31-b01
087678da96603c9705b38b6cc4a6569ac7b4420a jdk8u31-b02
401cbaa475b4efe53153119ab87a82b217980a7f jdk8u31-b03
060cdf93040c1bfa5fdf580da5e9999042632cc8 jdk8u31-b04
6e56d7f1634f6c4cd4196e699c06e6ca2e6d6efb jdk8u31-b05
1b3abbeee961dee49780c0e4af5337feb918c555 jdk8u40-b10
1b3abbeee961dee49780c0e4af5337feb918c555 jdk8u40-b10
f10fe402dfb1543723b4b117a7cba3ea3d4159f1 hs25.40-b15
f10fe402dfb1543723b4b117a7cba3ea3d4159f1 hs25.40-b15
99372b2fee0eb8b3452f47230e84aa6e97003184 jdk8u40-b11
99372b2fee0eb8b3452f47230e84aa6e97003184 jdk8u40-b11
make/hotspot_version
浏览文件 @
8f0618ad
#
#
# Copyright (c) 2006, 201
4
, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 201
5
, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
#
# This code is free software; you can redistribute it and/or modify it
# This code is free software; you can redistribute it and/or modify it
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
#
#
# Don't put quotes (fail windows build).
# Don't put quotes (fail windows build).
HOTSPOT_VM_COPYRIGHT=Copyright 201
4
HOTSPOT_VM_COPYRIGHT=Copyright 201
5
HS_MAJOR_VER=25
HS_MAJOR_VER=25
HS_MINOR_VER=40
HS_MINOR_VER=40
...
...
src/share/vm/ci/bcEscapeAnalyzer.cpp
浏览文件 @
8f0618ad
...
@@ -89,8 +89,8 @@ class BCEscapeAnalyzer::StateInfo {
...
@@ -89,8 +89,8 @@ class BCEscapeAnalyzer::StateInfo {
public:
public:
ArgumentMap
*
_vars
;
ArgumentMap
*
_vars
;
ArgumentMap
*
_stack
;
ArgumentMap
*
_stack
;
shor
t
_stack_height
;
in
t
_stack_height
;
shor
t
_max_stack
;
in
t
_max_stack
;
bool
_initialized
;
bool
_initialized
;
ArgumentMap
empty_map
;
ArgumentMap
empty_map
;
...
...
src/share/vm/classfile/systemDictionary.cpp
浏览文件 @
8f0618ad
...
@@ -1908,11 +1908,12 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
...
@@ -1908,11 +1908,12 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
InstanceKlass
::
cast
(
WK_KLASS
(
Reference_klass
))
->
set_reference_type
(
REF_OTHER
);
InstanceKlass
::
cast
(
WK_KLASS
(
Reference_klass
))
->
set_reference_type
(
REF_OTHER
);
InstanceRefKlass
::
update_nonstatic_oop_maps
(
WK_KLASS
(
Reference_klass
));
InstanceRefKlass
::
update_nonstatic_oop_maps
(
WK_KLASS
(
Reference_klass
));
initialize_wk_klasses_through
(
WK_KLASS_ENUM_NAME
(
PhantomReference
_klass
),
scan
,
CHECK
);
initialize_wk_klasses_through
(
WK_KLASS_ENUM_NAME
(
Cleaner
_klass
),
scan
,
CHECK
);
InstanceKlass
::
cast
(
WK_KLASS
(
SoftReference_klass
))
->
set_reference_type
(
REF_SOFT
);
InstanceKlass
::
cast
(
WK_KLASS
(
SoftReference_klass
))
->
set_reference_type
(
REF_SOFT
);
InstanceKlass
::
cast
(
WK_KLASS
(
WeakReference_klass
))
->
set_reference_type
(
REF_WEAK
);
InstanceKlass
::
cast
(
WK_KLASS
(
WeakReference_klass
))
->
set_reference_type
(
REF_WEAK
);
InstanceKlass
::
cast
(
WK_KLASS
(
FinalReference_klass
))
->
set_reference_type
(
REF_FINAL
);
InstanceKlass
::
cast
(
WK_KLASS
(
FinalReference_klass
))
->
set_reference_type
(
REF_FINAL
);
InstanceKlass
::
cast
(
WK_KLASS
(
PhantomReference_klass
))
->
set_reference_type
(
REF_PHANTOM
);
InstanceKlass
::
cast
(
WK_KLASS
(
PhantomReference_klass
))
->
set_reference_type
(
REF_PHANTOM
);
InstanceKlass
::
cast
(
WK_KLASS
(
Cleaner_klass
))
->
set_reference_type
(
REF_CLEANER
);
// JSR 292 classes
// JSR 292 classes
WKID
jsr292_group_start
=
WK_KLASS_ENUM_NAME
(
MethodHandle_klass
);
WKID
jsr292_group_start
=
WK_KLASS_ENUM_NAME
(
MethodHandle_klass
);
...
...
src/share/vm/classfile/systemDictionary.hpp
浏览文件 @
8f0618ad
...
@@ -128,6 +128,7 @@ class Ticks;
...
@@ -128,6 +128,7 @@ class Ticks;
do_klass(WeakReference_klass, java_lang_ref_WeakReference, Pre ) \
do_klass(WeakReference_klass, java_lang_ref_WeakReference, Pre ) \
do_klass(FinalReference_klass, java_lang_ref_FinalReference, Pre ) \
do_klass(FinalReference_klass, java_lang_ref_FinalReference, Pre ) \
do_klass(PhantomReference_klass, java_lang_ref_PhantomReference, Pre ) \
do_klass(PhantomReference_klass, java_lang_ref_PhantomReference, Pre ) \
do_klass(Cleaner_klass, sun_misc_Cleaner, Pre ) \
do_klass(Finalizer_klass, java_lang_ref_Finalizer, Pre ) \
do_klass(Finalizer_klass, java_lang_ref_Finalizer, Pre ) \
\
\
do_klass(Thread_klass, java_lang_Thread, Pre ) \
do_klass(Thread_klass, java_lang_Thread, Pre ) \
...
...
src/share/vm/classfile/verifier.cpp
浏览文件 @
8f0618ad
...
@@ -1553,14 +1553,14 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
...
@@ -1553,14 +1553,14 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
case
Bytecodes
::
_invokespecial
:
case
Bytecodes
::
_invokespecial
:
case
Bytecodes
::
_invokestatic
:
case
Bytecodes
::
_invokestatic
:
verify_invoke_instructions
(
verify_invoke_instructions
(
&
bcs
,
code_length
,
&
current_frame
,
&
bcs
,
code_length
,
&
current_frame
,
(
bci
>=
ex_min
&&
bci
<
ex_max
),
&
this_uninit
,
return_type
,
cp
,
CHECK_VERIFY
(
this
));
&
this_uninit
,
return_type
,
cp
,
&
stackmap_table
,
CHECK_VERIFY
(
this
));
no_control_flow
=
false
;
break
;
no_control_flow
=
false
;
break
;
case
Bytecodes
::
_invokeinterface
:
case
Bytecodes
::
_invokeinterface
:
case
Bytecodes
::
_invokedynamic
:
case
Bytecodes
::
_invokedynamic
:
verify_invoke_instructions
(
verify_invoke_instructions
(
&
bcs
,
code_length
,
&
current_frame
,
&
bcs
,
code_length
,
&
current_frame
,
(
bci
>=
ex_min
&&
bci
<
ex_max
),
&
this_uninit
,
return_type
,
cp
,
CHECK_VERIFY
(
this
));
&
this_uninit
,
return_type
,
cp
,
&
stackmap_table
,
CHECK_VERIFY
(
this
));
no_control_flow
=
false
;
break
;
no_control_flow
=
false
;
break
;
case
Bytecodes
::
_new
:
case
Bytecodes
::
_new
:
{
{
...
@@ -2408,8 +2408,9 @@ bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
...
@@ -2408,8 +2408,9 @@ bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
void
ClassVerifier
::
verify_invoke_init
(
void
ClassVerifier
::
verify_invoke_init
(
RawBytecodeStream
*
bcs
,
u2
ref_class_index
,
VerificationType
ref_class_type
,
RawBytecodeStream
*
bcs
,
u2
ref_class_index
,
VerificationType
ref_class_type
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
in_try_block
,
constantPoolHandle
cp
,
TRAPS
)
{
bool
*
this_uninit
,
constantPoolHandle
cp
,
StackMapTable
*
stackmap_table
,
TRAPS
)
{
u2
bci
=
bcs
->
bci
();
u2
bci
=
bcs
->
bci
();
VerificationType
type
=
current_frame
->
pop_stack
(
VerificationType
type
=
current_frame
->
pop_stack
(
VerificationType
::
reference_check
(),
CHECK_VERIFY
(
this
));
VerificationType
::
reference_check
(),
CHECK_VERIFY
(
this
));
...
@@ -2425,28 +2426,36 @@ void ClassVerifier::verify_invoke_init(
...
@@ -2425,28 +2426,36 @@ void ClassVerifier::verify_invoke_init(
return
;
return
;
}
}
// Check if this call is done from inside of a TRY block. If so, make
// If this invokespecial call is done from inside of a TRY block then make
// sure that all catch clause paths end in a throw. Otherwise, this
// sure that all catch clause paths end in a throw. Otherwise, this can
// can result in returning an incomplete object.
// result in returning an incomplete object.
ExceptionTable
exhandlers
(
_method
());
if
(
in_try_block
)
{
int
exlength
=
exhandlers
.
length
();
ExceptionTable
exhandlers
(
_method
());
for
(
int
i
=
0
;
i
<
exlength
;
i
++
)
{
int
exlength
=
exhandlers
.
length
();
u2
start_pc
=
exhandlers
.
start_pc
(
i
);
for
(
int
i
=
0
;
i
<
exlength
;
i
++
)
{
u2
end_pc
=
exhandlers
.
end_pc
(
i
);
u2
start_pc
=
exhandlers
.
start_pc
(
i
);
u2
end_pc
=
exhandlers
.
end_pc
(
i
);
if
(
bci
>=
start_pc
&&
bci
<
end_pc
)
{
if
(
!
ends_in_athrow
(
exhandlers
.
handler_pc
(
i
)))
{
if
(
bci
>=
start_pc
&&
bci
<
end_pc
)
{
verify_error
(
ErrorContext
::
bad_code
(
bci
),
if
(
!
ends_in_athrow
(
exhandlers
.
handler_pc
(
i
)))
{
"Bad <init> method call from after the start of a try block"
);
verify_error
(
ErrorContext
::
bad_code
(
bci
),
return
;
"Bad <init> method call from after the start of a try block"
);
}
else
if
(
VerboseVerification
)
{
return
;
ResourceMark
rm
;
}
else
if
(
VerboseVerification
)
{
tty
->
print_cr
(
ResourceMark
rm
;
"Survived call to ends_in_athrow(): %s"
,
tty
->
print_cr
(
current_class
()
->
name
()
->
as_C_string
());
"Survived call to ends_in_athrow(): %s"
,
current_class
()
->
name
()
->
as_C_string
());
}
}
}
}
}
}
// Check the exception handler target stackmaps with the locals from the
// incoming stackmap (before initialize_object() changes them to outgoing
// state).
verify_exception_handler_targets
(
bci
,
true
,
current_frame
,
stackmap_table
,
CHECK_VERIFY
(
this
));
}
// in_try_block
current_frame
->
initialize_object
(
type
,
current_type
());
current_frame
->
initialize_object
(
type
,
current_type
());
*
this_uninit
=
true
;
*
this_uninit
=
true
;
...
@@ -2500,6 +2509,13 @@ void ClassVerifier::verify_invoke_init(
...
@@ -2500,6 +2509,13 @@ void ClassVerifier::verify_invoke_init(
}
}
}
}
}
}
// Check the exception handler target stackmaps with the locals from the
// incoming stackmap (before initialize_object() changes them to outgoing
// state).
if
(
in_try_block
)
{
verify_exception_handler_targets
(
bci
,
*
this_uninit
,
current_frame
,
stackmap_table
,
CHECK_VERIFY
(
this
));
}
current_frame
->
initialize_object
(
type
,
new_class_type
);
current_frame
->
initialize_object
(
type
,
new_class_type
);
}
else
{
}
else
{
verify_error
(
ErrorContext
::
bad_type
(
bci
,
current_frame
->
stack_top_ctx
()),
verify_error
(
ErrorContext
::
bad_type
(
bci
,
current_frame
->
stack_top_ctx
()),
...
@@ -2528,8 +2544,8 @@ bool ClassVerifier::is_same_or_direct_interface(
...
@@ -2528,8 +2544,8 @@ bool ClassVerifier::is_same_or_direct_interface(
void
ClassVerifier
::
verify_invoke_instructions
(
void
ClassVerifier
::
verify_invoke_instructions
(
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
bool
*
this_uninit
,
VerificationType
return_type
,
bool
in_try_block
,
bool
*
this_uninit
,
VerificationType
return_type
,
constantPoolHandle
cp
,
TRAPS
)
{
constantPoolHandle
cp
,
StackMapTable
*
stackmap_table
,
TRAPS
)
{
// Make sure the constant pool item is the right type
// Make sure the constant pool item is the right type
u2
index
=
bcs
->
get_index_u2
();
u2
index
=
bcs
->
get_index_u2
();
Bytecodes
::
Code
opcode
=
bcs
->
raw_code
();
Bytecodes
::
Code
opcode
=
bcs
->
raw_code
();
...
@@ -2699,7 +2715,8 @@ void ClassVerifier::verify_invoke_instructions(
...
@@ -2699,7 +2715,8 @@ void ClassVerifier::verify_invoke_instructions(
opcode
!=
Bytecodes
::
_invokedynamic
)
{
opcode
!=
Bytecodes
::
_invokedynamic
)
{
if
(
method_name
==
vmSymbols
::
object_initializer_name
())
{
// <init> method
if
(
method_name
==
vmSymbols
::
object_initializer_name
())
{
// <init> method
verify_invoke_init
(
bcs
,
index
,
ref_class_type
,
current_frame
,
verify_invoke_init
(
bcs
,
index
,
ref_class_type
,
current_frame
,
code_length
,
this_uninit
,
cp
,
CHECK_VERIFY
(
this
));
code_length
,
in_try_block
,
this_uninit
,
cp
,
stackmap_table
,
CHECK_VERIFY
(
this
));
}
else
{
// other methods
}
else
{
// other methods
// Ensures that target class is assignable to method class.
// Ensures that target class is assignable to method class.
if
(
opcode
==
Bytecodes
::
_invokespecial
)
{
if
(
opcode
==
Bytecodes
::
_invokespecial
)
{
...
...
src/share/vm/classfile/verifier.hpp
浏览文件 @
8f0618ad
...
@@ -301,8 +301,9 @@ class ClassVerifier : public StackObj {
...
@@ -301,8 +301,9 @@ class ClassVerifier : public StackObj {
void
verify_invoke_init
(
void
verify_invoke_init
(
RawBytecodeStream
*
bcs
,
u2
ref_index
,
VerificationType
ref_class_type
,
RawBytecodeStream
*
bcs
,
u2
ref_index
,
VerificationType
ref_class_type
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
*
this_uninit
,
StackMapFrame
*
current_frame
,
u4
code_length
,
bool
in_try_block
,
constantPoolHandle
cp
,
TRAPS
);
bool
*
this_uninit
,
constantPoolHandle
cp
,
StackMapTable
*
stackmap_table
,
TRAPS
);
// Used by ends_in_athrow() to push all handlers that contain bci onto
// Used by ends_in_athrow() to push all handlers that contain bci onto
// the handler_stack, if the handler is not already on the stack.
// the handler_stack, if the handler is not already on the stack.
...
@@ -316,8 +317,8 @@ class ClassVerifier : public StackObj {
...
@@ -316,8 +317,8 @@ class ClassVerifier : public StackObj {
void
verify_invoke_instructions
(
void
verify_invoke_instructions
(
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
RawBytecodeStream
*
bcs
,
u4
code_length
,
StackMapFrame
*
current_frame
,
bool
*
this_uninit
,
VerificationType
return_type
,
bool
in_try_block
,
bool
*
this_uninit
,
VerificationType
return_type
,
constantPoolHandle
cp
,
TRAPS
);
constantPoolHandle
cp
,
StackMapTable
*
stackmap_table
,
TRAPS
);
VerificationType
get_newarray_type
(
u2
index
,
u2
bci
,
TRAPS
);
VerificationType
get_newarray_type
(
u2
index
,
u2
bci
,
TRAPS
);
void
verify_anewarray
(
u2
bci
,
u2
index
,
constantPoolHandle
cp
,
void
verify_anewarray
(
u2
bci
,
u2
index
,
constantPoolHandle
cp
,
...
...
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
8f0618ad
...
@@ -79,6 +79,7 @@
...
@@ -79,6 +79,7 @@
template(java_lang_ref_WeakReference, "java/lang/ref/WeakReference") \
template(java_lang_ref_WeakReference, "java/lang/ref/WeakReference") \
template(java_lang_ref_FinalReference, "java/lang/ref/FinalReference") \
template(java_lang_ref_FinalReference, "java/lang/ref/FinalReference") \
template(java_lang_ref_PhantomReference, "java/lang/ref/PhantomReference") \
template(java_lang_ref_PhantomReference, "java/lang/ref/PhantomReference") \
template(sun_misc_Cleaner, "sun/misc/Cleaner") \
template(java_lang_ref_Finalizer, "java/lang/ref/Finalizer") \
template(java_lang_ref_Finalizer, "java/lang/ref/Finalizer") \
template(java_lang_reflect_AccessibleObject, "java/lang/reflect/AccessibleObject") \
template(java_lang_reflect_AccessibleObject, "java/lang/reflect/AccessibleObject") \
template(java_lang_reflect_Method, "java/lang/reflect/Method") \
template(java_lang_reflect_Method, "java/lang/reflect/Method") \
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
浏览文件 @
8f0618ad
...
@@ -738,7 +738,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
...
@@ -738,7 +738,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
// Support for parallelizing survivor space rescan
// Support for parallelizing survivor space rescan
if
((
CMSParallelRemarkEnabled
&&
CMSParallelSurvivorRemarkEnabled
)
||
CMSParallelInitialMarkEnabled
)
{
if
((
CMSParallelRemarkEnabled
&&
CMSParallelSurvivorRemarkEnabled
)
||
CMSParallelInitialMarkEnabled
)
{
const
size_t
max_plab_samples
=
const
size_t
max_plab_samples
=
((
DefNewGeneration
*
)
_young_gen
)
->
max_survivor_size
()
/
MinTLABSize
;
((
DefNewGeneration
*
)
_young_gen
)
->
max_survivor_size
()
/
plab_sample_minimum_size
()
;
_survivor_plab_array
=
NEW_C_HEAP_ARRAY
(
ChunkArray
,
ParallelGCThreads
,
mtGC
);
_survivor_plab_array
=
NEW_C_HEAP_ARRAY
(
ChunkArray
,
ParallelGCThreads
,
mtGC
);
_survivor_chunk_array
=
NEW_C_HEAP_ARRAY
(
HeapWord
*
,
2
*
max_plab_samples
,
mtGC
);
_survivor_chunk_array
=
NEW_C_HEAP_ARRAY
(
HeapWord
*
,
2
*
max_plab_samples
,
mtGC
);
...
@@ -796,6 +796,12 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
...
@@ -796,6 +796,12 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_inter_sweep_timer
.
start
();
// start of time
_inter_sweep_timer
.
start
();
// start of time
}
}
size_t
CMSCollector
::
plab_sample_minimum_size
()
{
// The default value of MinTLABSize is 2k, but there is
// no way to get the default value if the flag has been overridden.
return
MAX2
(
ThreadLocalAllocBuffer
::
min_size
()
*
HeapWordSize
,
2
*
K
);
}
const
char
*
ConcurrentMarkSweepGeneration
::
name
()
const
{
const
char
*
ConcurrentMarkSweepGeneration
::
name
()
const
{
return
"concurrent mark-sweep generation"
;
return
"concurrent mark-sweep generation"
;
}
}
...
...
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
浏览文件 @
8f0618ad
...
@@ -764,6 +764,10 @@ class CMSCollector: public CHeapObj<mtGC> {
...
@@ -764,6 +764,10 @@ class CMSCollector: public CHeapObj<mtGC> {
size_t
*
_cursor
;
size_t
*
_cursor
;
ChunkArray
*
_survivor_plab_array
;
ChunkArray
*
_survivor_plab_array
;
// A bounded minimum size of PLABs, should not return too small values since
// this will affect the size of the data structures used for parallel young gen rescan
size_t
plab_sample_minimum_size
();
// Support for marking stack overflow handling
// Support for marking stack overflow handling
bool
take_from_overflow_list
(
size_t
num
,
CMSMarkStack
*
to_stack
);
bool
take_from_overflow_list
(
size_t
num
,
CMSMarkStack
*
to_stack
);
bool
par_take_from_overflow_list
(
size_t
num
,
bool
par_take_from_overflow_list
(
size_t
num
,
...
...
src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
浏览文件 @
8f0618ad
/*
/*
* Copyright (c) 2001, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -47,6 +47,13 @@ public:
...
@@ -47,6 +47,13 @@ public:
// active field set to true.
// active field set to true.
PtrQueue
(
qset_
,
perm
,
true
/* active */
)
{
}
PtrQueue
(
qset_
,
perm
,
true
/* active */
)
{
}
// Flush before destroying; queue may be used to capture pending work while
// doing something else, with auto-flush on completion.
~
DirtyCardQueue
()
{
if
(
!
is_permanent
())
flush
();
}
// Process queue entries and release resources.
void
flush
()
{
flush_impl
();
}
// Apply the closure to all elements, and reset the index to make the
// Apply the closure to all elements, and reset the index to make the
// buffer empty. If a closure application returns "false", return
// buffer empty. If a closure application returns "false", return
// "false" immediately, halting the iteration. If "consume" is true,
// "false" immediately, halting the iteration. If "consume" is true,
...
...
src/share/vm/gc_implementation/g1/ptrQueue.cpp
浏览文件 @
8f0618ad
/*
/*
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -31,11 +31,15 @@
...
@@ -31,11 +31,15 @@
#include "runtime/thread.inline.hpp"
#include "runtime/thread.inline.hpp"
PtrQueue
::
PtrQueue
(
PtrQueueSet
*
qset
,
bool
perm
,
bool
active
)
:
PtrQueue
::
PtrQueue
(
PtrQueueSet
*
qset
,
bool
perm
,
bool
active
)
:
_qset
(
qset
),
_buf
(
NULL
),
_index
(
0
),
_active
(
active
),
_qset
(
qset
),
_buf
(
NULL
),
_index
(
0
),
_
sz
(
0
),
_
active
(
active
),
_perm
(
perm
),
_lock
(
NULL
)
_perm
(
perm
),
_lock
(
NULL
)
{}
{}
void
PtrQueue
::
flush
()
{
PtrQueue
::~
PtrQueue
()
{
assert
(
_perm
||
(
_buf
==
NULL
),
"queue must be flushed before delete"
);
}
void
PtrQueue
::
flush_impl
()
{
if
(
!
_perm
&&
_buf
!=
NULL
)
{
if
(
!
_perm
&&
_buf
!=
NULL
)
{
if
(
_index
==
_sz
)
{
if
(
_index
==
_sz
)
{
// No work to do.
// No work to do.
...
...
src/share/vm/gc_implementation/g1/ptrQueue.hpp
浏览文件 @
8f0618ad
/*
/*
* Copyright (c) 2001, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -65,15 +65,18 @@ protected:
...
@@ -65,15 +65,18 @@ protected:
Mutex
*
_lock
;
Mutex
*
_lock
;
PtrQueueSet
*
qset
()
{
return
_qset
;
}
PtrQueueSet
*
qset
()
{
return
_qset
;
}
bool
is_permanent
()
const
{
return
_perm
;
}
// Process queue entries and release resources, if not permanent.
void
flush_impl
();
public:
public:
// Initialize this queue to contain a null buffer, and be part of the
// Initialize this queue to contain a null buffer, and be part of the
// given PtrQueueSet.
// given PtrQueueSet.
PtrQueue
(
PtrQueueSet
*
qset
,
bool
perm
=
false
,
bool
active
=
false
);
PtrQueue
(
PtrQueueSet
*
qset
,
bool
perm
=
false
,
bool
active
=
false
);
// Release any contained resources.
virtual
void
flush
();
// Requires queue flushed or permanent.
// Calls flush() when destroyed.
~
PtrQueue
();
~
PtrQueue
()
{
flush
();
}
// Associate a lock with a ptr queue.
// Associate a lock with a ptr queue.
void
set_lock
(
Mutex
*
lock
)
{
_lock
=
lock
;
}
void
set_lock
(
Mutex
*
lock
)
{
_lock
=
lock
;
}
...
...
src/share/vm/gc_implementation/g1/satbQueue.cpp
浏览文件 @
8f0618ad
...
@@ -39,7 +39,7 @@ void ObjPtrQueue::flush() {
...
@@ -39,7 +39,7 @@ void ObjPtrQueue::flush() {
// first before we flush it, otherwise we might end up with an
// first before we flush it, otherwise we might end up with an
// enqueued buffer with refs into the CSet which breaks our invariants.
// enqueued buffer with refs into the CSet which breaks our invariants.
filter
();
filter
();
PtrQueue
::
flush
();
flush_impl
();
}
}
// This method removes entries from an SATB buffer that will not be
// This method removes entries from an SATB buffer that will not be
...
...
src/share/vm/gc_implementation/g1/satbQueue.hpp
浏览文件 @
8f0618ad
/*
/*
* Copyright (c) 2001, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 201
4
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -60,9 +60,8 @@ public:
...
@@ -60,9 +60,8 @@ public:
// field to true. This is done in JavaThread::initialize_queues().
// field to true. This is done in JavaThread::initialize_queues().
PtrQueue
(
qset
,
perm
,
false
/* active */
)
{
}
PtrQueue
(
qset
,
perm
,
false
/* active */
)
{
}
// Overrides PtrQueue::flush() so that it can filter the buffer
// Process queue entries and free resources.
// before it is flushed.
void
flush
();
virtual
void
flush
();
// Overrides PtrQueue::should_enqueue_buffer(). See the method's
// Overrides PtrQueue::should_enqueue_buffer(). See the method's
// definition for more information.
// definition for more information.
...
...
src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
浏览文件 @
8f0618ad
...
@@ -63,7 +63,8 @@ public:
...
@@ -63,7 +63,8 @@ public:
virtual
~
ParGCAllocBuffer
()
{}
virtual
~
ParGCAllocBuffer
()
{}
static
const
size_t
min_size
()
{
static
const
size_t
min_size
()
{
return
ThreadLocalAllocBuffer
::
min_size
();
// Make sure that we return something that is larger than AlignmentReserve
return
align_object_size
(
MAX2
(
MinTLABSize
/
HeapWordSize
,
(
uintx
)
oopDesc
::
header_size
()))
+
AlignmentReserve
;
}
}
static
const
size_t
max_size
()
{
static
const
size_t
max_size
()
{
...
...
src/share/vm/memory/referenceProcessor.cpp
浏览文件 @
8f0618ad
...
@@ -118,6 +118,7 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
...
@@ -118,6 +118,7 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
_discoveredWeakRefs
=
&
_discoveredSoftRefs
[
_max_num_q
];
_discoveredWeakRefs
=
&
_discoveredSoftRefs
[
_max_num_q
];
_discoveredFinalRefs
=
&
_discoveredWeakRefs
[
_max_num_q
];
_discoveredFinalRefs
=
&
_discoveredWeakRefs
[
_max_num_q
];
_discoveredPhantomRefs
=
&
_discoveredFinalRefs
[
_max_num_q
];
_discoveredPhantomRefs
=
&
_discoveredFinalRefs
[
_max_num_q
];
_discoveredCleanerRefs
=
&
_discoveredPhantomRefs
[
_max_num_q
];
// Initialize all entries to NULL
// Initialize all entries to NULL
for
(
uint
i
=
0
;
i
<
_max_num_q
*
number_of_subclasses_of_ref
();
i
++
)
{
for
(
uint
i
=
0
;
i
<
_max_num_q
*
number_of_subclasses_of_ref
();
i
++
)
{
...
@@ -246,6 +247,13 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
...
@@ -246,6 +247,13 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
phantom_count
=
phantom_count
=
process_discovered_reflist
(
_discoveredPhantomRefs
,
NULL
,
false
,
process_discovered_reflist
(
_discoveredPhantomRefs
,
NULL
,
false
,
is_alive
,
keep_alive
,
complete_gc
,
task_executor
);
is_alive
,
keep_alive
,
complete_gc
,
task_executor
);
// Process cleaners, but include them in phantom statistics. We expect
// Cleaner references to be temporary, and don't want to deal with
// possible incompatibilities arising from making it more visible.
phantom_count
+=
process_discovered_reflist
(
_discoveredCleanerRefs
,
NULL
,
false
,
is_alive
,
keep_alive
,
complete_gc
,
task_executor
);
}
}
// Weak global JNI references. It would make more sense (semantically) to
// Weak global JNI references. It would make more sense (semantically) to
...
@@ -883,6 +891,7 @@ void ReferenceProcessor::balance_all_queues() {
...
@@ -883,6 +891,7 @@ void ReferenceProcessor::balance_all_queues() {
balance_queues
(
_discoveredWeakRefs
);
balance_queues
(
_discoveredWeakRefs
);
balance_queues
(
_discoveredFinalRefs
);
balance_queues
(
_discoveredFinalRefs
);
balance_queues
(
_discoveredPhantomRefs
);
balance_queues
(
_discoveredPhantomRefs
);
balance_queues
(
_discoveredCleanerRefs
);
}
}
size_t
size_t
...
@@ -1042,6 +1051,9 @@ inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt)
...
@@ -1042,6 +1051,9 @@ inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt)
case
REF_PHANTOM
:
case
REF_PHANTOM
:
list
=
&
_discoveredPhantomRefs
[
id
];
list
=
&
_discoveredPhantomRefs
[
id
];
break
;
break
;
case
REF_CLEANER
:
list
=
&
_discoveredCleanerRefs
[
id
];
break
;
case
REF_NONE
:
case
REF_NONE
:
// we should not reach here if we are an InstanceRefKlass
// we should not reach here if we are an InstanceRefKlass
default:
default:
...
@@ -1307,6 +1319,17 @@ void ReferenceProcessor::preclean_discovered_references(
...
@@ -1307,6 +1319,17 @@ void ReferenceProcessor::preclean_discovered_references(
preclean_discovered_reflist
(
_discoveredPhantomRefs
[
i
],
is_alive
,
preclean_discovered_reflist
(
_discoveredPhantomRefs
[
i
],
is_alive
,
keep_alive
,
complete_gc
,
yield
);
keep_alive
,
complete_gc
,
yield
);
}
}
// Cleaner references. Included in timing for phantom references. We
// expect Cleaner references to be temporary, and don't want to deal with
// possible incompatibilities arising from making it more visible.
for
(
uint
i
=
0
;
i
<
_max_num_q
;
i
++
)
{
if
(
yield
->
should_return
())
{
return
;
}
preclean_discovered_reflist
(
_discoveredCleanerRefs
[
i
],
is_alive
,
keep_alive
,
complete_gc
,
yield
);
}
}
}
}
}
...
@@ -1375,6 +1398,7 @@ const char* ReferenceProcessor::list_name(uint i) {
...
@@ -1375,6 +1398,7 @@ const char* ReferenceProcessor::list_name(uint i) {
case
1
:
return
"WeakRef"
;
case
1
:
return
"WeakRef"
;
case
2
:
return
"FinalRef"
;
case
2
:
return
"FinalRef"
;
case
3
:
return
"PhantomRef"
;
case
3
:
return
"PhantomRef"
;
case
4
:
return
"CleanerRef"
;
}
}
ShouldNotReachHere
();
ShouldNotReachHere
();
return
NULL
;
return
NULL
;
...
...
src/share/vm/memory/referenceProcessor.hpp
浏览文件 @
8f0618ad
...
@@ -264,9 +264,10 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
...
@@ -264,9 +264,10 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
DiscoveredList
*
_discoveredWeakRefs
;
DiscoveredList
*
_discoveredWeakRefs
;
DiscoveredList
*
_discoveredFinalRefs
;
DiscoveredList
*
_discoveredFinalRefs
;
DiscoveredList
*
_discoveredPhantomRefs
;
DiscoveredList
*
_discoveredPhantomRefs
;
DiscoveredList
*
_discoveredCleanerRefs
;
public:
public:
static
int
number_of_subclasses_of_ref
()
{
return
(
REF_
PHANTOM
-
REF_OTHER
);
}
static
int
number_of_subclasses_of_ref
()
{
return
(
REF_
CLEANER
-
REF_OTHER
);
}
uint
num_q
()
{
return
_num_q
;
}
uint
num_q
()
{
return
_num_q
;
}
uint
max_num_q
()
{
return
_max_num_q
;
}
uint
max_num_q
()
{
return
_max_num_q
;
}
...
...
src/share/vm/memory/referenceType.hpp
浏览文件 @
8f0618ad
...
@@ -35,7 +35,8 @@ enum ReferenceType {
...
@@ -35,7 +35,8 @@ enum ReferenceType {
REF_SOFT
,
// Subclass of java/lang/ref/SoftReference
REF_SOFT
,
// Subclass of java/lang/ref/SoftReference
REF_WEAK
,
// Subclass of java/lang/ref/WeakReference
REF_WEAK
,
// Subclass of java/lang/ref/WeakReference
REF_FINAL
,
// Subclass of java/lang/ref/FinalReference
REF_FINAL
,
// Subclass of java/lang/ref/FinalReference
REF_PHANTOM
// Subclass of java/lang/ref/PhantomReference
REF_PHANTOM
,
// Subclass of java/lang/ref/PhantomReference
REF_CLEANER
// Subclass of sun/misc/Cleaner
};
};
#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP
#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP
src/share/vm/memory/threadLocalAllocBuffer.cpp
浏览文件 @
8f0618ad
...
@@ -235,22 +235,19 @@ void ThreadLocalAllocBuffer::startup_initialization() {
...
@@ -235,22 +235,19 @@ void ThreadLocalAllocBuffer::startup_initialization() {
}
}
size_t
ThreadLocalAllocBuffer
::
initial_desired_size
()
{
size_t
ThreadLocalAllocBuffer
::
initial_desired_size
()
{
size_t
init_sz
;
size_t
init_sz
=
0
;
if
(
TLABSize
>
0
)
{
if
(
TLABSize
>
0
)
{
init_sz
=
MIN2
(
TLABSize
/
HeapWordSize
,
max_size
());
init_sz
=
TLABSize
/
HeapWordSize
;
}
else
if
(
global_stats
()
==
NULL
)
{
}
else
if
(
global_stats
()
!=
NULL
)
{
// Startup issue - main thread initialized before heap initialized.
init_sz
=
min_size
();
}
else
{
// Initial size is a function of the average number of allocating threads.
// Initial size is a function of the average number of allocating threads.
unsigned
nof_threads
=
global_stats
()
->
allocating_threads_avg
();
unsigned
nof_threads
=
global_stats
()
->
allocating_threads_avg
();
init_sz
=
(
Universe
::
heap
()
->
tlab_capacity
(
myThread
())
/
HeapWordSize
)
/
init_sz
=
(
Universe
::
heap
()
->
tlab_capacity
(
myThread
())
/
HeapWordSize
)
/
(
nof_threads
*
target_refills
());
(
nof_threads
*
target_refills
());
init_sz
=
align_object_size
(
init_sz
);
init_sz
=
align_object_size
(
init_sz
);
init_sz
=
MIN2
(
MAX2
(
init_sz
,
min_size
()),
max_size
());
}
}
init_sz
=
MIN2
(
MAX2
(
init_sz
,
min_size
()),
max_size
());
return
init_sz
;
return
init_sz
;
}
}
...
...
src/share/vm/memory/threadLocalAllocBuffer.hpp
浏览文件 @
8f0618ad
...
@@ -105,7 +105,7 @@ public:
...
@@ -105,7 +105,7 @@ public:
// do nothing. tlabs must be inited by initialize() calls
// do nothing. tlabs must be inited by initialize() calls
}
}
static
const
size_t
min_size
()
{
return
align_object_size
(
MinTLABSize
/
HeapWordSize
);
}
static
const
size_t
min_size
()
{
return
align_object_size
(
MinTLABSize
/
HeapWordSize
)
+
alignment_reserve
()
;
}
static
const
size_t
max_size
()
{
assert
(
_max_size
!=
0
,
"max_size not set up"
);
return
_max_size
;
}
static
const
size_t
max_size
()
{
assert
(
_max_size
!=
0
,
"max_size not set up"
);
return
_max_size
;
}
static
void
set_max_size
(
size_t
max_size
)
{
_max_size
=
max_size
;
}
static
void
set_max_size
(
size_t
max_size
)
{
_max_size
=
max_size
;
}
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
8f0618ad
...
@@ -671,6 +671,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > MetablockTreeDicti
...
@@ -671,6 +671,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > MetablockTreeDicti
static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(FinalReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(FinalReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Cleaner_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Finalizer_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Finalizer_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Thread_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Thread_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), Klass*) \
...
...
src/share/vm/utilities/defaultStream.hpp
浏览文件 @
8f0618ad
...
@@ -41,6 +41,8 @@ class defaultStream : public xmlTextStream {
...
@@ -41,6 +41,8 @@ class defaultStream : public xmlTextStream {
void
init
();
void
init
();
void
init_log
();
void
init_log
();
fileStream
*
open_file
(
const
char
*
log_name
);
void
start_log
();
void
finish_log
();
void
finish_log
();
void
finish_log_on_error
(
char
*
buf
,
int
buflen
);
void
finish_log_on_error
(
char
*
buf
,
int
buflen
);
public:
public:
...
...
src/share/vm/utilities/ostream.cpp
浏览文件 @
8f0618ad
...
@@ -370,7 +370,6 @@ extern Mutex* tty_lock;
...
@@ -370,7 +370,6 @@ extern Mutex* tty_lock;
#define EXTRACHARLEN 32
#define EXTRACHARLEN 32
#define CURRENTAPPX ".current"
#define CURRENTAPPX ".current"
#define FILENAMEBUFLEN 1024
// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
char
*
get_datetime_string
(
char
*
buf
,
size_t
len
)
{
char
*
get_datetime_string
(
char
*
buf
,
size_t
len
)
{
os
::
local_time_string
(
buf
,
len
);
os
::
local_time_string
(
buf
,
len
);
...
@@ -404,7 +403,6 @@ static const char* make_log_name_internal(const char* log_name, const char* forc
...
@@ -404,7 +403,6 @@ static const char* make_log_name_internal(const char* log_name, const char* forc
buffer_length
=
strlen
(
log_name
)
+
1
;
buffer_length
=
strlen
(
log_name
)
+
1
;
}
}
// const char* star = strchr(basename, '*');
const
char
*
pts
=
strstr
(
basename
,
"%p"
);
const
char
*
pts
=
strstr
(
basename
,
"%p"
);
int
pid_pos
=
(
pts
==
NULL
)
?
-
1
:
(
pts
-
nametail
);
int
pid_pos
=
(
pts
==
NULL
)
?
-
1
:
(
pts
-
nametail
);
...
@@ -419,6 +417,11 @@ static const char* make_log_name_internal(const char* log_name, const char* forc
...
@@ -419,6 +417,11 @@ static const char* make_log_name_internal(const char* log_name, const char* forc
buffer_length
+=
strlen
(
tms
);
buffer_length
+=
strlen
(
tms
);
}
}
// File name is too long.
if
(
buffer_length
>
JVM_MAXPATHLEN
)
{
return
NULL
;
}
// Create big enough buffer.
// Create big enough buffer.
char
*
buf
=
NEW_C_HEAP_ARRAY
(
char
,
buffer_length
,
mtInternal
);
char
*
buf
=
NEW_C_HEAP_ARRAY
(
char
,
buffer_length
,
mtInternal
);
...
@@ -492,46 +495,88 @@ static const char* make_log_name(const char* log_name, const char* force_directo
...
@@ -492,46 +495,88 @@ static const char* make_log_name(const char* log_name, const char* force_directo
void
test_loggc_filename
()
{
void
test_loggc_filename
()
{
int
pid
;
int
pid
;
char
tms
[
32
];
char
tms
[
32
];
char
i_result
[
FILENAMEBUF
LEN
];
char
i_result
[
JVM_MAXPATH
LEN
];
const
char
*
o_result
;
const
char
*
o_result
;
get_datetime_string
(
tms
,
sizeof
(
tms
));
get_datetime_string
(
tms
,
sizeof
(
tms
));
pid
=
os
::
current_process_id
();
pid
=
os
::
current_process_id
();
// test.log
// test.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"test.log"
,
tms
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"test.log"
,
tms
);
o_result
=
make_log_name_internal
(
"test.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"test.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// test-%t-%p.log
// test-%t-%p.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"test-%s-pid%u.log"
,
tms
,
pid
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"test-%s-pid%u.log"
,
tms
,
pid
);
o_result
=
make_log_name_internal
(
"test-%t-%p.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"test-%t-%p.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t-%%p.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t-%%p.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// test-%t%p.log
// test-%t%p.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"test-%spid%u.log"
,
tms
,
pid
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"test-%spid%u.log"
,
tms
,
pid
);
o_result
=
make_log_name_internal
(
"test-%t%p.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"test-%t%p.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t%%p.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
test-%%t%%p.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %p%t.log
// %p%t.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"pid%u%s.log"
,
pid
,
tms
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"pid%u%s.log"
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"%p%t.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"%p%t.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p%%t.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p%%t.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %p-test.log
// %p-test.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"pid%u-test.log"
,
pid
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"pid%u-test.log"
,
pid
);
o_result
=
make_log_name_internal
(
"%p-test.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"%p-test.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p-test.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%p-test.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
// %t.log
// %t.log
jio_snprintf
(
i_result
,
sizeof
(
char
)
*
FILENAMEBUF
LEN
,
"%s.log"
,
tms
);
jio_snprintf
(
i_result
,
JVM_MAXPATH
LEN
,
"%s.log"
,
tms
);
o_result
=
make_log_name_internal
(
"%t.log"
,
NULL
,
pid
,
tms
);
o_result
=
make_log_name_internal
(
"%t.log"
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%t.log
\"
, NULL)"
);
assert
(
strcmp
(
i_result
,
o_result
)
==
0
,
"failed on testing make_log_name(
\"
%%t.log
\"
, NULL)"
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
{
// longest filename
char
longest_name
[
JVM_MAXPATHLEN
];
memset
(
longest_name
,
'a'
,
sizeof
(
longest_name
));
longest_name
[
JVM_MAXPATHLEN
-
1
]
=
'\0'
;
o_result
=
make_log_name_internal
((
const
char
*
)
&
longest_name
,
NULL
,
pid
,
tms
);
assert
(
strcmp
(
longest_name
,
o_result
)
==
0
,
err_msg
(
"longest name does not match. expected '%s' but got '%s'"
,
longest_name
,
o_result
));
FREE_C_HEAP_ARRAY
(
char
,
o_result
,
mtInternal
);
}
{
// too long file name
char
too_long_name
[
JVM_MAXPATHLEN
+
100
];
int
too_long_length
=
sizeof
(
too_long_name
);
memset
(
too_long_name
,
'a'
,
too_long_length
);
too_long_name
[
too_long_length
-
1
]
=
'\0'
;
o_result
=
make_log_name_internal
((
const
char
*
)
&
too_long_name
,
NULL
,
pid
,
tms
);
assert
(
o_result
==
NULL
,
err_msg
(
"Too long file name should return NULL, but got '%s'"
,
o_result
));
}
{
// too long with timestamp
char
longest_name
[
JVM_MAXPATHLEN
];
memset
(
longest_name
,
'a'
,
JVM_MAXPATHLEN
);
longest_name
[
JVM_MAXPATHLEN
-
3
]
=
'%'
;
longest_name
[
JVM_MAXPATHLEN
-
2
]
=
't'
;
longest_name
[
JVM_MAXPATHLEN
-
1
]
=
'\0'
;
o_result
=
make_log_name_internal
((
const
char
*
)
&
longest_name
,
NULL
,
pid
,
tms
);
assert
(
o_result
==
NULL
,
err_msg
(
"Too long file name after timestamp expansion should return NULL, but got '%s'"
,
o_result
));
}
{
// too long with pid
char
longest_name
[
JVM_MAXPATHLEN
];
memset
(
longest_name
,
'a'
,
JVM_MAXPATHLEN
);
longest_name
[
JVM_MAXPATHLEN
-
3
]
=
'%'
;
longest_name
[
JVM_MAXPATHLEN
-
2
]
=
'p'
;
longest_name
[
JVM_MAXPATHLEN
-
1
]
=
'\0'
;
o_result
=
make_log_name_internal
((
const
char
*
)
&
longest_name
,
NULL
,
pid
,
tms
);
assert
(
o_result
==
NULL
,
err_msg
(
"Too long file name after pid expansion should return NULL, but got '%s'"
,
o_result
));
}
}
}
#endif // PRODUCT
#endif // PRODUCT
...
@@ -640,9 +685,16 @@ gcLogFileStream::gcLogFileStream(const char* file_name) {
...
@@ -640,9 +685,16 @@ gcLogFileStream::gcLogFileStream(const char* file_name) {
_bytes_written
=
0L
;
_bytes_written
=
0L
;
_file_name
=
make_log_name
(
file_name
,
NULL
);
_file_name
=
make_log_name
(
file_name
,
NULL
);
if
(
_file_name
==
NULL
)
{
warning
(
"Cannot open file %s: file name is too long.
\n
"
,
file_name
);
_need_close
=
false
;
UseGCLogFileRotation
=
false
;
return
;
}
// gc log file rotation
// gc log file rotation
if
(
UseGCLogFileRotation
&&
NumberOfGCLogFiles
>
1
)
{
if
(
UseGCLogFileRotation
&&
NumberOfGCLogFiles
>
1
)
{
char
tempbuf
[
FILENAMEBUF
LEN
];
char
tempbuf
[
JVM_MAXPATH
LEN
];
jio_snprintf
(
tempbuf
,
sizeof
(
tempbuf
),
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
tempbuf
,
sizeof
(
tempbuf
),
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
_file
=
fopen
(
tempbuf
,
"w"
);
_file
=
fopen
(
tempbuf
,
"w"
);
}
else
{
}
else
{
...
@@ -674,10 +726,10 @@ void gcLogFileStream::write(const char* s, size_t len) {
...
@@ -674,10 +726,10 @@ void gcLogFileStream::write(const char* s, size_t len) {
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
// must be synchronized.
void
gcLogFileStream
::
rotate_log
(
bool
force
,
outputStream
*
out
)
{
void
gcLogFileStream
::
rotate_log
(
bool
force
,
outputStream
*
out
)
{
char
time_msg
[
FILENAME
BUFLEN
];
char
time_msg
[
O_
BUFLEN
];
char
time_str
[
EXTRACHARLEN
];
char
time_str
[
EXTRACHARLEN
];
char
current_file_name
[
FILENAMEBUF
LEN
];
char
current_file_name
[
JVM_MAXPATH
LEN
];
char
renamed_file_name
[
FILENAMEBUF
LEN
];
char
renamed_file_name
[
JVM_MAXPATH
LEN
];
if
(
!
should_rotate
(
force
))
{
if
(
!
should_rotate
(
force
))
{
return
;
return
;
...
@@ -716,12 +768,15 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) {
...
@@ -716,12 +768,15 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) {
// have a form of extended_filename.<i>.current where i is the current rotation
// have a form of extended_filename.<i>.current where i is the current rotation
// file number. After it reaches max file size, the file will be saved and renamed
// file number. After it reaches max file size, the file will be saved and renamed
// with .current removed from its tail.
// with .current removed from its tail.
size_t
filename_len
=
strlen
(
_file_name
);
if
(
_file
!=
NULL
)
{
if
(
_file
!=
NULL
)
{
jio_snprintf
(
renamed_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
,
jio_snprintf
(
renamed_file_name
,
JVM_MAXPATHLEN
,
"%s.%d"
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHARLEN
,
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
_file_name
,
_cur_file_num
);
int
result
=
jio_snprintf
(
current_file_name
,
JVM_MAXPATHLEN
,
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
if
(
result
>=
JVM_MAXPATHLEN
)
{
warning
(
"Cannot create new log file name: %s: file name is too long.
\n
"
,
current_file_name
);
return
;
}
const
char
*
msg
=
force
?
"GC log rotation request has been received."
const
char
*
msg
=
force
?
"GC log rotation request has been received."
:
"GC log file has reached the maximum size."
;
:
"GC log file has reached the maximum size."
;
...
@@ -760,19 +815,23 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) {
...
@@ -760,19 +815,23 @@ void gcLogFileStream::rotate_log(bool force, outputStream* out) {
_cur_file_num
++
;
_cur_file_num
++
;
if
(
_cur_file_num
>
NumberOfGCLogFiles
-
1
)
_cur_file_num
=
0
;
if
(
_cur_file_num
>
NumberOfGCLogFiles
-
1
)
_cur_file_num
=
0
;
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHAR
LEN
,
"%s.%d"
CURRENTAPPX
,
int
result
=
jio_snprintf
(
current_file_name
,
JVM_MAXPATH
LEN
,
"%s.%d"
CURRENTAPPX
,
_file_name
,
_cur_file_num
);
_file_name
,
_cur_file_num
);
if
(
result
>=
JVM_MAXPATHLEN
)
{
warning
(
"Cannot create new log file name: %s: file name is too long.
\n
"
,
current_file_name
);
return
;
}
_file
=
fopen
(
current_file_name
,
"w"
);
_file
=
fopen
(
current_file_name
,
"w"
);
if
(
_file
!=
NULL
)
{
if
(
_file
!=
NULL
)
{
_bytes_written
=
0L
;
_bytes_written
=
0L
;
_need_close
=
true
;
_need_close
=
true
;
// reuse current_file_name for time_msg
// reuse current_file_name for time_msg
jio_snprintf
(
current_file_name
,
filename_len
+
EXTRACHAR
LEN
,
jio_snprintf
(
current_file_name
,
JVM_MAXPATH
LEN
,
"%s.%d"
,
_file_name
,
_cur_file_num
);
"%s.%d"
,
_file_name
,
_cur_file_num
);
jio_snprintf
(
time_msg
,
sizeof
(
time_msg
),
"%s GC log file created %s
\n
"
,
jio_snprintf
(
time_msg
,
sizeof
(
time_msg
),
"%s GC log file created %s
\n
"
,
os
::
local_time_string
((
char
*
)
time_str
,
sizeof
(
time_str
)),
os
::
local_time_string
((
char
*
)
time_str
,
sizeof
(
time_str
)),
current_file_name
);
current_file_name
);
write
(
time_msg
,
strlen
(
time_msg
));
write
(
time_msg
,
strlen
(
time_msg
));
if
(
out
!=
NULL
)
{
if
(
out
!=
NULL
)
{
...
@@ -820,32 +879,64 @@ bool defaultStream::has_log_file() {
...
@@ -820,32 +879,64 @@ bool defaultStream::has_log_file() {
return
_log_file
!=
NULL
;
return
_log_file
!=
NULL
;
}
}
void
defaultStream
::
init_log
()
{
fileStream
*
defaultStream
::
open_file
(
const
char
*
log_name
)
{
// %%% Need a MutexLocker?
const
char
*
log_name
=
LogFile
!=
NULL
?
LogFile
:
"hotspot_%p.log"
;
const
char
*
try_name
=
make_log_name
(
log_name
,
NULL
);
const
char
*
try_name
=
make_log_name
(
log_name
,
NULL
);
fileStream
*
file
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
fileStream
(
try_name
);
if
(
try_name
==
NULL
)
{
if
(
!
file
->
is_open
())
{
warning
(
"Cannot open file %s: file name is too long.
\n
"
,
log_name
);
// Try again to open the file.
return
NULL
;
char
warnbuf
[
O_BUFLEN
*
2
];
jio_snprintf
(
warnbuf
,
sizeof
(
warnbuf
),
"Warning: Cannot open log file: %s
\n
"
,
try_name
);
// Note: This feature is for maintainer use only. No need for L10N.
jio_print
(
warnbuf
);
FREE_C_HEAP_ARRAY
(
char
,
try_name
,
mtInternal
);
try_name
=
make_log_name
(
log_name
,
os
::
get_temp_directory
());
jio_snprintf
(
warnbuf
,
sizeof
(
warnbuf
),
"Warning: Forcing option -XX:LogFile=%s
\n
"
,
try_name
);
jio_print
(
warnbuf
);
delete
file
;
file
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
fileStream
(
try_name
);
}
}
fileStream
*
file
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
fileStream
(
try_name
);
FREE_C_HEAP_ARRAY
(
char
,
try_name
,
mtInternal
);
FREE_C_HEAP_ARRAY
(
char
,
try_name
,
mtInternal
);
if
(
file
->
is_open
())
{
return
file
;
}
// Try again to open the file in the temp directory.
delete
file
;
char
warnbuf
[
O_BUFLEN
*
2
];
jio_snprintf
(
warnbuf
,
sizeof
(
warnbuf
),
"Warning: Cannot open log file: %s
\n
"
,
log_name
);
// Note: This feature is for maintainer use only. No need for L10N.
jio_print
(
warnbuf
);
try_name
=
make_log_name
(
log_name
,
os
::
get_temp_directory
());
if
(
try_name
==
NULL
)
{
warning
(
"Cannot open file %s: file name is too long for directory %s.
\n
"
,
log_name
,
os
::
get_temp_directory
());
return
NULL
;
}
jio_snprintf
(
warnbuf
,
sizeof
(
warnbuf
),
"Warning: Forcing option -XX:LogFile=%s
\n
"
,
try_name
);
jio_print
(
warnbuf
);
file
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
fileStream
(
try_name
);
FREE_C_HEAP_ARRAY
(
char
,
try_name
,
mtInternal
);
if
(
file
->
is_open
())
{
if
(
file
->
is_open
())
{
return
file
;
}
delete
file
;
return
NULL
;
}
void
defaultStream
::
init_log
()
{
// %%% Need a MutexLocker?
const
char
*
log_name
=
LogFile
!=
NULL
?
LogFile
:
"hotspot_%p.log"
;
fileStream
*
file
=
open_file
(
log_name
);
if
(
file
!=
NULL
)
{
_log_file
=
file
;
_log_file
=
file
;
xmlStream
*
xs
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
xmlStream
(
file
);
_outer_xmlStream
=
new
(
ResourceObj
::
C_HEAP
,
mtInternal
)
xmlStream
(
file
);
_outer_xmlStream
=
xs
;
start_log
();
}
else
{
// and leave xtty as NULL
LogVMOutput
=
false
;
DisplayVMOutput
=
true
;
LogCompilation
=
false
;
}
}
void
defaultStream
::
start_log
()
{
xmlStream
*
xs
=
_outer_xmlStream
;
if
(
this
==
tty
)
xtty
=
xs
;
if
(
this
==
tty
)
xtty
=
xs
;
// Write XML header.
// Write XML header.
xs
->
print_cr
(
"<?xml version='1.0' encoding='UTF-8'?>"
);
xs
->
print_cr
(
"<?xml version='1.0' encoding='UTF-8'?>"
);
...
@@ -900,13 +991,6 @@ void defaultStream::init_log() {
...
@@ -900,13 +991,6 @@ void defaultStream::init_log() {
xs
->
head
(
"tty"
);
xs
->
head
(
"tty"
);
// All further non-markup text gets copied to the tty:
// All further non-markup text gets copied to the tty:
xs
->
_text
=
this
;
// requires friend declaration!
xs
->
_text
=
this
;
// requires friend declaration!
}
else
{
delete
(
file
);
// and leave xtty as NULL
LogVMOutput
=
false
;
DisplayVMOutput
=
true
;
LogCompilation
=
false
;
}
}
}
// finish_log() is called during normal VM shutdown. finish_log_on_error() is
// finish_log() is called during normal VM shutdown. finish_log_on_error() is
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录