Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
a04480fd
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
a04480fd
编写于
11月 09, 2009
作者:
P
prr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6899078: potential deadlock and performance issue in freeing strike resources with D3D pipeline
Reviewed-by: tdv, igor
上级
5d8cafdf
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
100 addition
and
20 deletion
+100
-20
src/share/classes/sun/font/Font2D.java
src/share/classes/sun/font/Font2D.java
+0
-15
src/share/classes/sun/font/FontDesignMetrics.java
src/share/classes/sun/font/FontDesignMetrics.java
+1
-1
src/share/classes/sun/font/FontStrikeDisposer.java
src/share/classes/sun/font/FontStrikeDisposer.java
+3
-1
src/share/classes/sun/font/StrikeCache.java
src/share/classes/sun/font/StrikeCache.java
+15
-3
src/share/classes/sun/java2d/Disposer.java
src/share/classes/sun/java2d/Disposer.java
+81
-0
未找到文件。
src/share/classes/sun/font/Font2D.java
浏览文件 @
a04480fd
...
...
@@ -320,21 +320,6 @@ public abstract class Font2D {
lastFontStrike
=
new
SoftReference
(
strike
);
StrikeCache
.
refStrike
(
strike
);
return
strike
;
}
else
{
/* We have found a cleared reference that has not yet
* been removed by the disposer.
* If we make this reference unreachable by removing it
* from the map,or overwriting it with a new reference to
* a new strike, then it is possible it may never be
* enqueued for disposal. That is the implication of
* the docs for java.lang.ref. So on finding a cleared
* reference, we need to dispose the native resources,
* if they haven't already been freed.
* The reference object needs to have a reference to
* the disposer instance for this to occur.
*/
((
StrikeCache
.
DisposableStrike
)
strikeRef
)
.
getDisposer
().
dispose
();
}
}
/* When we create a new FontStrike instance, we *must*
...
...
src/share/classes/sun/font/FontDesignMetrics.java
浏览文件 @
a04480fd
...
...
@@ -171,7 +171,7 @@ public final class FontDesignMetrics extends FontMetrics {
* out we can clear the keys from the table.
*/
private
static
class
KeyReference
extends
SoftReference
implements
DisposerRecord
{
implements
DisposerRecord
,
Disposer
.
PollDisposable
{
static
ReferenceQueue
queue
=
Disposer
.
getQueue
();
...
...
src/share/classes/sun/font/FontStrikeDisposer.java
浏览文件 @
a04480fd
...
...
@@ -25,6 +25,7 @@
package
sun.font
;
import
sun.java2d.Disposer
;
import
sun.java2d.DisposerRecord
;
/*
...
...
@@ -49,7 +50,8 @@ import sun.java2d.DisposerRecord;
* entries would be removed much more promptly than we need.
*/
class
FontStrikeDisposer
implements
DisposerRecord
{
class
FontStrikeDisposer
implements
DisposerRecord
,
Disposer
.
PollDisposable
{
Font2D
font2D
;
FontStrikeDesc
desc
;
...
...
src/share/classes/sun/font/StrikeCache.java
浏览文件 @
a04480fd
...
...
@@ -254,9 +254,20 @@ public final class StrikeCache {
// because they may be accessed on that thread at the time of the
// disposal (for example, when the accel. cache is invalidated)
// REMIND: this look a bit heavyweight, but should be ok
// because strike disposal is a relatively infrequent operation,
// more worrisome is the necessity of getting a GC here.
// Whilst this is a bit heavyweight, in most applications
// strike disposal is a relatively infrequent operation, so it
// doesn't matter. But in some tests that use vast numbers
// of strikes, the switching back and forth is measurable.
// So the "pollRemove" call is added to batch up the work.
// If we are polling we know we've already been called back
// and can directly dispose the record.
// Also worrisome is the necessity of getting a GC here.
if
(
Disposer
.
pollingQueue
)
{
doDispose
(
disposer
);
return
;
}
RenderQueue
rq
=
null
;
GraphicsEnvironment
ge
=
GraphicsEnvironment
.
getLocalGraphicsEnvironment
();
...
...
@@ -277,6 +288,7 @@ public final class StrikeCache {
rq
.
flushAndInvokeNow
(
new
Runnable
()
{
public
void
run
()
{
doDispose
(
disposer
);
Disposer
.
pollRemove
();
}
});
}
finally
{
...
...
src/share/classes/sun/java2d/Disposer.java
浏览文件 @
a04480fd
...
...
@@ -29,6 +29,7 @@ import java.lang.ref.Reference;
import
java.lang.ref.ReferenceQueue
;
import
java.lang.ref.PhantomReference
;
import
java.lang.ref.WeakReference
;
import
java.util.ArrayList
;
import
java.util.Hashtable
;
/**
...
...
@@ -146,6 +147,7 @@ public class Disposer implements Runnable {
rec
.
dispose
();
obj
=
null
;
rec
=
null
;
clearDeferredRecords
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Exception while removing reference: "
+
e
);
e
.
printStackTrace
();
...
...
@@ -153,6 +155,85 @@ public class Disposer implements Runnable {
}
}
/*
* This is a marker interface that, if implemented, means it
* doesn't acquire any special locks, and is safe to
* be disposed in the poll loop on whatever thread
* which happens to be the Toolkit thread, is in use.
*/
public
static
interface
PollDisposable
{
};
private
static
ArrayList
<
DisposerRecord
>
deferredRecords
=
null
;
private
static
void
clearDeferredRecords
()
{
if
(
deferredRecords
==
null
||
deferredRecords
.
isEmpty
())
{
return
;
}
for
(
int
i
=
0
;
i
<
deferredRecords
.
size
();
i
++)
{
try
{
DisposerRecord
rec
=
deferredRecords
.
get
(
i
);
rec
.
dispose
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Exception while disposing deferred rec."
);
e
.
printStackTrace
();
}
}
deferredRecords
.
clear
();
}
/*
* Set to indicate the queue is presently being polled.
*/
public
static
volatile
boolean
pollingQueue
=
false
;
/*
* The pollRemove() method is called back from a dispose method
* that is running on the toolkit thread and wants to
* dispose any pending refs that are safe to be disposed
* on that thread.
*/
public
static
void
pollRemove
()
{
/* This should never be called recursively, so this check
* is just a safeguard against the unexpected.
*/
if
(
pollingQueue
)
{
return
;
}
Object
obj
;
pollingQueue
=
true
;
int
freed
=
0
;
int
deferred
=
0
;
try
{
while
((
obj
=
queue
.
poll
())
!=
null
&&
freed
<
10000
&&
deferred
<
100
)
{
freed
++;
((
Reference
)
obj
).
clear
();
DisposerRecord
rec
=
(
DisposerRecord
)
records
.
remove
(
obj
);
if
(
rec
instanceof
PollDisposable
)
{
rec
.
dispose
();
obj
=
null
;
rec
=
null
;
}
else
{
if
(
rec
==
null
)
{
// shouldn't happen, but just in case.
continue
;
}
deferred
++;
if
(
deferredRecords
==
null
)
{
deferredRecords
=
new
ArrayList
<
DisposerRecord
>(
5
);
}
deferredRecords
.
add
(
rec
);
}
}
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Exception while removing reference: "
+
e
);
e
.
printStackTrace
();
}
finally
{
pollingQueue
=
false
;
}
}
private
static
native
void
initIDs
();
/*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录