Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
e89cfee2
R
runtime
项目概览
dotNET Platform
/
runtime
10 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
e89cfee2
编写于
7月 17, 2023
作者:
M
Michał Petryka
提交者:
GitHub
7月 17, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Intrinsify Array GetArrayDataReference for SZ arrays (#87374)
上级
3c07a775
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
121 addition
and
8 deletion
+121
-8
src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.CoreCLR.cs
...c/System/Runtime/InteropServices/MemoryMarshal.CoreCLR.cs
+1
-0
src/coreclr/jit/importercalls.cpp
src/coreclr/jit/importercalls.cpp
+26
-7
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.NativeAot.cs
...System/Runtime/InteropServices/MemoryMarshal.NativeAot.cs
+1
-0
src/coreclr/vm/jitinterface.cpp
src/coreclr/vm/jitinterface.cpp
+1
-1
src/tests/JIT/Intrinsics/MemoryMarshalGetArrayDataReference.cs
...ests/JIT/Intrinsics/MemoryMarshalGetArrayDataReference.cs
+92
-0
未找到文件。
src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.CoreCLR.cs
浏览文件 @
e89cfee2
...
...
@@ -33,6 +33,7 @@ public static unsafe partial class MemoryMarshal
/// This technique does not perform array variance checks. The caller must manually perform any array variance checks
/// if the caller wishes to write to the returned reference.
/// </remarks>
[
Intrinsic
]
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
static
ref
byte
GetArrayDataReference
(
Array
array
)
{
...
...
src/coreclr/jit/importercalls.cpp
浏览文件 @
e89cfee2
...
...
@@ -2762,14 +2762,33 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
case
NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference
:
{
assert
(
sig
->
numArgs
==
1
);
assert
(
sig
->
sigInst
.
methInstCount
==
1
);
GenTree
*
array
=
impPopStack
().
val
;
CORINFO_CLASS_HANDLE
elemHnd
=
sig
->
sigInst
.
methInst
[
0
];
CorInfoType
jitType
=
info
.
compCompHnd
->
asCorInfoType
(
elemHnd
);
var_types
elemType
=
JITtype2varType
(
jitType
);
GenTree
*
array
=
impStackTop
().
val
;
bool
notNull
=
false
;
CORINFO_CLASS_HANDLE
elemHnd
=
NO_CLASS_HANDLE
;
CorInfoType
jitType
;
if
(
sig
->
sigInst
.
methInstCount
==
1
)
{
elemHnd
=
sig
->
sigInst
.
methInst
[
0
];
jitType
=
info
.
compCompHnd
->
asCorInfoType
(
elemHnd
);
}
else
{
bool
isExact
=
false
;
CORINFO_CLASS_HANDLE
arrayHnd
=
gtGetClassHandle
(
array
,
&
isExact
,
&
notNull
);
if
((
arrayHnd
==
NO_CLASS_HANDLE
)
||
!
info
.
compCompHnd
->
isSDArray
(
arrayHnd
))
{
return
nullptr
;
}
jitType
=
info
.
compCompHnd
->
getChildType
(
arrayHnd
,
&
elemHnd
);
}
array
=
impPopStack
().
val
;
assert
(
jitType
!=
CORINFO_TYPE_UNDEF
);
assert
((
jitType
!=
CORINFO_TYPE_VALUECLASS
)
||
(
elemHnd
!=
NO_CLASS_HANDLE
));
if
(
fgAddrCouldBeNull
(
array
))
if
(
!
notNull
&&
fgAddrCouldBeNull
(
array
))
{
GenTree
*
arrayClone
;
array
=
impCloneExpr
(
array
,
&
arrayClone
,
CHECK_SPILL_ALL
,
...
...
@@ -2780,7 +2799,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
}
GenTree
*
index
=
gtNewIconNode
(
0
,
TYP_I_IMPL
);
GenTreeIndexAddr
*
indexAddr
=
gtNewArrayIndexAddr
(
array
,
index
,
elemType
,
elemHnd
);
GenTreeIndexAddr
*
indexAddr
=
gtNewArrayIndexAddr
(
array
,
index
,
JITtype2varType
(
jitType
)
,
elemHnd
);
indexAddr
->
gtFlags
&=
~
GTF_INX_RNGCHK
;
indexAddr
->
gtFlags
|=
GTF_INX_ADDR_NONNULL
;
retNode
=
indexAddr
;
...
...
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.NativeAot.cs
浏览文件 @
e89cfee2
...
...
@@ -34,6 +34,7 @@ public static unsafe partial class MemoryMarshal
/// This technique does not perform array variance checks. The caller must manually perform any array variance checks
/// if the caller wishes to write to the returned reference.
/// </remarks>
[
Intrinsic
]
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
static
ref
byte
GetArrayDataReference
(
Array
array
)
{
...
...
src/coreclr/vm/jitinterface.cpp
浏览文件 @
e89cfee2
...
...
@@ -4737,7 +4737,7 @@ CorInfoType CEEInfo::getChildType (
}
/*********************************************************************/
// Check if this is a single dimensional array type
// Check if this is a single dimensional
, zero based
array type
bool
CEEInfo
::
isSDArray
(
CORINFO_CLASS_HANDLE
cls
)
{
CONTRACTL
{
...
...
src/tests/JIT/Intrinsics/MemoryMarshalGetArrayDataReference.cs
浏览文件 @
e89cfee2
...
...
@@ -114,6 +114,98 @@ unsafe static int Main(string[] args)
ThrowsNRE
(()
=>
ref
ptrByte
(
NoInline
<
byte
[
]>
(
null
)));
ThrowsNRE
(()
=>
ref
ptrString
(
NoInline
<
string
[
]>
(
null
)));
// use no inline methods to avoid indirect call inlining in the future
[
MethodImpl
(
MethodImplOptions
.
NoInlining
)]
static
delegate
*<
Array
,
ref
byte
>
GetMdPtr
()
=>
&
MemoryMarshal
.
GetArrayDataReference
;
delegate
*<
Array
,
ref
byte
>
ptrMd
=
GetMdPtr
();
IsTrue
(
Unsafe
.
AreSame
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
testByteArray
),
ref
testByteArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
ptrMd
(
testByteArray
),
ref
testByteArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
(
testByteArray
)),
ref
testByteArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
testByteArray
)),
ref
testByteArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
ptrMd
(
NoInline
(
testByteArray
)),
ref
testByteArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
testStringArray
)),
ref
testStringArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
testStringArray
)),
ref
testStringArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
(
testStringArray
))),
ref
testStringArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
testStringArray
))),
ref
testStringArray
[
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
NoInline
(
testStringArray
))),
ref
testStringArray
[
0
]));
byte
[,]
testByteMdArray
=
new
byte
[
1
,
1
];
IsTrue
(
Unsafe
.
AreSame
(
ref
MemoryMarshal
.
GetArrayDataReference
(
testByteMdArray
),
ref
testByteMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
ptrMd
(
testByteMdArray
),
ref
testByteMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
(
testByteMdArray
)),
ref
testByteMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
ptrMd
(
NoInline
(
testByteMdArray
)),
ref
testByteMdArray
[
0
,
0
]));
string
[,]
testStringMdArray
=
new
string
[
1
,
1
];
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
(
testStringMdArray
)),
ref
testStringMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
testStringMdArray
)),
ref
testStringMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
(
testStringMdArray
))),
ref
testStringMdArray
[
0
,
0
]));
IsTrue
(
Unsafe
.
AreSame
(
ref
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
NoInline
(
testStringMdArray
))),
ref
testStringMdArray
[
0
,
0
]));
Array
nonZeroArray
=
Array
.
CreateInstance
(
typeof
(
string
),
new
[]
{
1
},
new
[]
{
-
1
});
string
test
=
"test"
;
nonZeroArray
.
SetValue
(
test
,
-
1
);
IsTrue
(
ReferenceEquals
(
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
(
nonZeroArray
)),
test
));
IsTrue
(
ReferenceEquals
(
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
nonZeroArray
)),
test
));
IsTrue
(
ReferenceEquals
(
Unsafe
.
As
<
byte
,
string
>(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
(
nonZeroArray
))),
test
));
IsTrue
(
ReferenceEquals
(
Unsafe
.
As
<
byte
,
string
>(
ref
ptrMd
(
NoInline
(
nonZeroArray
))),
test
));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
new
byte
[
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
new
string
[
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
new
byte
[
0
,
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
new
string
[
0
,
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
new
byte
[
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
new
string
[
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
new
byte
[
0
,
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
new
string
[
0
,
0
])));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
(
new
byte
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
(
new
string
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
(
new
byte
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
(
new
string
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
new
byte
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
new
string
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
new
byte
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
new
string
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
(
new
byte
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
(
new
string
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
(
new
byte
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
(
new
string
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
<
Array
>(
new
byte
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
<
Array
>(
new
string
[
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
<
Array
>(
new
byte
[
0
,
0
]))));
IsFalse
(
Unsafe
.
IsNullRef
(
ref
ptrMd
(
NoInline
<
Array
>(
new
string
[
0
,
0
]))));
ThrowsNRE
(()
=>
{
_
=
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
null
);
});
ThrowsNRE
(()
=>
{
_
=
ref
ptrMd
(
null
);
});
ThrowsNRE
(()
=>
{
_
=
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
<
byte
[
]>
(
null
));
});
ThrowsNRE
(()
=>
{
_
=
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
<
string
[
]>
(
null
));
});
ThrowsNRE
(()
=>
{
_
=
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
null
));
});
ThrowsNRE
(()
=>
{
_
=
ref
ptrMd
(
NoInline
<
byte
[
]>
(
null
));
});
ThrowsNRE
(()
=>
{
_
=
ref
ptrMd
(
NoInline
<
string
[
]>
(
null
));
});
ThrowsNRE
(()
=>
{
_
=
ref
ptrMd
(
NoInline
<
Array
>(
null
));
});
ThrowsNRE
(()
=>
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
null
));
ThrowsNRE
(()
=>
ref
ptrMd
(
null
));
ThrowsNRE
(()
=>
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
<
byte
[
]>
(
null
)));
ThrowsNRE
(()
=>
ref
MemoryMarshal
.
GetArrayDataReference
((
Array
)
NoInline
<
string
[
]>
(
null
)));
ThrowsNRE
(()
=>
ref
MemoryMarshal
.
GetArrayDataReference
(
NoInline
<
Array
>(
null
)));
ThrowsNRE
(()
=>
ref
ptrMd
(
NoInline
<
byte
[
]>
(
null
)));
ThrowsNRE
(()
=>
ref
ptrMd
(
NoInline
<
string
[
]>
(
null
)));
ThrowsNRE
(()
=>
ref
ptrMd
(
NoInline
<
Array
>(
null
)));
// from https://github.com/dotnet/runtime/issues/58312#issuecomment-993491291
[
MethodImpl
(
MethodImplOptions
.
NoInlining
)]
static
int
Problem1
(
StructWithByte
[]
a
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录