Imported Upstream version 4.6.0.243
Former-commit-id: ff34202749e8df2aa83f2578b16260b444f50987
This commit is contained in:
parent
804b15604f
commit
3cc9601fd9
@ -93,6 +93,7 @@ GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested));
|
||||
/* pointer to a previously allocated heap */
|
||||
/* object. */
|
||||
|
||||
// Keep somewhat in sync with mono/metadata/profiler.h:enum MonoGCEvent
|
||||
typedef enum {
|
||||
GC_EVENT_START,
|
||||
GC_EVENT_MARK_START,
|
||||
|
@ -1,4 +1,8 @@
|
||||
.TH mprof-report 1 ""
|
||||
.de Sp
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.TH mprof-report 1 ""
|
||||
.SH The Mono log profiler
|
||||
.PP
|
||||
The Mono \f[I]log\f[] profiler can be used to collect a lot of
|
||||
@ -237,6 +241,9 @@ Methods JITted using mono JIT, Methods JITted using LLVM, Total time
|
||||
spent JITting (sec), User Time, System Time, Total Time, Working Set,
|
||||
Private Bytes, Virtual Bytes, Page Faults and CPU Load Average (1min,
|
||||
5min and 15min).
|
||||
.IP \[bu] 2
|
||||
\f[I]coverage\f[]: collect code coverage data. This implies enabling
|
||||
the \f[I]calls\f[] option.
|
||||
.RE
|
||||
.SS Analyzing the profile data
|
||||
.PP
|
||||
@ -260,7 +267,7 @@ To see this info invoke mprof-report as follows:
|
||||
\f[B]mprof-report\ --traces\ output.mlpd\f[]
|
||||
.PP
|
||||
The maximum number of methods in each stack trace can be specified
|
||||
with the \f[I]\[em]maxframes=NUM\f[] option:
|
||||
with the \f[I]--maxframes=NUM\f[] option:
|
||||
.PP
|
||||
\f[B]mprof-report\ --traces\ --maxframes=4\ output.mlpd\f[]
|
||||
.PP
|
||||
@ -272,7 +279,7 @@ specific events when the \f[I]nocalls\f[] option is used, so in
|
||||
that case, if more stack frames are required in mprof-report, a
|
||||
bigger value for maxframes when profiling must be used, too.
|
||||
.PP
|
||||
The \f[I]\[em]traces\f[] option also controls the reverse reference
|
||||
The \f[I]--traces\f[] option also controls the reverse reference
|
||||
feature in the heapshot report: for each class it reports how many
|
||||
references to objects of that class come from other classes.
|
||||
.SS Sort order for methods and allocations
|
||||
@ -362,6 +369,10 @@ version
|
||||
\f[I]heapshot\f[]: live heap usage at heap shots
|
||||
.IP \[bu] 2
|
||||
\f[I]counters\f[]: counters samples
|
||||
.IP \[bu] 2
|
||||
\f[I]coverage\f[]: code coverage data
|
||||
.IP \[bu] 2
|
||||
\f[I]stats\f[]: event statistics
|
||||
.PP
|
||||
It is possible to limit some of the data displayed to a timeframe
|
||||
of the program execution with the option:
|
||||
@ -391,23 +402,23 @@ Instead of printing the usual reports from the profiler data, it is
|
||||
possible to track some interesting information about some specific
|
||||
object addresses.
|
||||
The objects are selected based on their address with the
|
||||
\f[I]\[em]track\f[] option as follows:
|
||||
\f[I]--track\f[] option as follows:
|
||||
.PP
|
||||
\f[B]--track=0xaddr1[,0xaddr2,...]\f[]
|
||||
.PP
|
||||
The reported info (if available in the data file), will be class
|
||||
name, size, creation time, stack trace of creation (with the
|
||||
\f[I]\[em]traces\f[] option), etc.
|
||||
\f[I]--traces\f[] option), etc.
|
||||
If heapshot data is available it will be possible to also track
|
||||
what other objects reference one of the listed addresses.
|
||||
.PP
|
||||
The object addresses can be gathered either from the profiler
|
||||
report in some cases (like in the monitor lock report), from the
|
||||
live application or they can be selected with the
|
||||
\f[I]\[em]find=FINDSPEC\f[] option.
|
||||
\f[I]--find=FINDSPEC\f[] option.
|
||||
FINDSPEC can be one of the following:
|
||||
.IP \[bu] 2
|
||||
\f[I]S:SIZE\f[]: where the object is selected if it's size is at
|
||||
\f[I]S:SIZE\f[]: where the object is selected if its size is at
|
||||
least \f[I]SIZE\f[]
|
||||
.IP \[bu] 2
|
||||
\f[I]T:NAME\f[]: where the object is selected if \f[I]NAME\f[]
|
||||
@ -432,6 +443,13 @@ By default mprof-report will print the summary data to the console.
|
||||
To print it to a file, instead, use the option:
|
||||
.PP
|
||||
\f[B]--out=FILENAME\f[]
|
||||
.SS Processing code coverage data
|
||||
.PP
|
||||
If you ran the profiler with the \f[I]coverage\f[] option, you can
|
||||
process the collected coverage data into an XML file by running
|
||||
mprof-report like this:
|
||||
.PP
|
||||
\f[B]mprof-report --coverage-out=coverage.xml output.mlpd\f[]
|
||||
.SS Dealing with profiler slowness
|
||||
.PP
|
||||
If the profiler needs to collect lots of data, the execution of the
|
||||
@ -439,20 +457,20 @@ program will slow down significantly, usually 10 to 20 times
|
||||
slower.
|
||||
There are several ways to reduce the impact of the profiler on the
|
||||
program execution.
|
||||
.SS Use the statistical sampling mode
|
||||
.PP
|
||||
.IP "\f[I]Use the statistical sampling mode\f[]" 4
|
||||
.Sp
|
||||
Statistical sampling allows executing a program under the profiler
|
||||
with minimal performance overhead (usually less than 10%).
|
||||
This mode allows checking where the program is spending most of
|
||||
it's execution time without significantly perturbing its behaviour.
|
||||
.SS Collect less data
|
||||
.PP
|
||||
its execution time without significantly perturbing its behaviour.
|
||||
.IP "\f[I]Collect less data\f[]" 4
|
||||
.Sp
|
||||
Collecting method enter/leave events can be very expensive,
|
||||
especially in programs that perform many millions of tiny calls.
|
||||
The profiler option \f[I]nocalls\f[] can be used to avoid
|
||||
collecting this data or it can be limited to only a few call levels
|
||||
with the \f[I]calldepth\f[] option.
|
||||
.PP
|
||||
.Sp
|
||||
Object allocation information is expensive as well, though much
|
||||
less than method enter/leave events.
|
||||
If it's not needed, it can be skipped with the \f[I]noalloc\f[]
|
||||
@ -463,14 +481,14 @@ expensive as well.
|
||||
The impact of stack trace information can be reduced by setting a
|
||||
low value with the \f[I]maxframes\f[] option or by eliminating them
|
||||
completely, by setting it to 0.
|
||||
.PP
|
||||
The other major source of data is the heapshot profiler option:
|
||||
especially if the managed heap is big, since every object needs to
|
||||
be inspected.
|
||||
.Sp
|
||||
The other major source of data is the \f[I]heapshot\f[] profiler
|
||||
option: especially if the managed heap is big, since every object
|
||||
needs to be inspected.
|
||||
The \f[I]MODE\f[] parameter of the \f[I]heapshot\f[] option can be
|
||||
used to reduce the frequency of the heap shots.
|
||||
.SS Reduce the timestamp overhead
|
||||
.PP
|
||||
.IP "\f[I]Reduce the timestamp overhead\f[]" 4
|
||||
.Sp
|
||||
On many operating systems or architectures what actually slows down
|
||||
profiling is the function provided by the system to get timestamp
|
||||
information.
|
||||
@ -486,15 +504,15 @@ There are a few ways to minimize the amount of data, for example by
|
||||
not collecting some of the more space-consuming information or by
|
||||
compressing the information on the fly or by just generating a
|
||||
summary report.
|
||||
.SS Reducing the amount of data
|
||||
.PP
|
||||
.IP "\f[I]Reducing the amount of data\f[]" 4
|
||||
.Sp
|
||||
Method enter/leave events can be excluded completely with the
|
||||
\f[I]nocalls\f[] option or they can be limited to just a few levels
|
||||
of calls with the \f[I]calldepth\f[] option.
|
||||
For example, the option:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]calldepth=10\f[]
|
||||
.PP
|
||||
.Sp
|
||||
will ignore the method events when there are more than 10 managed
|
||||
stack frames.
|
||||
This is very useful for programs that have deep recursion or for
|
||||
@ -503,59 +521,59 @@ the call stack.
|
||||
The optimal number for the calldepth option depends on the program
|
||||
and it needs to be balanced between providing enough profiling
|
||||
information and allowing fast execution speed.
|
||||
.PP
|
||||
.Sp
|
||||
Note that by default, if method events are not recorded at all, the
|
||||
profiler will collect stack trace information at events like
|
||||
allocations.
|
||||
To avoid gathering this data, use the \f[I]maxframes=0\f[] profiler
|
||||
option.
|
||||
.PP
|
||||
.Sp
|
||||
Allocation events can be eliminated with the \f[I]noalloc\f[]
|
||||
option.
|
||||
.PP
|
||||
.Sp
|
||||
Heap shot data can also be huge: by default it is collected at each
|
||||
major collection.
|
||||
To reduce the frequency, you can specify a heapshot mode: for
|
||||
example to collect every 5 collections (including major and minor):
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]heapshot=5gc\f[]
|
||||
.PP
|
||||
.Sp
|
||||
or when at least 5 seconds passed since the last heap shot:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]heapshot=5000ms\f[]
|
||||
.SS Compressing the data
|
||||
.PP
|
||||
.IP "\f[I]Compressing the data\f[]" 4
|
||||
.Sp
|
||||
To reduce the amout of disk space used by the data, the data can be
|
||||
compressed either after it has been generated with the gzip
|
||||
command:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]gzip\ -9\ output.mlpd\f[]
|
||||
.PP
|
||||
.Sp
|
||||
or it can be compressed automatically by using the \f[I]zip\f[]
|
||||
profiler option.
|
||||
Note that in this case there could be a significant slowdown of the
|
||||
profiled program.
|
||||
.PP
|
||||
.Sp
|
||||
The mprof-report program will tranparently deal with either
|
||||
compressed or uncompressed data files.
|
||||
.SS Generating only a summary report
|
||||
.PP
|
||||
.IP "\f[I]Generating only a summary report\f[]" 4
|
||||
.Sp
|
||||
Often it's enough to look at the profiler summary report to
|
||||
diagnose an issue and in this case it's possible to avoid saving
|
||||
the profiler data file to disk.
|
||||
This can be accomplished with the \f[I]report\f[] profiler option,
|
||||
which will basically send the data to the mprof-report program for
|
||||
display.
|
||||
.PP
|
||||
.Sp
|
||||
To have more control of what summary information is reported (or to
|
||||
use a completely different program to decode the profiler data),
|
||||
the \f[I]output\f[] profiler option can be used, with \f[B]|\f[] as
|
||||
the first character: the rest of the output name will be executed
|
||||
as a program with the data fed in on the standard input.
|
||||
.PP
|
||||
.Sp
|
||||
For example, to print only the Monitor summary with stack trace
|
||||
information, you could use it like this:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]output=|mprof-report\ --reports=monitor\ --traces\ -\f[]
|
||||
.SH WEB SITE
|
||||
http://www.mono-project.com/docs/debug+profile/profile/profiler/
|
||||
@ -563,5 +581,4 @@ http://www.mono-project.com/docs/debug+profile/profile/profiler/
|
||||
.PP
|
||||
mono(1)
|
||||
.SH AUTHORS
|
||||
Paolo Molaro.
|
||||
|
||||
Paolo Molaro, Alex Rønne Petersen
|
||||
|
@ -125,9 +125,9 @@ namespace Mono.Data.Sqlite
|
||||
// Compatibility with versions < 3.5.0
|
||||
int n;
|
||||
|
||||
try {
|
||||
if (UnsafeNativeMethods.use_sqlite3_open_v2) {
|
||||
n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero);
|
||||
} catch (EntryPointNotFoundException) {
|
||||
} else {
|
||||
Console.WriteLine ("Your sqlite3 version is old - please upgrade to at least v3.5.0!");
|
||||
n = UnsafeNativeMethods.sqlite3_open (ToUTF8 (strFilename), out db);
|
||||
}
|
||||
|
@ -208,9 +208,9 @@ namespace Mono.Data.Sqlite
|
||||
#else
|
||||
ResetConnection(db);
|
||||
int n;
|
||||
try {
|
||||
if (UnsafeNativeMethods.use_sqlite3_close_v2) {
|
||||
n = UnsafeNativeMethods.sqlite3_close_v2(db);
|
||||
} catch (EntryPointNotFoundException) {
|
||||
} else {
|
||||
n = UnsafeNativeMethods.sqlite3_close(db);
|
||||
}
|
||||
#endif
|
||||
|
@ -16,6 +16,27 @@ namespace Mono.Data.Sqlite
|
||||
#endif
|
||||
internal static class UnsafeNativeMethods
|
||||
{
|
||||
internal static readonly bool use_sqlite3_close_v2 = false;
|
||||
internal static readonly bool use_sqlite3_open_v2 = false;
|
||||
internal static readonly bool use_sqlite3_create_function_v2 = false;
|
||||
static UnsafeNativeMethods()
|
||||
{
|
||||
// calculate the version number parts
|
||||
// https://www.sqlite.org/c3ref/c_source_id.html
|
||||
// (<major> * 1000000) + (<minor> * 1000) + (<release>)
|
||||
int versionNumber = sqlite3_libversion_number();
|
||||
int release = versionNumber % 1000;
|
||||
int minor = (versionNumber / 1000) % 1000;
|
||||
int major = versionNumber / 1000000;
|
||||
Version version = new Version(major, minor, release);
|
||||
|
||||
// set the various versions
|
||||
// https://sqlite.org/changes.html
|
||||
use_sqlite3_open_v2 = version >= new Version(3, 5, 0);
|
||||
use_sqlite3_close_v2 = version >= new Version(3, 7, 14);
|
||||
use_sqlite3_create_function_v2 = version >= new Version(3, 7, 3);
|
||||
}
|
||||
|
||||
#if !SQLITE_STANDARD
|
||||
|
||||
#if !USE_INTEROP_DLL
|
||||
@ -730,6 +751,13 @@ namespace Mono.Data.Sqlite
|
||||
#endif
|
||||
internal static extern int sqlite3_free (IntPtr ptr);
|
||||
|
||||
#if !PLATFORM_COMPACTFRAMEWORK
|
||||
[DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
#else
|
||||
[DllImport(SQLITE_DLL)]
|
||||
#endif
|
||||
internal static extern int sqlite3_libversion_number();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,15 @@ System.IO.Pipes/AnonymousPipeClientStream.cs
|
||||
System.IO.Pipes/AnonymousPipeServerStream.cs
|
||||
System.IO.Pipes/NamedPipeClientStream.cs
|
||||
System.IO.Pipes/NamedPipeServerStream.cs
|
||||
System.IO.Pipes/PipeAccessRights.cs
|
||||
System.IO.Pipes/PipeAccessRule.cs
|
||||
System.IO.Pipes/PipeAuditRule.cs
|
||||
System.IO.Pipes/PipeDirection.cs
|
||||
System.IO.Pipes/PipeInterfaces.cs
|
||||
System.IO.Pipes/PipeOptions.cs
|
||||
System.IO.Pipes/PipeSecurity.cs
|
||||
System.IO.Pipes/PipeStream.cs
|
||||
System.IO.Pipes/PipeStreamImpersonationWorker.cs
|
||||
System.IO.Pipes/PipeTransmissionMode.cs
|
||||
|
||||
ReferenceSources/SR.cs
|
||||
|
@ -1,11 +1,6 @@
|
||||
#include common_System.Core.dll.sources
|
||||
#include dynamic_System.Core.dll.sources
|
||||
|
||||
System.IO.Pipes/PipeAccessRights.cs
|
||||
System.IO.Pipes/PipeAccessRule.cs
|
||||
System.IO.Pipes/PipeAuditRule.cs
|
||||
System.IO.Pipes/PipeSecurity.cs
|
||||
System.IO.Pipes/PipeStreamImpersonationWorker.cs
|
||||
System.IO.Pipes/PipeUnix.cs
|
||||
System.IO.Pipes/PipeWin32.cs
|
||||
|
||||
|
@ -450,7 +450,7 @@ namespace System.Net
|
||||
newWebHeaders.Add(headerName,webHeaders[headerName]);
|
||||
}
|
||||
|
||||
webHeaders = newWebHeaders;
|
||||
this.webHeaders = newWebHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Win32.SafeHandles
|
||||
{
|
||||
public sealed class SafeAccessTokenHandle : SafeHandle
|
||||
{
|
||||
public override bool IsInvalid {
|
||||
get {
|
||||
return handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public SafeAccessTokenHandle ()
|
||||
: base (IntPtr.Zero, true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -157,7 +157,11 @@ internal class Latin1Encoding : Encoding
|
||||
buffer = EncoderFallback.CreateFallbackBuffer ();
|
||||
if (Char.IsSurrogate (ch) && count > 1 &&
|
||||
Char.IsSurrogate (chars [charIndex]))
|
||||
buffer.Fallback (ch, chars [charIndex], charIndex++ - 1);
|
||||
{
|
||||
buffer.Fallback (ch, chars [charIndex], charIndex - 1);
|
||||
charIndex++;
|
||||
count--;
|
||||
}
|
||||
else
|
||||
buffer.Fallback (ch, charIndex - 1);
|
||||
if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
|
||||
|
@ -862,6 +862,22 @@ namespace System {
|
||||
}
|
||||
}
|
||||
#else
|
||||
public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
return GetEnvironmentVariable (variable);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
return GetEnvironmentVariables ();
|
||||
|
||||
return (IDictionary)new Hashtable ();
|
||||
}
|
||||
|
||||
public static void SetEnvironmentVariable (string variable, string value)
|
||||
{
|
||||
if (variable == null)
|
||||
@ -875,6 +891,14 @@ namespace System {
|
||||
|
||||
InternalSetEnvironmentVariable (variable, value);
|
||||
}
|
||||
|
||||
public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
SetEnvironmentVariable (variable, value);
|
||||
|
||||
// other targets ignored
|
||||
}
|
||||
#endif
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
internal static extern void InternalSetEnvironmentVariable (string variable, string value);
|
||||
|
@ -119,6 +119,40 @@ namespace MonoTests.System.Text
|
||||
Assert.AreEqual (testchars [i], (char) bytes [i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes7 ()
|
||||
{
|
||||
var latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
|
||||
var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
|
||||
var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
|
||||
Assert.AreEqual (expected, actual, "#1");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#2");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F, 0x20 };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#3");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#4");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834\udd1e "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#5");
|
||||
|
||||
expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
|
||||
actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
|
||||
Assert.AreEqual (expected, actual, "#6");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834 "); // invalid surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#7");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[])
|
||||
public void TestGetChars1 ()
|
||||
{
|
||||
@ -212,6 +246,15 @@ namespace MonoTests.System.Text
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (EncoderFallbackException))]
|
||||
public void EncoderFallback ()
|
||||
{
|
||||
Encoding e = Encoding.ASCII.Clone () as Encoding;
|
||||
e.EncoderFallback = new EncoderExceptionFallback ();
|
||||
e.GetBytes ("\u24c8");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (DecoderFallbackException))]
|
||||
public void DecoderFallback ()
|
||||
|
350
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
Normal file
350
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
Normal file
@ -0,0 +1,350 @@
|
||||
//
|
||||
// Latin1EncodingTest.cs
|
||||
//
|
||||
// Author:
|
||||
// Alexander Köplinger (alexander.koeplinger@xamarin.com)
|
||||
//
|
||||
// Copyright (C) 2016 Xamarin, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Constraints;
|
||||
|
||||
#if !MOBILE
|
||||
using NUnit.Framework.SyntaxHelpers;
|
||||
#endif
|
||||
|
||||
namespace MonoTests.System.Text
|
||||
{
|
||||
[TestFixture]
|
||||
public class Latin1EncodingTest
|
||||
{
|
||||
private char[] testchars;
|
||||
private byte[] testbytes;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
testchars = new char[4];
|
||||
testchars[0] = 'T';
|
||||
testchars[1] = 'e';
|
||||
testchars[2] = 's';
|
||||
testchars[3] = 't';
|
||||
testbytes = new byte[4];
|
||||
testbytes[0] = (byte) 'T';
|
||||
testbytes[1] = (byte) 'e';
|
||||
testbytes[2] = (byte) 's';
|
||||
testbytes[3] = (byte) 't';
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBrowserDisplay ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserDisplay);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBrowserSave ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserSave);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsMailNewsDisplay ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsDisplay);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsMailNewsSave ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsSave);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[])
|
||||
public void TestGetBytes1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars);
|
||||
for (int i = 0; i < testchars.Length; i++)
|
||||
Assert.AreEqual (testchars[i], (char) bytes[i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[], int, int)
|
||||
public void TestGetBytes2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars, 1, 1);
|
||||
Assert.AreEqual (1, bytes.Length, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test non-Latin1 char in char[]
|
||||
public void TestGetBytes3 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
testchars[2] = (char) 0x100;
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars);
|
||||
Assert.AreEqual ('T', (char) bytes [0], "#1");
|
||||
Assert.AreEqual ('e', (char) bytes [1], "#2");
|
||||
Assert.AreEqual ('?', (char) bytes [2], "#3");
|
||||
Assert.AreEqual ('t', (char) bytes [3], "#4");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[], int, int, byte[], int)
|
||||
public void TestGetBytes4 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetBytes(testchars, 1, 1, bytes, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string, int, int, byte[], int)
|
||||
public void TestGetBytes5 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetBytes("Test", 1, 1, bytes, 0);
|
||||
Assert.AreEqual ('e', (char) bytes [0], "#1");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes6 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes("Test");
|
||||
for (int i = 0; i < testchars.Length; i++)
|
||||
Assert.AreEqual (testchars [i], (char) bytes [i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes7 ()
|
||||
{
|
||||
var latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
|
||||
var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
|
||||
var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
|
||||
Assert.AreEqual (expected, actual, "#1");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#2");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F, 0x20 };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#3");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#4");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834\udd1e "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#5");
|
||||
|
||||
expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
|
||||
actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
|
||||
Assert.AreEqual (expected, actual, "#6");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834 "); // invalid surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#7");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[])
|
||||
public void TestGetChars1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = latin1_encoding.GetChars(testbytes);
|
||||
for (int i = 0; i < testbytes.Length; i++)
|
||||
Assert.AreEqual (testbytes[i], (byte) chars[i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[], int, int)
|
||||
public void TestGetChars2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = latin1_encoding.GetChars(testbytes, 1, 1);
|
||||
Assert.AreEqual (1, chars.Length, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[], int, int, char[], int)
|
||||
public void TestGetChars4 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = new char[1];
|
||||
int cnt = latin1_encoding.GetChars(testbytes, 1, 1, chars, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetString(char[])
|
||||
public void TestGetString1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
string str = latin1_encoding.GetString(testbytes);
|
||||
Assert.AreEqual ("Test", str);
|
||||
}
|
||||
|
||||
[Test] // Test GetString(char[], int, int)
|
||||
public void TestGetString2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
string str = latin1_encoding.GetString(testbytes, 1, 2);
|
||||
Assert.AreEqual ("es", str);
|
||||
}
|
||||
|
||||
[Test] // Test Decoder
|
||||
public void TestDecoder ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = new char[1];
|
||||
int cnt = latin1_encoding.GetDecoder().GetChars(testbytes, 1, 1, chars, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test Decoder
|
||||
public void TestEncoder ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetEncoder().GetBytes(testchars, 1, 1, bytes, 0, false);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestZero ()
|
||||
{
|
||||
Encoding encoding = Encoding.GetEncoding ("latin1");
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0]), "#1");
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (EncoderFallbackException))]
|
||||
public void EncoderFallback ()
|
||||
{
|
||||
Encoding e = Encoding.GetEncoding ("latin1").Clone () as Encoding;
|
||||
e.EncoderFallback = new EncoderExceptionFallback ();
|
||||
e.GetBytes ("\u24c8");
|
||||
}
|
||||
|
||||
[Test]
|
||||
// [ExpectedException (typeof (ArgumentException))]
|
||||
public void DecoderFallback2 ()
|
||||
{
|
||||
var bytes = new byte[] {
|
||||
0x30, 0xa0, 0x31, 0xa8
|
||||
};
|
||||
var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
|
||||
enc.DecoderFallback = new TestFallbackDecoder ();
|
||||
|
||||
var chars = new char [7];
|
||||
var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
|
||||
Console.WriteLine (ret);
|
||||
|
||||
for (int i = 0; i < chars.Length; i++) {
|
||||
Console.Write ("{0:x2} ", (int)chars [i]);
|
||||
}
|
||||
Console.WriteLine ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DecoderFallback3 ()
|
||||
{
|
||||
var bytes = new byte[] {
|
||||
0x30, 0xa0, 0x31, 0xa8
|
||||
};
|
||||
var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
|
||||
enc.DecoderFallback = new TestFallbackDecoder ();
|
||||
|
||||
var chars = new char[] { '9', '8', '7', '6', '5' };
|
||||
var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
|
||||
|
||||
Assert.That (ret, Is.EqualTo (4), "ret");
|
||||
Assert.That (chars [0], Is.EqualTo ('0'), "chars[0]");
|
||||
Assert.That (chars [1], Is.EqualTo ((char)0xA0), "chars[1]");
|
||||
Assert.That (chars [2], Is.EqualTo ('1'), "chars[2]");
|
||||
Assert.That (chars [3], Is.EqualTo ((char)0xA8), "chars[3]");
|
||||
Assert.That (chars [4], Is.EqualTo ('5'), "chars[4]");
|
||||
}
|
||||
|
||||
class TestFallbackDecoder : DecoderFallback {
|
||||
const int count = 2;
|
||||
|
||||
public override int MaxCharCount {
|
||||
get { return count; }
|
||||
}
|
||||
|
||||
public override DecoderFallbackBuffer CreateFallbackBuffer ()
|
||||
{
|
||||
return new Buffer ();
|
||||
}
|
||||
|
||||
class Buffer : DecoderFallbackBuffer {
|
||||
char[] queue;
|
||||
int index;
|
||||
|
||||
public override int Remaining {
|
||||
get {
|
||||
return queue.Length - index;
|
||||
}
|
||||
}
|
||||
|
||||
public override char GetNextChar ()
|
||||
{
|
||||
return index < queue.Length ? queue [index++] : '\0';
|
||||
}
|
||||
|
||||
public override bool Fallback (byte[] bytes, int unused)
|
||||
{
|
||||
queue = new char[bytes.Length * count];
|
||||
index = 0;
|
||||
for (int i = 0; i < bytes.Length; i++) {
|
||||
for (int j = 0; j < count; j++)
|
||||
queue [index++] = (char)(bytes [i]+j);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool MovePrevious ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override void Reset ()
|
||||
{
|
||||
base.Reset ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -615,7 +615,6 @@ System.Security/NamedPermissionSet.cs
|
||||
System.Security/PermissionBuilder.cs
|
||||
System.Security/PermissionSet.cs
|
||||
System.Security/PolicyLevelType.cs
|
||||
System.Security/SafeAccessTokenHandle.cs
|
||||
System.Security/SecureString.cs
|
||||
System.Security/SecurityElement.cs
|
||||
System.Security/SecurityFrame.cs
|
||||
@ -1393,6 +1392,7 @@ ReferenceSources/SecurityContext.cs
|
||||
../referencesource/mscorlib/system/security/attributes.cs
|
||||
../referencesource/mscorlib/system/security/securitycontext.cs
|
||||
../referencesource/mscorlib/system/security/securitydocument.cs
|
||||
../referencesource/mscorlib/system/security/safesecurityhandles.cs
|
||||
|
||||
../referencesource/mscorlib/system/security/claims/Claim.cs
|
||||
../referencesource/mscorlib/system/security/claims/ClaimsIdentity.cs
|
||||
|
@ -405,6 +405,7 @@ System.Text/EncoderTest.cs
|
||||
System.Text/EncodingTest.cs
|
||||
System.Text/EncodingTester.cs
|
||||
System.Text/EncodingInfoTest.cs
|
||||
System.Text/Latin1EncodingTest.cs
|
||||
System.Text/StringBuilderTest.cs
|
||||
System.Text/TestEncoding.cs
|
||||
System.Text/UnicodeEncodingTest.cs
|
||||
|
@ -501,6 +501,44 @@ namespace System.Dynamic {
|
||||
binder.ReturnType
|
||||
);
|
||||
|
||||
#if MONO // referencesource version
|
||||
Expression condition;
|
||||
// If the return type can not be assigned null then just check for type assignablity otherwise allow null.
|
||||
if (binder.ReturnType.IsValueType && Nullable.GetUnderlyingType(binder.ReturnType) == null) {
|
||||
condition = Expression.TypeIs(resultMO.Expression, binder.ReturnType);
|
||||
}
|
||||
else {
|
||||
condition = Expression.OrElse(
|
||||
Expression.Equal(resultMO.Expression, Expression.Constant(null)),
|
||||
Expression.TypeIs(resultMO.Expression, binder.ReturnType));
|
||||
}
|
||||
|
||||
var checkedConvert = Expression.Condition(
|
||||
condition,
|
||||
convert,
|
||||
Expression.Throw(
|
||||
Expression.New(typeof(InvalidCastException).GetConstructor(new Type[]{typeof(string)}),
|
||||
Expression.Call(
|
||||
typeof(string).GetMethod("Format", new Type[] {typeof(string), typeof(object[])}),
|
||||
Expression.Constant(convertFailed),
|
||||
Expression.NewArrayInit(typeof(object),
|
||||
Expression.Condition(
|
||||
Expression.Equal(resultMO.Expression, Expression.Constant(null)),
|
||||
Expression.Constant("null"),
|
||||
Expression.Call(
|
||||
resultMO.Expression,
|
||||
typeof(object).GetMethod("GetType")
|
||||
),
|
||||
typeof(object)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
binder.ReturnType
|
||||
),
|
||||
binder.ReturnType
|
||||
);
|
||||
#else
|
||||
var checkedConvert = Expression.Condition(
|
||||
Expression.TypeIs(resultMO.Expression, binder.ReturnType),
|
||||
convert,
|
||||
@ -524,6 +562,7 @@ namespace System.Dynamic {
|
||||
),
|
||||
binder.ReturnType
|
||||
);
|
||||
#endif
|
||||
|
||||
resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
0e58c3fba67bf21766014677b5f894f7637162d9
|
||||
c490c7433c000c0ca9ff7be0753080941738fdbc
|
@ -1 +1 @@
|
||||
8ad53def268a4750474dee2731ef4039642458aa
|
||||
c3bbfb8e3d0bb1d4648a456800a8f616d8a28016
|
@ -1 +1 @@
|
||||
4ed6e201e6785a6e9e44a113d2be4c9fd569673c
|
||||
8410f10f87dea9524681b3f688dab2f70afbf9b5
|
@ -1 +1 @@
|
||||
9d728aa18a9d89c58a94469c86f374658f784ccd
|
||||
d2b12594e92c61982d88980ec4bfaeb7c3bdf9ab
|
@ -38,7 +38,11 @@ namespace Microsoft.Win32.SafeHandles {
|
||||
[SecurityCritical]
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
#if MONO
|
||||
return true;
|
||||
#else
|
||||
return Win32Native.CloseHandle(handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2562,6 +2562,9 @@ namespace Mono.CSharp
|
||||
pow /= 10;
|
||||
}
|
||||
}
|
||||
} else if (c == '\n' || c == UnicodeLS || c == UnicodePS) {
|
||||
advance_line ();
|
||||
break;
|
||||
} else if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') {
|
||||
break;
|
||||
}
|
||||
@ -2587,9 +2590,6 @@ namespace Mono.CSharp
|
||||
while (c == ' ' || c == '\t')
|
||||
c = get_char ();
|
||||
|
||||
if (c == '\n' || c == UnicodeLS || c == UnicodePS)
|
||||
advance_line ();
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
|
28
mcs/tests/dtest-065.cs
Normal file
28
mcs/tests/dtest-065.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System.Dynamic;
|
||||
|
||||
public class TestConvert : DynamicObject
|
||||
{
|
||||
public override bool TryConvert (ConvertBinder binder, out object result)
|
||||
{
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class Test : DynamicObject
|
||||
{
|
||||
public override bool TryInvokeMember (InvokeMemberBinder binder, object [] args, out object result)
|
||||
{
|
||||
result = new TestConvert ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class XX
|
||||
{
|
||||
public static void Main ()
|
||||
{
|
||||
dynamic t = new Test ();
|
||||
string result = t.SomeMethod ();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<symbols>
|
||||
<files>
|
||||
<file id="1" name="test-debug-30.cs" checksum="d3addfa69f16faf00991ef839451a975" />
|
||||
<file id="1" name="test-debug-30.cs" checksum="5303b32b0208123737567d53022ae3d5" />
|
||||
</files>
|
||||
<methods>
|
||||
<method token="0x6000001">
|
||||
@ -27,5 +27,14 @@
|
||||
<locals />
|
||||
<scopes />
|
||||
</method>
|
||||
<method token="0x6000004">
|
||||
<sequencepoints>
|
||||
<entry il="0x0" row="23" col="2" file_ref="1" hidden="false" />
|
||||
<entry il="0x1" row="24" col="3" file_ref="1" hidden="false" />
|
||||
<entry il="0x6" row="25" col="2" file_ref="1" hidden="false" />
|
||||
</sequencepoints>
|
||||
<locals />
|
||||
<scopes />
|
||||
</method>
|
||||
</methods>
|
||||
</symbols>
|
@ -15,4 +15,12 @@ class PragmaNewLinesParsing
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma warning disable 618
|
||||
#pragma warning restore 618
|
||||
|
||||
void OneMore ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
720ef10c534ff81a6c9296b3f09a50987144d5a9
|
||||
216a310da0866d4efac81f4c8a3bcdc849ad8891
|
@ -1927,6 +1927,20 @@ mono_domain_assembly_search (MonoAssemblyName *aname,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
prevent_running_reference_assembly (MonoAssembly *ass, MonoError *error)
|
||||
{
|
||||
mono_error_init (error);
|
||||
gboolean refasm = mono_assembly_get_reference_assembly_attribute (ass, error);
|
||||
if (!is_ok (error))
|
||||
return TRUE;
|
||||
if (refasm) {
|
||||
mono_error_set_bad_image (error, ass->image, "Could not load file or assembly or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context.\n");
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MonoReflectionAssembly *
|
||||
ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean refOnly)
|
||||
{
|
||||
@ -1935,37 +1949,40 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re
|
||||
MonoDomain *domain = mono_domain_get ();
|
||||
char *name, *filename;
|
||||
MonoImageOpenStatus status = MONO_IMAGE_OK;
|
||||
MonoAssembly *ass;
|
||||
MonoAssembly *ass = NULL;
|
||||
|
||||
name = NULL;
|
||||
result = NULL;
|
||||
|
||||
mono_error_init (&error);
|
||||
|
||||
if (fname == NULL) {
|
||||
MonoException *exc = mono_get_exception_argument_null ("assemblyFile");
|
||||
mono_set_pending_exception (exc);
|
||||
return NULL;
|
||||
mono_error_set_argument_null (&error, "assemblyFile", "");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
name = filename = mono_string_to_utf8_checked (fname, &error);
|
||||
if (mono_error_set_pending_exception (&error))
|
||||
return NULL;
|
||||
if (!is_ok (&error))
|
||||
goto leave;
|
||||
|
||||
ass = mono_assembly_open_full (filename, &status, refOnly);
|
||||
|
||||
if (!ass) {
|
||||
MonoException *exc;
|
||||
|
||||
if (status == MONO_IMAGE_IMAGE_INVALID)
|
||||
exc = mono_get_exception_bad_image_format2 (NULL, fname);
|
||||
mono_error_set_bad_image_name (&error, name, "");
|
||||
else
|
||||
exc = mono_get_exception_file_not_found2 (NULL, fname);
|
||||
g_free (name);
|
||||
mono_set_pending_exception (exc);
|
||||
return NULL;
|
||||
mono_error_set_exception_instance (&error, mono_get_exception_file_not_found2 (NULL, fname));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
if (!refOnly && prevent_running_reference_assembly (ass, &error))
|
||||
goto leave;
|
||||
|
||||
result = mono_assembly_get_object_checked (domain, ass, &error);
|
||||
if (!result)
|
||||
mono_error_set_pending_exception (&error);
|
||||
|
||||
leave:
|
||||
mono_error_set_pending_exception (&error);
|
||||
g_free (name);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2000,6 +2017,11 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!refonly && prevent_running_reference_assembly (ass, &error)) {
|
||||
mono_error_set_pending_exception (&error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
refass = mono_assembly_get_object_checked (domain, ass, &error);
|
||||
if (!refass)
|
||||
mono_error_set_pending_exception (&error);
|
||||
@ -2017,7 +2039,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
|
||||
MonoAssembly *ass;
|
||||
MonoAssemblyName aname;
|
||||
MonoReflectionAssembly *refass = NULL;
|
||||
gchar *name;
|
||||
gchar *name = NULL;
|
||||
gboolean parsed;
|
||||
|
||||
g_assert (assRef);
|
||||
@ -2026,16 +2048,13 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
|
||||
if (mono_error_set_pending_exception (&error))
|
||||
return NULL;
|
||||
parsed = mono_assembly_name_parse (name, &aname);
|
||||
g_free (name);
|
||||
|
||||
if (!parsed) {
|
||||
/* This is a parse error... */
|
||||
if (!refOnly) {
|
||||
refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
|
||||
if (!mono_error_ok (&error)) {
|
||||
mono_error_set_pending_exception (&error);
|
||||
return NULL;
|
||||
}
|
||||
if (!is_ok (&error))
|
||||
goto leave;
|
||||
}
|
||||
return refass;
|
||||
}
|
||||
@ -2047,25 +2066,31 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoString *assRef,
|
||||
/* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
|
||||
if (!refOnly) {
|
||||
refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
|
||||
if (!mono_error_ok (&error)) {
|
||||
mono_error_set_pending_exception (&error);
|
||||
return NULL;
|
||||
}
|
||||
if (!is_ok (&error))
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
refass = NULL;
|
||||
if (!refass) {
|
||||
return NULL;
|
||||
}
|
||||
if (!refass)
|
||||
goto leave;
|
||||
ass = refass->assembly;
|
||||
}
|
||||
|
||||
if (refass == NULL)
|
||||
refass = mono_assembly_get_object_checked (domain, ass, &error);
|
||||
if (!refOnly && prevent_running_reference_assembly (ass, &error))
|
||||
goto leave;
|
||||
|
||||
if (refass == NULL)
|
||||
mono_error_set_pending_exception (&error);
|
||||
else
|
||||
MONO_OBJECT_SETREF (refass, evidence, evidence);
|
||||
g_assert (ass);
|
||||
if (refass == NULL) {
|
||||
refass = mono_assembly_get_object_checked (domain, ass, &error);
|
||||
if (!is_ok (&error))
|
||||
goto leave;
|
||||
}
|
||||
|
||||
MONO_OBJECT_SETREF (refass, evidence, evidence);
|
||||
|
||||
leave:
|
||||
g_free (name);
|
||||
mono_error_set_pending_exception (&error);
|
||||
return refass;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
1
mono/metadata/assembly.c.REMOVED.git-id
Normal file
1
mono/metadata/assembly.c.REMOVED.git-id
Normal file
@ -0,0 +1 @@
|
||||
7bd02ff37eea77a111cb30ce2d3b64953d487736
|
@ -424,7 +424,6 @@ on_gc_notification (GC_EventType event)
|
||||
switch (e) {
|
||||
case MONO_GC_EVENT_PRE_STOP_WORLD:
|
||||
MONO_GC_WORLD_STOP_BEGIN ();
|
||||
mono_thread_info_suspend_lock ();
|
||||
break;
|
||||
|
||||
case MONO_GC_EVENT_POST_STOP_WORLD:
|
||||
@ -437,7 +436,6 @@ on_gc_notification (GC_EventType event)
|
||||
|
||||
case MONO_GC_EVENT_POST_START_WORLD:
|
||||
MONO_GC_WORLD_RESTART_END (1);
|
||||
mono_thread_info_suspend_unlock ();
|
||||
break;
|
||||
|
||||
case MONO_GC_EVENT_START:
|
||||
@ -477,7 +475,21 @@ on_gc_notification (GC_EventType event)
|
||||
}
|
||||
|
||||
mono_profiler_gc_event (e, 0);
|
||||
|
||||
switch (e) {
|
||||
case MONO_GC_EVENT_PRE_STOP_WORLD:
|
||||
mono_thread_info_suspend_lock ();
|
||||
mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED, 0);
|
||||
break;
|
||||
case MONO_GC_EVENT_POST_START_WORLD:
|
||||
mono_thread_info_suspend_unlock ();
|
||||
mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD_UNLOCKED, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_gc_heap_resize (size_t new_size)
|
||||
@ -769,7 +781,7 @@ mono_gc_invoke_finalizers (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
MonoBoolean
|
||||
mono_gc_pending_finalizers (void)
|
||||
{
|
||||
return GC_should_invoke_finalizers ();
|
||||
|
@ -1 +1 @@
|
||||
17da478b5e9c1f089d76de0bc275da6ab5e21077
|
||||
56e12ad673e2765956a4fc89dade62a15656a02f
|
@ -697,4 +697,8 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
|
||||
void
|
||||
mono_context_init_checked (MonoDomain *domain, MonoError *error);
|
||||
|
||||
gboolean
|
||||
mono_assembly_get_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error);
|
||||
|
||||
|
||||
#endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */
|
||||
|
@ -807,6 +807,16 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
|
||||
|
||||
mono_profiler_appdomain_name (domain, domain->friendly_name);
|
||||
|
||||
/* Have to do this quite late so that we at least have System.Object */
|
||||
MonoError custom_attr_error;
|
||||
if (mono_assembly_get_reference_assembly_attribute (ass, &custom_attr_error)) {
|
||||
char *corlib_file = g_build_filename (mono_assembly_getrootdir (), "mono", current_runtime->framework_version, "mscorlib.dll", NULL);
|
||||
g_print ("Could not load file or assembly %s. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context.", corlib_file);
|
||||
g_free (corlib_file);
|
||||
exit (1);
|
||||
}
|
||||
mono_error_assert_ok (&custom_attr_error);
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
|
@ -145,10 +145,6 @@ void mono_gchandle_free_domain (MonoDomain *domain);
|
||||
|
||||
typedef void (*FinalizerThreadCallback) (gpointer user_data);
|
||||
|
||||
/* if there are finalizers to run, run them. Returns the number of finalizers run */
|
||||
gboolean mono_gc_pending_finalizers (void);
|
||||
void mono_gc_finalize_notify (void);
|
||||
|
||||
void* mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size);
|
||||
void* mono_gc_alloc_obj (MonoVTable *vtable, size_t size);
|
||||
void* mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length);
|
||||
|
@ -263,8 +263,12 @@ mono_gc_run_finalize (void *obj, void *data)
|
||||
if (log_finalizers)
|
||||
g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o);
|
||||
|
||||
mono_profiler_gc_finalize_object_begin (o);
|
||||
|
||||
runtime_invoke (o, NULL, &exc, NULL);
|
||||
|
||||
mono_profiler_gc_finalize_object_end (o);
|
||||
|
||||
if (log_finalizers)
|
||||
g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o);
|
||||
|
||||
@ -779,11 +783,15 @@ finalizer_thread (gpointer unused)
|
||||
}
|
||||
}
|
||||
|
||||
mono_profiler_gc_finalize_begin ();
|
||||
|
||||
/* If finished == TRUE, mono_gc_cleanup has been called (from mono_runtime_cleanup),
|
||||
* before the domain is unloaded.
|
||||
*/
|
||||
mono_gc_invoke_finalizers ();
|
||||
|
||||
mono_profiler_gc_finalize_end ();
|
||||
|
||||
mono_threads_join_threads ();
|
||||
|
||||
reference_queue_proccess_all ();
|
||||
|
@ -195,7 +195,7 @@ jit_info_table_chunk_index (MonoJitInfoTableChunk *chunk, MonoThreadHazardPointe
|
||||
|
||||
while (left < right) {
|
||||
int pos = (left + right) / 2;
|
||||
MonoJitInfo *ji = (MonoJitInfo *)get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
|
||||
MonoJitInfo *ji = (MonoJitInfo *)mono_get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
|
||||
gint8 *code_end = (gint8*)ji->code_start + ji->code_size;
|
||||
|
||||
if (addr < code_end)
|
||||
@ -228,7 +228,7 @@ jit_info_table_find (MonoJitInfoTable *table, MonoThreadHazardPointers *hp, gint
|
||||
MonoJitInfoTableChunk *chunk = table->chunks [chunk_pos];
|
||||
|
||||
while (pos < chunk->num_elements) {
|
||||
ji = (MonoJitInfo *)get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
|
||||
ji = (MonoJitInfo *)mono_get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
|
||||
|
||||
++pos;
|
||||
|
||||
@ -286,7 +286,7 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
|
||||
table by a hazard pointer and make sure that the pointer is
|
||||
still there after we've made it hazardous, we don't have to
|
||||
worry about the writer freeing the table. */
|
||||
table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
|
||||
table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
|
||||
|
||||
ji = jit_info_table_find (table, hp, (gint8*)addr);
|
||||
if (hp)
|
||||
@ -298,7 +298,7 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
|
||||
|
||||
/* Maybe its an AOT module */
|
||||
if (try_aot && mono_get_root_domain () && mono_get_root_domain ()->aot_modules) {
|
||||
table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
|
||||
table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
|
||||
module_ji = jit_info_table_find (table, hp, (gint8*)addr);
|
||||
if (module_ji)
|
||||
ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr);
|
||||
|
@ -91,6 +91,39 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* mono_config_get_os:
|
||||
*
|
||||
* Returns the operating system that Mono is running on, as used for dllmap entries.
|
||||
*/
|
||||
const char *
|
||||
mono_config_get_os (void)
|
||||
{
|
||||
return CONFIG_OS;
|
||||
}
|
||||
|
||||
/**
|
||||
* mono_config_get_cpu:
|
||||
*
|
||||
* Returns the architecture that Mono is running on, as used for dllmap entries.
|
||||
*/
|
||||
const char *
|
||||
mono_config_get_cpu (void)
|
||||
{
|
||||
return CONFIG_CPU;
|
||||
}
|
||||
|
||||
/**
|
||||
* mono_config_get_wordsize:
|
||||
*
|
||||
* Returns the word size that Mono is running on, as used for dllmap entries.
|
||||
*/
|
||||
const char *
|
||||
mono_config_get_wordsize (void)
|
||||
{
|
||||
return CONFIG_WORDSIZE;
|
||||
}
|
||||
|
||||
static void start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
|
@ -13,6 +13,10 @@
|
||||
|
||||
MONO_BEGIN_DECLS
|
||||
|
||||
MONO_API const char *mono_config_get_os (void);
|
||||
MONO_API const char *mono_config_get_cpu (void);
|
||||
MONO_API const char *mono_config_get_wordsize (void);
|
||||
|
||||
MONO_API const char* mono_get_config_dir (void);
|
||||
MONO_API void mono_set_config_dir (const char *dir);
|
||||
|
||||
|
@ -50,6 +50,8 @@ MONO_API int mono_gc_get_generation (MonoObject *object);
|
||||
MONO_API int mono_gc_collection_count (int generation);
|
||||
MONO_API int64_t mono_gc_get_used_size (void);
|
||||
MONO_API int64_t mono_gc_get_heap_size (void);
|
||||
MONO_API MonoBoolean mono_gc_pending_finalizers (void);
|
||||
MONO_API void mono_gc_finalize_notify (void);
|
||||
MONO_API int mono_gc_invoke_finalizers (void);
|
||||
/* heap walking is only valid in the pre-stop-world event callback */
|
||||
MONO_API int mono_gc_walk_heap (int flags, MonoGCReferences callback, void *data);
|
||||
|
@ -75,6 +75,11 @@ void mono_profiler_gc_moves (void **objects, int num);
|
||||
void mono_profiler_gc_handle (int op, int type, uintptr_t handle, MonoObject *obj);
|
||||
void mono_profiler_gc_roots (int num, void **objects, int *root_types, uintptr_t *extra_info);
|
||||
|
||||
void mono_profiler_gc_finalize_begin (void);
|
||||
void mono_profiler_gc_finalize_object_begin (MonoObject *obj);
|
||||
void mono_profiler_gc_finalize_object_end (MonoObject *obj);
|
||||
void mono_profiler_gc_finalize_end (void);
|
||||
|
||||
void mono_profiler_code_chunk_new (gpointer chunk, int size);
|
||||
void mono_profiler_code_chunk_destroy (gpointer chunk);
|
||||
void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, gconstpointer data);
|
||||
|
@ -102,6 +102,11 @@ struct _ProfilerDesc {
|
||||
MonoProfileGCHandleFunc gc_handle;
|
||||
MonoProfileGCRootFunc gc_roots;
|
||||
|
||||
MonoProfileGCFinalizeFunc gc_finalize_begin;
|
||||
MonoProfileGCFinalizeObjectFunc gc_finalize_object_begin;
|
||||
MonoProfileGCFinalizeObjectFunc gc_finalize_object_end;
|
||||
MonoProfileGCFinalizeFunc gc_finalize_end;
|
||||
|
||||
MonoProfileFunc runtime_initialized_event;
|
||||
|
||||
MonoProfilerCodeChunkNew code_chunk_new;
|
||||
@ -925,6 +930,50 @@ mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback, MonoPro
|
||||
prof_list->gc_roots = roots_callback;
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_gc_finalize_begin (void)
|
||||
{
|
||||
for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
|
||||
if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_begin)
|
||||
prof->gc_finalize_begin (prof->profiler);
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_gc_finalize_object_begin (MonoObject *obj)
|
||||
{
|
||||
for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
|
||||
if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_begin)
|
||||
prof->gc_finalize_object_begin (prof->profiler, obj);
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_gc_finalize_object_end (MonoObject *obj)
|
||||
{
|
||||
for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
|
||||
if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_end)
|
||||
prof->gc_finalize_object_end (prof->profiler, obj);
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_gc_finalize_end (void)
|
||||
{
|
||||
for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
|
||||
if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_end)
|
||||
prof->gc_finalize_end (prof->profiler);
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_install_gc_finalize (MonoProfileGCFinalizeFunc begin, MonoProfileGCFinalizeObjectFunc begin_obj, MonoProfileGCFinalizeObjectFunc end_obj, MonoProfileGCFinalizeFunc end)
|
||||
{
|
||||
if (!prof_list)
|
||||
return;
|
||||
|
||||
prof_list->gc_finalize_begin = begin;
|
||||
prof_list->gc_finalize_object_begin = begin_obj;
|
||||
prof_list->gc_finalize_object_begin = end_obj;
|
||||
prof_list->gc_finalize_end = end;
|
||||
}
|
||||
|
||||
void
|
||||
mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback)
|
||||
{
|
||||
|
@ -31,7 +31,8 @@ typedef enum {
|
||||
MONO_PROFILE_IOMAP_EVENTS = 1 << 18, /* this should likely be removed, too */
|
||||
MONO_PROFILE_GC_MOVES = 1 << 19,
|
||||
MONO_PROFILE_GC_ROOTS = 1 << 20,
|
||||
MONO_PROFILE_CONTEXT_EVENTS = 1 << 21
|
||||
MONO_PROFILE_CONTEXT_EVENTS = 1 << 21,
|
||||
MONO_PROFILE_GC_FINALIZATION = 1 << 22
|
||||
} MonoProfileFlags;
|
||||
|
||||
typedef enum {
|
||||
@ -39,6 +40,7 @@ typedef enum {
|
||||
MONO_PROFILE_FAILED
|
||||
} MonoProfileResult;
|
||||
|
||||
// Keep somewhat in sync with libgc/include/gc.h:enum GC_EventType
|
||||
typedef enum {
|
||||
MONO_GC_EVENT_START,
|
||||
MONO_GC_EVENT_MARK_START,
|
||||
@ -46,10 +48,26 @@ typedef enum {
|
||||
MONO_GC_EVENT_RECLAIM_START,
|
||||
MONO_GC_EVENT_RECLAIM_END,
|
||||
MONO_GC_EVENT_END,
|
||||
/*
|
||||
* This is the actual arrival order of the following events:
|
||||
*
|
||||
* MONO_GC_EVENT_PRE_STOP_WORLD
|
||||
* MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED
|
||||
* MONO_GC_EVENT_POST_STOP_WORLD
|
||||
* MONO_GC_EVENT_PRE_START_WORLD
|
||||
* MONO_GC_EVENT_POST_START_WORLD_UNLOCKED
|
||||
* MONO_GC_EVENT_POST_START_WORLD
|
||||
*
|
||||
* The LOCKED and UNLOCKED events guarantee that, by the time they arrive,
|
||||
* the GC and suspend locks will both have been acquired and released,
|
||||
* respectively.
|
||||
*/
|
||||
MONO_GC_EVENT_PRE_STOP_WORLD,
|
||||
MONO_GC_EVENT_POST_STOP_WORLD,
|
||||
MONO_GC_EVENT_PRE_START_WORLD,
|
||||
MONO_GC_EVENT_POST_START_WORLD
|
||||
MONO_GC_EVENT_POST_START_WORLD,
|
||||
MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED,
|
||||
MONO_GC_EVENT_POST_START_WORLD_UNLOCKED
|
||||
} MonoGCEvent;
|
||||
|
||||
/* coverage info */
|
||||
@ -150,6 +168,9 @@ typedef void (*MonoProfileGCResizeFunc) (MonoProfiler *prof, int64_t new_size)
|
||||
typedef void (*MonoProfileGCHandleFunc) (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj);
|
||||
typedef void (*MonoProfileGCRootFunc) (MonoProfiler *prof, int num_roots, void **objects, int *root_types, uintptr_t *extra_info);
|
||||
|
||||
typedef void (*MonoProfileGCFinalizeFunc) (MonoProfiler *prof);
|
||||
typedef void (*MonoProfileGCFinalizeObjectFunc) (MonoProfiler *prof, MonoObject *obj);
|
||||
|
||||
typedef void (*MonoProfileIomapFunc) (MonoProfiler *prof, const char *report, const char *pathname, const char *new_pathname);
|
||||
|
||||
typedef mono_bool (*MonoProfileCoverageFilterFunc) (MonoProfiler *prof, MonoMethod *method);
|
||||
@ -197,6 +218,7 @@ MONO_API void mono_profiler_coverage_get (MonoProfiler *prof, MonoMethod *metho
|
||||
MONO_API void mono_profiler_install_gc (MonoProfileGCFunc callback, MonoProfileGCResizeFunc heap_resize_callback);
|
||||
MONO_API void mono_profiler_install_gc_moves (MonoProfileGCMoveFunc callback);
|
||||
MONO_API void mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback, MonoProfileGCRootFunc roots_callback);
|
||||
MONO_API void mono_profiler_install_gc_finalize (MonoProfileGCFinalizeFunc begin, MonoProfileGCFinalizeObjectFunc begin_obj, MonoProfileGCFinalizeObjectFunc end_obj, MonoProfileGCFinalizeFunc end);
|
||||
MONO_API void mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback);
|
||||
|
||||
MONO_API void mono_profiler_install_code_chunk_new (MonoProfilerCodeChunkNew callback);
|
||||
|
@ -490,7 +490,7 @@ mono_gc_invoke_finalizers (void)
|
||||
return sgen_gc_invoke_finalizers ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
MonoBoolean
|
||||
mono_gc_pending_finalizers (void)
|
||||
{
|
||||
return sgen_have_pending_finalizers ();
|
||||
|
@ -209,6 +209,8 @@ sgen_client_stop_world (int generation)
|
||||
|
||||
acquire_gc_locks ();
|
||||
|
||||
mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED, generation);
|
||||
|
||||
/* We start to scan after locks are taking, this ensures we won't be interrupted. */
|
||||
sgen_process_togglerefs ();
|
||||
|
||||
@ -283,6 +285,8 @@ sgen_client_restart_world (int generation, gint64 *stw_time)
|
||||
*/
|
||||
release_gc_locks ();
|
||||
|
||||
mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD_UNLOCKED, generation);
|
||||
|
||||
*stw_time = usec;
|
||||
}
|
||||
|
||||
|
@ -824,7 +824,7 @@ EXTRA_DIST = TestDriver.cs \
|
||||
Makefile.am.in
|
||||
|
||||
version.h: Makefile
|
||||
echo "#define FULL_VERSION \"Stable 4.6.0.182/3ed2bba\"" > version.h
|
||||
echo "#define FULL_VERSION \"Stable 4.6.0.243/dea2155\"" > version.h
|
||||
|
||||
# Utility target for patching libtool to speed up linking
|
||||
patch-libtool:
|
||||
|
@ -824,7 +824,7 @@ EXTRA_DIST = TestDriver.cs \
|
||||
Makefile.am.in
|
||||
|
||||
version.h: Makefile
|
||||
echo "#define FULL_VERSION \"Stable 4.6.0.182/3ed2bba\"" > version.h
|
||||
echo "#define FULL_VERSION \"Stable 4.6.0.243/dea2155\"" > version.h
|
||||
|
||||
# Utility target for patching libtool to speed up linking
|
||||
patch-libtool:
|
||||
|
@ -1 +1 @@
|
||||
95fb4f0f463f11376bc66366d33b0ada31e655e7
|
||||
573c53e6293cd2939965dca9b67122cfc812637e
|
@ -1883,3 +1883,8 @@ mono_throw_method_access (MonoMethod *callee, MonoMethod *caller)
|
||||
g_free (callee_name);
|
||||
g_free (caller_name);
|
||||
}
|
||||
|
||||
void
|
||||
mono_dummy_jit_icall (void)
|
||||
{
|
||||
}
|
||||
|
@ -226,4 +226,6 @@ double mono_ckfinite (double d);
|
||||
|
||||
void mono_throw_method_access (MonoMethod *callee, MonoMethod *caller);
|
||||
|
||||
void mono_dummy_jit_icall (void);
|
||||
|
||||
#endif /* __MONO_JIT_ICALLS_H__ */
|
||||
|
@ -1 +1 @@
|
||||
3bcf4cb71650d65d78892cb857793dfc5e9ff723
|
||||
a907decc82e6ebd6fbd2f02741729d50fcfe07b4
|
@ -1 +1 @@
|
||||
aa7acf5abc72eb26d1200dce837653f7885f2eab
|
||||
3f41fb3fc226e85aa23b373990dd4e5738d6d28d
|
@ -1 +1 @@
|
||||
a708eb3eb22b244fef50931de958816f2d0f4ece
|
||||
2eac36939370f203a0ed0b3ea7e284bc90b21527
|
@ -1 +1 @@
|
||||
d88a6c99a8f362bb690424ace4462d58f3d913d9
|
||||
357e260799833ed8d4a1bf415c148853bf610e39
|
@ -1 +1 @@
|
||||
2fe69c378a64914c4bb35bf1a52a00153609255b
|
||||
1bf1ba6fa13f613a176781c0d4a9c16183273460
|
@ -1 +1 @@
|
||||
5d6ebc7b6bc126975df54bdc38c29d247d5ca8d0
|
||||
783896f15681743acb6001dad302705db271bee9
|
@ -1 +1 @@
|
||||
3089a8546b1d3a4d605535a775c1f57d27eb793f
|
||||
7d2c0d8b8cfda73cacd3b6847b37f7c5dd523da4
|
@ -1 +1 @@
|
||||
352a868b87f98ab2000dd24c33320aee1b63b2a5
|
||||
c4ae82e0cbcbda75f4f963ba3f352e7d90dc4c14
|
@ -1 +1 @@
|
||||
3fe40d2cfc28fdd8a055b003ad58785d5cbd3427
|
||||
a1094afa173fbe0baeb75c2ff221e0e9b73ae7e9
|
@ -1 +1 @@
|
||||
022f8a5e790b8ea9334d4fa61bb7f92c99229c9f
|
||||
5003bfe025403fa2d02c9709b18d04fa2e26b491
|
@ -1 +1 @@
|
||||
badf12b33b3bf1d72f1466b48e8c8a0aeb517e88
|
||||
6a3a6c0aa4e1c0a792e0d4bcc355138b97d67f68
|
@ -1 +1 @@
|
||||
#define FULL_VERSION "Stable 4.6.0.182/3ed2bba"
|
||||
#define FULL_VERSION "Stable 4.6.0.243/dea2155"
|
||||
|
@ -1 +1 @@
|
||||
e8d53afea686ed76588370c99fe74beac2c0718b
|
||||
b213528caaa35b55a02a43f0c8b2329a40eeab75
|
@ -1 +1 @@
|
||||
99e68567571dcf59b3759f143d2642e0861c06de
|
||||
40e4187280464b96aac6aa5ea5d1f8539689ea02
|
@ -3,10 +3,14 @@
|
||||
|
||||
#define BUF_ID 0x4D504C01
|
||||
#define LOG_HEADER_ID 0x4D505A01
|
||||
#define LOG_VERSION_MAJOR 0
|
||||
#define LOG_VERSION_MINOR 4
|
||||
#define LOG_DATA_VERSION 12
|
||||
#define LOG_VERSION_MAJOR 1
|
||||
#define LOG_VERSION_MINOR 0
|
||||
#define LOG_DATA_VERSION 13
|
||||
/*
|
||||
* Changes in major/minor versions:
|
||||
* version 1.0: removed sysid field from header
|
||||
* added args, arch, os fields to header
|
||||
*
|
||||
* Changes in data versions:
|
||||
* version 2: added offsets in heap walk
|
||||
* version 3: added GC roots
|
||||
@ -27,6 +31,32 @@
|
||||
added TYPE_GC_HANDLE_{CREATED,DESTROYED}_BT
|
||||
TYPE_JIT events are no longer guaranteed to have code start/size info (can be zero)
|
||||
* version 12: added MONO_COUNTER_PROFILER
|
||||
* version 13: added MONO_GC_EVENT_{PRE_STOP_WORLD_LOCKED,POST_START_WORLD_UNLOCKED}
|
||||
added TYPE_META + TYPE_SYNC_POINT
|
||||
removed il and native offset in TYPE_SAMPLE_HIT
|
||||
methods in backtraces are now encoded as proper method pointers
|
||||
removed flags in backtrace format
|
||||
removed flags in metadata events
|
||||
changed the following fields to a single byte rather than leb128
|
||||
TYPE_GC_EVENT: event_type, generation
|
||||
TYPE_HEAP_ROOT: root_type
|
||||
TYPE_JITHELPER: type
|
||||
TYPE_SAMPLE_HIT: sample_type
|
||||
TYPE_CLAUSE: clause_type
|
||||
TYPE_SAMPLE_COUNTERS_DESC: type, unit, variance
|
||||
TYPE_SAMPLE_COUNTERS: type
|
||||
added time fields to all events that were missing one
|
||||
TYPE_HEAP_OBJECT
|
||||
TYPE_HEAP_ROOT
|
||||
TYPE_SAMPLE_USYM
|
||||
TYPE_SAMPLE_COUNTERS_DESC
|
||||
TYPE_COVERAGE_METHOD
|
||||
TYPE_COVERAGE_STATEMENT
|
||||
TYPE_COVERAGE_CLASS
|
||||
TYPE_COVERAGE_ASSEMBLY
|
||||
moved the time field in TYPE_SAMPLE_HIT to right after the event byte, now encoded as a regular time field
|
||||
changed the time field in TYPE_SAMPLE_COUNTERS to be encoded as a regular time field (in nanoseconds)
|
||||
added TYPE_GC_FINALIZE_{START,END,OBJECT_START,OBJECT_END}
|
||||
*/
|
||||
|
||||
enum {
|
||||
@ -40,6 +70,7 @@ enum {
|
||||
TYPE_SAMPLE,
|
||||
TYPE_RUNTIME,
|
||||
TYPE_COVERAGE,
|
||||
TYPE_META,
|
||||
/* extended type for TYPE_HEAP */
|
||||
TYPE_HEAP_START = 0 << 4,
|
||||
TYPE_HEAP_END = 1 << 4,
|
||||
@ -48,13 +79,6 @@ enum {
|
||||
/* extended type for TYPE_METADATA */
|
||||
TYPE_END_LOAD = 2 << 4,
|
||||
TYPE_END_UNLOAD = 4 << 4,
|
||||
/* metadata type byte for TYPE_METADATA */
|
||||
TYPE_CLASS = 1,
|
||||
TYPE_IMAGE = 2,
|
||||
TYPE_ASSEMBLY = 3,
|
||||
TYPE_DOMAIN = 4,
|
||||
TYPE_THREAD = 5,
|
||||
TYPE_CONTEXT = 6,
|
||||
/* extended type for TYPE_GC */
|
||||
TYPE_GC_EVENT = 1 << 4,
|
||||
TYPE_GC_RESIZE = 2 << 4,
|
||||
@ -63,15 +87,19 @@ enum {
|
||||
TYPE_GC_HANDLE_DESTROYED = 5 << 4,
|
||||
TYPE_GC_HANDLE_CREATED_BT = 6 << 4,
|
||||
TYPE_GC_HANDLE_DESTROYED_BT = 7 << 4,
|
||||
TYPE_GC_FINALIZE_START = 8 << 4,
|
||||
TYPE_GC_FINALIZE_END = 9 << 4,
|
||||
TYPE_GC_FINALIZE_OBJECT_START = 10 << 4,
|
||||
TYPE_GC_FINALIZE_OBJECT_END = 11 << 4,
|
||||
/* extended type for TYPE_METHOD */
|
||||
TYPE_LEAVE = 1 << 4,
|
||||
TYPE_ENTER = 2 << 4,
|
||||
TYPE_EXC_LEAVE = 3 << 4,
|
||||
TYPE_JIT = 4 << 4,
|
||||
/* extended type for TYPE_EXCEPTION */
|
||||
TYPE_THROW = 0 << 4,
|
||||
TYPE_CLAUSE = 1 << 4,
|
||||
TYPE_EXCEPTION_BT = 1 << 7,
|
||||
TYPE_THROW_NO_BT = 0 << 7,
|
||||
TYPE_THROW_BT = 1 << 7,
|
||||
TYPE_CLAUSE = 1 << 4,
|
||||
/* extended type for TYPE_ALLOC */
|
||||
TYPE_ALLOC_NO_BT = 0 << 4,
|
||||
TYPE_ALLOC_BT = 1 << 4,
|
||||
@ -91,9 +119,27 @@ enum {
|
||||
TYPE_COVERAGE_METHOD = 1 << 4,
|
||||
TYPE_COVERAGE_STATEMENT = 2 << 4,
|
||||
TYPE_COVERAGE_CLASS = 3 << 4,
|
||||
/* extended type for TYPE_META */
|
||||
TYPE_SYNC_POINT = 0 << 4,
|
||||
TYPE_END
|
||||
};
|
||||
|
||||
enum {
|
||||
/* metadata type byte for TYPE_METADATA */
|
||||
TYPE_CLASS = 1,
|
||||
TYPE_IMAGE = 2,
|
||||
TYPE_ASSEMBLY = 3,
|
||||
TYPE_DOMAIN = 4,
|
||||
TYPE_THREAD = 5,
|
||||
TYPE_CONTEXT = 6,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SYNC_POINT_PERIODIC,
|
||||
SYNC_POINT_WORLD_STOP,
|
||||
SYNC_POINT_WORLD_START
|
||||
} MonoProfilerSyncPointType;
|
||||
|
||||
// Sampling sources
|
||||
// Unless you have compiled with --enable-perf-events, only SAMPLE_CYCLES is available
|
||||
enum {
|
||||
|
@ -418,7 +418,7 @@ uintptr_t
|
||||
process_id (void)
|
||||
{
|
||||
#ifdef HOST_WIN32
|
||||
return 0; /* FIXME */
|
||||
return GetCurrentProcessId ();
|
||||
#else
|
||||
return (uintptr_t)getpid ();
|
||||
#endif
|
||||
|
@ -1144,10 +1144,7 @@ major_get_and_reset_num_major_objects_marked (void)
|
||||
|
||||
/* gcc 4.2.1 from xcode4 crashes on sgen_card_table_get_card_address () when this is enabled */
|
||||
#if defined(PLATFORM_MACOSX)
|
||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
||||
+ __GNUC_MINOR__ * 100 \
|
||||
+ __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION <= 40300
|
||||
#if MONO_GNUC_VERSION <= 40300
|
||||
#undef PREFETCH_CARDS
|
||||
#endif
|
||||
#endif
|
||||
|
@ -436,7 +436,8 @@ BASE_TEST_CS_SRC= \
|
||||
pinvoke_ppci.cs \
|
||||
pinvoke_ppcf.cs \
|
||||
pinvoke_ppcd.cs \
|
||||
bug-29585.cs
|
||||
bug-29585.cs \
|
||||
reference-loader.cs
|
||||
|
||||
TEST_CS_SRC_DIST= \
|
||||
$(BASE_TEST_CS_SRC) \
|
||||
@ -700,11 +701,13 @@ TEST_IL_SRC= \
|
||||
# but that need to be compiled
|
||||
PREREQ_IL_SRC=event-il.il module-cctor.il
|
||||
PREREQ_CS_SRC=
|
||||
PREREQ_IL_DLL_SRC=event-il.il module-cctor.il
|
||||
PREREQ_CS_DLL_SRC=
|
||||
PREREQ_IL_DLL_SRC=
|
||||
PREREQ_CS_DLL_SRC=TestingReferenceAssembly.cs TestingReferenceReferenceAssembly.cs
|
||||
|
||||
PREREQSI_IL=$(PREREQ_IL_SRC:.il=.exe)
|
||||
PREREQSI_CS=$(PREREQ_CS_SRC:.cs=.exe)
|
||||
PREREQSI_IL=$(PREREQ_IL_SRC:.il=.exe) \
|
||||
$(PREREQ_IL_DLL_SRC:.il=.dll)
|
||||
PREREQSI_CS=$(PREREQ_CS_SRC:.cs=.exe) \
|
||||
$(PREREQ_CS_DLL_SRC:.cs=.dll)
|
||||
TESTSI_CS=$(TEST_CS_SRC:.cs=.exe)
|
||||
TESTSI_IL=$(TEST_IL_SRC:.il=.exe)
|
||||
TESTBS=$(BENCHSRC:.cs=.exe)
|
||||
@ -719,6 +722,13 @@ EXTRA_DIST=test-driver test-runner.cs $(TEST_CS_SRC_DIST) $(TEST_IL_SRC) \
|
||||
%.exe: %.cs TestDriver.dll
|
||||
$(MCS) -r:System.dll -r:System.Xml.dll -r:System.Core.dll -r:TestDriver.dll -r:Mono.Posix.dll -out:$@ $<
|
||||
|
||||
%.dll: %.cs
|
||||
$(MCS) -r:System.dll -target:library -out:$@ $<
|
||||
|
||||
TestingReferenceReferenceAssembly.dll: TestingReferenceReferenceAssembly.cs TestingReferenceAssembly.dll
|
||||
$(MCS) -r:TestingReferenceAssembly.dll -target:library -out:$@ $<
|
||||
|
||||
|
||||
# mkbundle works on ppc, but the pkg-config POC doesn't when run with make test
|
||||
if POWERPC
|
||||
test_platform:
|
||||
|
@ -842,7 +842,8 @@ BASE_TEST_CS_SRC = \
|
||||
pinvoke_ppci.cs \
|
||||
pinvoke_ppcf.cs \
|
||||
pinvoke_ppcd.cs \
|
||||
bug-29585.cs
|
||||
bug-29585.cs \
|
||||
reference-loader.cs
|
||||
|
||||
TEST_CS_SRC_DIST = \
|
||||
$(BASE_TEST_CS_SRC) \
|
||||
@ -1056,10 +1057,14 @@ TEST_IL_SRC = \
|
||||
# but that need to be compiled
|
||||
PREREQ_IL_SRC = event-il.il module-cctor.il
|
||||
PREREQ_CS_SRC =
|
||||
PREREQ_IL_DLL_SRC = event-il.il module-cctor.il
|
||||
PREREQ_CS_DLL_SRC =
|
||||
PREREQSI_IL = $(PREREQ_IL_SRC:.il=.exe)
|
||||
PREREQSI_CS = $(PREREQ_CS_SRC:.cs=.exe)
|
||||
PREREQ_IL_DLL_SRC =
|
||||
PREREQ_CS_DLL_SRC = TestingReferenceAssembly.cs TestingReferenceReferenceAssembly.cs
|
||||
PREREQSI_IL = $(PREREQ_IL_SRC:.il=.exe) \
|
||||
$(PREREQ_IL_DLL_SRC:.il=.dll)
|
||||
|
||||
PREREQSI_CS = $(PREREQ_CS_SRC:.cs=.exe) \
|
||||
$(PREREQ_CS_DLL_SRC:.cs=.dll)
|
||||
|
||||
TESTSI_CS = $(TEST_CS_SRC:.cs=.exe)
|
||||
TESTSI_IL = $(TEST_IL_SRC:.il=.exe)
|
||||
TESTBS = $(BENCHSRC:.cs=.exe)
|
||||
@ -1596,6 +1601,12 @@ aotcheck: testaot gshared-aot
|
||||
%.exe: %.cs TestDriver.dll
|
||||
$(MCS) -r:System.dll -r:System.Xml.dll -r:System.Core.dll -r:TestDriver.dll -r:Mono.Posix.dll -out:$@ $<
|
||||
|
||||
%.dll: %.cs
|
||||
$(MCS) -r:System.dll -target:library -out:$@ $<
|
||||
|
||||
TestingReferenceReferenceAssembly.dll: TestingReferenceReferenceAssembly.cs TestingReferenceAssembly.dll
|
||||
$(MCS) -r:TestingReferenceAssembly.dll -target:library -out:$@ $<
|
||||
|
||||
# mkbundle works on ppc, but the pkg-config POC doesn't when run with make test
|
||||
@POWERPC_TRUE@test_platform:
|
||||
# Can't use mkbundle on win32 since there is no static build there
|
||||
|
111
mono/tests/reference-loader.cs
Normal file
111
mono/tests/reference-loader.cs
Normal file
@ -0,0 +1,111 @@
|
||||
//
|
||||
// reference-loader.cs:
|
||||
//
|
||||
// Test for reference assembly loading
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
public class Tests {
|
||||
public static int Main (string[] args)
|
||||
{
|
||||
return TestDriver.RunTests (typeof (Tests), args);
|
||||
}
|
||||
|
||||
public static int test_0_loadFrom_reference ()
|
||||
{
|
||||
// Check that loading a reference assembly by filename for execution is an error
|
||||
try {
|
||||
var a = Assembly.LoadFrom ("./TestingReferenceAssembly.dll");
|
||||
} catch (BadImageFormatException exn) {
|
||||
// Console.Error.WriteLine ("exn was {0}", exn);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int test_0_load_reference ()
|
||||
{
|
||||
// Check that loading a reference assembly for execution is an error
|
||||
try {
|
||||
var an = new AssemblyName ("TestingReferenceAssembly");
|
||||
var a = Assembly.Load (an);
|
||||
} catch (BadImageFormatException exn) {
|
||||
//Console.Error.WriteLine ("exn was {0}", exn);
|
||||
return 0;
|
||||
} catch (FileNotFoundException exn) {
|
||||
Console.Error.WriteLine ("incorrect exn was {0}", exn);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int test_0_reflection_load_reference ()
|
||||
{
|
||||
// Check that reflection-only loading a reference assembly is okay
|
||||
var an = new AssemblyName ("TestingReferenceAssembly");
|
||||
var a = Assembly.ReflectionOnlyLoad (an.FullName);
|
||||
var t = a.GetType ("X");
|
||||
var f = t.GetField ("Y");
|
||||
if (f.FieldType.Equals (typeof (Int32)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int test_0_load_reference_asm_via_reference ()
|
||||
{
|
||||
// Check that loading an assembly that references a reference assembly doesn't succeed.
|
||||
var an = new AssemblyName ("TestingReferenceReferenceAssembly");
|
||||
try {
|
||||
var a = Assembly.Load (an);
|
||||
var t = a.GetType ("Z");
|
||||
} catch (FileNotFoundException){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int test_0_reflection_load_reference_asm_via_reference ()
|
||||
{
|
||||
// Check that reflection-only loading an assembly that
|
||||
// references a reference assembly is okay.
|
||||
var an = new AssemblyName ("TestingReferenceReferenceAssembly");
|
||||
var a = Assembly.ReflectionOnlyLoad (an.FullName);
|
||||
var t = a.GetType ("Z");
|
||||
var f = t.GetField ("Y");
|
||||
if (f.FieldType.Equals (typeof (Int32)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public static int test_0_load_reference_bytes ()
|
||||
{
|
||||
// Check that loading a reference assembly from a byte array for execution is an error
|
||||
byte[] bs = File.ReadAllBytes ("./TestingReferenceAssembly.dll");
|
||||
try {
|
||||
var a = Assembly.Load (bs);
|
||||
} catch (BadImageFormatException) {
|
||||
return 0;
|
||||
} catch (FileNotFoundException exn) {
|
||||
Console.Error.WriteLine ("incorrect exn was {0}", exn);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int test_0_reflection_load_reference_bytes ()
|
||||
{
|
||||
// Check that loading a reference assembly from a byte
|
||||
// array for reflection only is okay.
|
||||
byte[] bs = File.ReadAllBytes ("./TestingReferenceAssembly.dll");
|
||||
var a = Assembly.ReflectionOnlyLoad (bs);
|
||||
var t = a.GetType ("X");
|
||||
var f = t.GetField ("Y");
|
||||
if (f.FieldType.Equals (typeof (Int32)))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
@ -74,11 +74,11 @@ worker (void *arg)
|
||||
break;
|
||||
case STATE_OUT:
|
||||
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
|
||||
result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
|
||||
result = mono_lls_find (&lls, hp, i);
|
||||
assert (!result);
|
||||
mono_hazard_pointer_clear_all (hp, -1);
|
||||
|
||||
result = mono_lls_insert (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
|
||||
result = mono_lls_insert (&lls, hp, &nodes [i].node);
|
||||
mono_hazard_pointer_clear_all (hp, -1);
|
||||
|
||||
assert (nodes [i].state == STATE_BUSY);
|
||||
@ -89,12 +89,12 @@ worker (void *arg)
|
||||
break;
|
||||
case STATE_IN:
|
||||
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
|
||||
result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
|
||||
result = mono_lls_find (&lls, hp, i);
|
||||
assert (result);
|
||||
assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
|
||||
mono_hazard_pointer_clear_all (hp, -1);
|
||||
|
||||
result = mono_lls_remove (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
|
||||
result = mono_lls_remove (&lls, hp, &nodes [i].node);
|
||||
mono_hazard_pointer_clear_all (hp, -1);
|
||||
|
||||
++thread_data->num_removes;
|
||||
@ -126,7 +126,7 @@ main (int argc, char *argv [])
|
||||
|
||||
mono_threads_init (&thread_callbacks, 0);
|
||||
|
||||
mono_lls_init (&lls, free_node, HAZARD_FREE_NO_LOCK);
|
||||
mono_lls_init (&lls, free_node);
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
nodes [i].node.key = i;
|
||||
|
@ -126,6 +126,7 @@ monoutils_sources = \
|
||||
atomic.c \
|
||||
mono-hwcap.h \
|
||||
mono-hwcap.c \
|
||||
mono-hwcap-vars.h \
|
||||
bsearch.h \
|
||||
bsearch.c \
|
||||
mono-signal-handler.h \
|
||||
@ -176,48 +177,56 @@ arch_sources += mach-support-unknown.c
|
||||
|
||||
endif
|
||||
|
||||
if !CROSS_COMPILE
|
||||
|
||||
if X86
|
||||
arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
|
||||
arch_sources += mono-hwcap-x86.c
|
||||
endif
|
||||
|
||||
if AMD64
|
||||
arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
|
||||
arch_sources += mono-hwcap-x86.c
|
||||
endif
|
||||
|
||||
if ARM
|
||||
arch_sources += mono-hwcap-arm.c mono-hwcap-arm.h
|
||||
arch_sources += mono-hwcap-arm.c
|
||||
endif
|
||||
|
||||
if ARM64
|
||||
arch_sources += mono-hwcap-arm64.c mono-hwcap-arm64.h
|
||||
arch_sources += mono-hwcap-arm64.c
|
||||
endif
|
||||
|
||||
if MIPS
|
||||
arch_sources += mono-hwcap-mips.c mono-hwcap-mips.h
|
||||
arch_sources += mono-hwcap-mips.c
|
||||
endif
|
||||
|
||||
if POWERPC
|
||||
arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
|
||||
arch_sources += mono-hwcap-ppc.c
|
||||
endif
|
||||
|
||||
if POWERPC64
|
||||
arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
|
||||
arch_sources += mono-hwcap-ppc.c
|
||||
endif
|
||||
|
||||
if SPARC
|
||||
arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
|
||||
arch_sources += mono-hwcap-sparc.c
|
||||
endif
|
||||
|
||||
if SPARC64
|
||||
arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
|
||||
arch_sources += mono-hwcap-sparc.c
|
||||
endif
|
||||
|
||||
if IA64
|
||||
arch_sources += mono-hwcap-ia64.c mono-hwcap-ia64.h
|
||||
arch_sources += mono-hwcap-ia64.c
|
||||
endif
|
||||
|
||||
if S390X
|
||||
arch_sources += mono-hwcap-s390x.c mono-hwcap-s390x.h
|
||||
arch_sources += mono-hwcap-s390x.c
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
arch_sources += mono-hwcap-cross.c
|
||||
|
||||
endif
|
||||
|
||||
libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources)
|
||||
|
@ -85,17 +85,18 @@ target_triplet = @target@
|
||||
@ARM_TRUE@@CROSS_COMPILE_FALSE@am__append_3 = mach-support-arm.c
|
||||
@ARM64_TRUE@@CROSS_COMPILE_FALSE@am__append_4 = mach-support-arm64.c
|
||||
@CROSS_COMPILE_TRUE@am__append_5 = mach-support-unknown.c
|
||||
@X86_TRUE@am__append_6 = mono-hwcap-x86.c mono-hwcap-x86.h
|
||||
@AMD64_TRUE@am__append_7 = mono-hwcap-x86.c mono-hwcap-x86.h
|
||||
@ARM_TRUE@am__append_8 = mono-hwcap-arm.c mono-hwcap-arm.h
|
||||
@ARM64_TRUE@am__append_9 = mono-hwcap-arm64.c mono-hwcap-arm64.h
|
||||
@MIPS_TRUE@am__append_10 = mono-hwcap-mips.c mono-hwcap-mips.h
|
||||
@POWERPC_TRUE@am__append_11 = mono-hwcap-ppc.c mono-hwcap-ppc.h
|
||||
@POWERPC64_TRUE@am__append_12 = mono-hwcap-ppc.c mono-hwcap-ppc.h
|
||||
@SPARC_TRUE@am__append_13 = mono-hwcap-sparc.c mono-hwcap-sparc.h
|
||||
@SPARC64_TRUE@am__append_14 = mono-hwcap-sparc.c mono-hwcap-sparc.h
|
||||
@IA64_TRUE@am__append_15 = mono-hwcap-ia64.c mono-hwcap-ia64.h
|
||||
@S390X_TRUE@am__append_16 = mono-hwcap-s390x.c mono-hwcap-s390x.h
|
||||
@CROSS_COMPILE_FALSE@@X86_TRUE@am__append_6 = mono-hwcap-x86.c
|
||||
@AMD64_TRUE@@CROSS_COMPILE_FALSE@am__append_7 = mono-hwcap-x86.c
|
||||
@ARM_TRUE@@CROSS_COMPILE_FALSE@am__append_8 = mono-hwcap-arm.c
|
||||
@ARM64_TRUE@@CROSS_COMPILE_FALSE@am__append_9 = mono-hwcap-arm64.c
|
||||
@CROSS_COMPILE_FALSE@@MIPS_TRUE@am__append_10 = mono-hwcap-mips.c
|
||||
@CROSS_COMPILE_FALSE@@POWERPC_TRUE@am__append_11 = mono-hwcap-ppc.c
|
||||
@CROSS_COMPILE_FALSE@@POWERPC64_TRUE@am__append_12 = mono-hwcap-ppc.c
|
||||
@CROSS_COMPILE_FALSE@@SPARC_TRUE@am__append_13 = mono-hwcap-sparc.c
|
||||
@CROSS_COMPILE_FALSE@@SPARC64_TRUE@am__append_14 = mono-hwcap-sparc.c
|
||||
@CROSS_COMPILE_FALSE@@IA64_TRUE@am__append_15 = mono-hwcap-ia64.c
|
||||
@CROSS_COMPILE_FALSE@@S390X_TRUE@am__append_16 = mono-hwcap-s390x.c
|
||||
@CROSS_COMPILE_TRUE@am__append_17 = mono-hwcap-cross.c
|
||||
subdir = mono/utils
|
||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
|
||||
@ -155,20 +156,17 @@ am__libmonoutils_la_SOURCES_DIST = mono-md5.c mono-sha1.c \
|
||||
mono-threads-posix-abort-syscall.c \
|
||||
mono-threads-windows-abort-syscall.c mono-tls.h mono-tls.c \
|
||||
linux_magic.h mono-memory-model.h atomic.h atomic.c \
|
||||
mono-hwcap.h mono-hwcap.c bsearch.h bsearch.c \
|
||||
mono-signal-handler.h mono-conc-hashtable.h \
|
||||
mono-hwcap.h mono-hwcap.c mono-hwcap-vars.h bsearch.h \
|
||||
bsearch.c mono-signal-handler.h mono-conc-hashtable.h \
|
||||
mono-conc-hashtable.c sha1.h sha1.c json.h json.c networking.c \
|
||||
networking-posix.c networking-fallback.c networking-missing.c \
|
||||
networking-windows.c networking.h mono-rand.c mono-rand.h \
|
||||
memfuncs.c memfuncs.h parse.c parse.h checked-build.c \
|
||||
checked-build.h mach-support-x86.c mach-support-amd64.c \
|
||||
mach-support-arm.c mach-support-arm64.c mach-support-unknown.c \
|
||||
mono-hwcap-x86.c mono-hwcap-x86.h mono-hwcap-arm.c \
|
||||
mono-hwcap-arm.h mono-hwcap-arm64.c mono-hwcap-arm64.h \
|
||||
mono-hwcap-mips.c mono-hwcap-mips.h mono-hwcap-ppc.c \
|
||||
mono-hwcap-ppc.h mono-hwcap-sparc.c mono-hwcap-sparc.h \
|
||||
mono-hwcap-ia64.c mono-hwcap-ia64.h mono-hwcap-s390x.c \
|
||||
mono-hwcap-s390x.h
|
||||
mono-hwcap-x86.c mono-hwcap-arm.c mono-hwcap-arm64.c \
|
||||
mono-hwcap-mips.c mono-hwcap-ppc.c mono-hwcap-sparc.c \
|
||||
mono-hwcap-ia64.c mono-hwcap-s390x.c mono-hwcap-cross.c
|
||||
am__objects_1 = mono-md5.lo mono-sha1.lo mono-logger.lo \
|
||||
mono-codeman.lo dlmalloc.lo mono-counters.lo mono-dl.lo \
|
||||
mono-dl-windows.lo mono-dl-darwin.lo mono-dl-posix.lo \
|
||||
@ -201,24 +199,27 @@ am__objects_1 = mono-md5.lo mono-sha1.lo mono-logger.lo \
|
||||
@ARM64_TRUE@@CROSS_COMPILE_FALSE@am__objects_5 = \
|
||||
@ARM64_TRUE@@CROSS_COMPILE_FALSE@ mach-support-arm64.lo
|
||||
@CROSS_COMPILE_TRUE@am__objects_6 = mach-support-unknown.lo
|
||||
@X86_TRUE@am__objects_7 = mono-hwcap-x86.lo
|
||||
@AMD64_TRUE@am__objects_8 = mono-hwcap-x86.lo
|
||||
@ARM_TRUE@am__objects_9 = mono-hwcap-arm.lo
|
||||
@ARM64_TRUE@am__objects_10 = mono-hwcap-arm64.lo
|
||||
@MIPS_TRUE@am__objects_11 = mono-hwcap-mips.lo
|
||||
@POWERPC_TRUE@am__objects_12 = mono-hwcap-ppc.lo
|
||||
@POWERPC64_TRUE@am__objects_13 = mono-hwcap-ppc.lo
|
||||
@SPARC_TRUE@am__objects_14 = mono-hwcap-sparc.lo
|
||||
@SPARC64_TRUE@am__objects_15 = mono-hwcap-sparc.lo
|
||||
@IA64_TRUE@am__objects_16 = mono-hwcap-ia64.lo
|
||||
@S390X_TRUE@am__objects_17 = mono-hwcap-s390x.lo
|
||||
am__objects_18 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
|
||||
@CROSS_COMPILE_FALSE@@X86_TRUE@am__objects_7 = mono-hwcap-x86.lo
|
||||
@AMD64_TRUE@@CROSS_COMPILE_FALSE@am__objects_8 = mono-hwcap-x86.lo
|
||||
@ARM_TRUE@@CROSS_COMPILE_FALSE@am__objects_9 = mono-hwcap-arm.lo
|
||||
@ARM64_TRUE@@CROSS_COMPILE_FALSE@am__objects_10 = mono-hwcap-arm64.lo
|
||||
@CROSS_COMPILE_FALSE@@MIPS_TRUE@am__objects_11 = mono-hwcap-mips.lo
|
||||
@CROSS_COMPILE_FALSE@@POWERPC_TRUE@am__objects_12 = mono-hwcap-ppc.lo
|
||||
@CROSS_COMPILE_FALSE@@POWERPC64_TRUE@am__objects_13 = \
|
||||
@CROSS_COMPILE_FALSE@@POWERPC64_TRUE@ mono-hwcap-ppc.lo
|
||||
@CROSS_COMPILE_FALSE@@SPARC_TRUE@am__objects_14 = mono-hwcap-sparc.lo
|
||||
@CROSS_COMPILE_FALSE@@SPARC64_TRUE@am__objects_15 = \
|
||||
@CROSS_COMPILE_FALSE@@SPARC64_TRUE@ mono-hwcap-sparc.lo
|
||||
@CROSS_COMPILE_FALSE@@IA64_TRUE@am__objects_16 = mono-hwcap-ia64.lo
|
||||
@CROSS_COMPILE_FALSE@@S390X_TRUE@am__objects_17 = mono-hwcap-s390x.lo
|
||||
@CROSS_COMPILE_TRUE@am__objects_18 = mono-hwcap-cross.lo
|
||||
am__objects_19 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
|
||||
$(am__objects_5) $(am__objects_6) $(am__objects_7) \
|
||||
$(am__objects_8) $(am__objects_9) $(am__objects_10) \
|
||||
$(am__objects_11) $(am__objects_12) $(am__objects_13) \
|
||||
$(am__objects_14) $(am__objects_15) $(am__objects_16) \
|
||||
$(am__objects_17)
|
||||
am_libmonoutils_la_OBJECTS = $(am__objects_1) $(am__objects_18)
|
||||
$(am__objects_17) $(am__objects_18)
|
||||
am_libmonoutils_la_OBJECTS = $(am__objects_1) $(am__objects_19)
|
||||
libmonoutils_la_OBJECTS = $(am_libmonoutils_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -630,6 +631,7 @@ monoutils_sources = \
|
||||
atomic.c \
|
||||
mono-hwcap.h \
|
||||
mono-hwcap.c \
|
||||
mono-hwcap-vars.h \
|
||||
bsearch.h \
|
||||
bsearch.c \
|
||||
mono-signal-handler.h \
|
||||
@ -659,7 +661,7 @@ arch_sources = $(am__append_1) $(am__append_2) $(am__append_3) \
|
||||
$(am__append_7) $(am__append_8) $(am__append_9) \
|
||||
$(am__append_10) $(am__append_11) $(am__append_12) \
|
||||
$(am__append_13) $(am__append_14) $(am__append_15) \
|
||||
$(am__append_16)
|
||||
$(am__append_16) $(am__append_17)
|
||||
libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources)
|
||||
libmonoutilsincludedir = $(includedir)/mono-$(API_VER)/mono/utils
|
||||
libmonoutilsinclude_HEADERS = \
|
||||
@ -754,6 +756,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-filemap.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-arm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-arm64.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-cross.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-ia64.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-mips.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mono-hwcap-ppc.Plo@am__quote@
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <mono/utils/mono-membar.h>
|
||||
|
||||
/*
|
||||
The current Nexus 7 arm-v7a fails with:
|
||||
@ -29,7 +30,6 @@ Apple targets have historically being problematic, xcode 4.6 would miscompile th
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <mono/utils/mono-membar.h>
|
||||
|
||||
/* mingw is missing InterlockedCompareExchange64 () from winbase.h */
|
||||
#if HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64==0
|
||||
@ -180,30 +180,63 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
|
||||
/* Prefer GCC atomic ops if the target supports it (see configure.ac). */
|
||||
#elif defined(USE_GCC_ATOMIC_OPS)
|
||||
|
||||
/*
|
||||
* As of this comment (August 2016), all current Clang versions get atomic
|
||||
* intrinsics on ARM64 wrong. All GCC versions prior to 5.3.0 do, too. The bug
|
||||
* is the same: The compiler developers thought that the acq + rel barriers
|
||||
* that ARM64 load/store instructions can impose are sufficient to provide
|
||||
* sequential consistency semantics. This is not the case:
|
||||
*
|
||||
* http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229588.html
|
||||
*
|
||||
* We work around this bug by inserting full barriers around each atomic
|
||||
* intrinsic if we detect that we're built with a buggy compiler.
|
||||
*/
|
||||
|
||||
#if defined (HOST_ARM64) && (defined (__clang__) || MONO_GNUC_VERSION < 50300)
|
||||
#define WRAP_ATOMIC_INTRINSIC(INTRIN) \
|
||||
({ \
|
||||
mono_memory_barrier (); \
|
||||
__typeof__ (INTRIN) atomic_ret__ = (INTRIN); \
|
||||
mono_memory_barrier (); \
|
||||
atomic_ret__; \
|
||||
})
|
||||
|
||||
#define gcc_sync_val_compare_and_swap(a, b, c) WRAP_ATOMIC_INTRINSIC (__sync_val_compare_and_swap (a, b, c))
|
||||
#define gcc_sync_add_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_add_and_fetch (a, b))
|
||||
#define gcc_sync_sub_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_sub_and_fetch (a, b))
|
||||
#define gcc_sync_fetch_and_add(a, b) WRAP_ATOMIC_INTRINSIC (__sync_fetch_and_add (a, b))
|
||||
#else
|
||||
#define gcc_sync_val_compare_and_swap(a, b, c) __sync_val_compare_and_swap (a, b, c)
|
||||
#define gcc_sync_add_and_fetch(a, b) __sync_add_and_fetch (a, b)
|
||||
#define gcc_sync_sub_and_fetch(a, b) __sync_sub_and_fetch (a, b)
|
||||
#define gcc_sync_fetch_and_add(a, b) __sync_fetch_and_add (a, b)
|
||||
#endif
|
||||
|
||||
static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
|
||||
gint32 exch, gint32 comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap (dest, comp, exch);
|
||||
return gcc_sync_val_compare_and_swap (dest, comp, exch);
|
||||
}
|
||||
|
||||
static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap (dest, comp, exch);
|
||||
return gcc_sync_val_compare_and_swap (dest, comp, exch);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
|
||||
{
|
||||
return __sync_add_and_fetch (dest, add);
|
||||
return gcc_sync_add_and_fetch (dest, add);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedIncrement(volatile gint32 *val)
|
||||
{
|
||||
return __sync_add_and_fetch (val, 1);
|
||||
return gcc_sync_add_and_fetch (val, 1);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedDecrement(volatile gint32 *val)
|
||||
{
|
||||
return __sync_sub_and_fetch (val, 1);
|
||||
return gcc_sync_sub_and_fetch (val, 1);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
|
||||
@ -211,7 +244,7 @@ static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
|
||||
gint32 old_val;
|
||||
do {
|
||||
old_val = *val;
|
||||
} while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
|
||||
} while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
|
||||
return old_val;
|
||||
}
|
||||
|
||||
@ -221,30 +254,30 @@ static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
|
||||
gpointer old_val;
|
||||
do {
|
||||
old_val = *val;
|
||||
} while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
|
||||
} while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
|
||||
return old_val;
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
|
||||
{
|
||||
return __sync_fetch_and_add (val, add);
|
||||
return gcc_sync_fetch_and_add (val, add);
|
||||
}
|
||||
|
||||
static inline gint8 InterlockedRead8(volatile gint8 *src)
|
||||
{
|
||||
/* Kind of a hack, but GCC doesn't give us anything better, and it's
|
||||
* certainly not as bad as using a CAS loop. */
|
||||
return __sync_fetch_and_add (src, 0);
|
||||
return gcc_sync_fetch_and_add (src, 0);
|
||||
}
|
||||
|
||||
static inline gint16 InterlockedRead16(volatile gint16 *src)
|
||||
{
|
||||
return __sync_fetch_and_add (src, 0);
|
||||
return gcc_sync_fetch_and_add (src, 0);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedRead(volatile gint32 *src)
|
||||
{
|
||||
return __sync_fetch_and_add (src, 0);
|
||||
return gcc_sync_fetch_and_add (src, 0);
|
||||
}
|
||||
|
||||
static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
|
||||
@ -253,7 +286,7 @@ static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
|
||||
gint8 old_val;
|
||||
do {
|
||||
old_val = *dst;
|
||||
} while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
} while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
}
|
||||
|
||||
static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
|
||||
@ -261,7 +294,7 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
|
||||
gint16 old_val;
|
||||
do {
|
||||
old_val = *dst;
|
||||
} while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
} while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
}
|
||||
|
||||
static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
|
||||
@ -270,7 +303,7 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
|
||||
gint32 old_val;
|
||||
do {
|
||||
old_val = *dst;
|
||||
} while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
} while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
|
||||
}
|
||||
|
||||
#if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__)) || (defined (__sparc__) && !defined (__arch64__))
|
||||
@ -281,33 +314,33 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
|
||||
|
||||
static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap (dest, comp, exch);
|
||||
return gcc_sync_val_compare_and_swap (dest, comp, exch);
|
||||
}
|
||||
|
||||
static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
|
||||
{
|
||||
return __sync_add_and_fetch (dest, add);
|
||||
return gcc_sync_add_and_fetch (dest, add);
|
||||
}
|
||||
|
||||
static inline gint64 InterlockedIncrement64(volatile gint64 *val)
|
||||
{
|
||||
return __sync_add_and_fetch (val, 1);
|
||||
return gcc_sync_add_and_fetch (val, 1);
|
||||
}
|
||||
|
||||
static inline gint64 InterlockedDecrement64(volatile gint64 *val)
|
||||
{
|
||||
return __sync_sub_and_fetch (val, 1);
|
||||
return gcc_sync_sub_and_fetch (val, 1);
|
||||
}
|
||||
|
||||
static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
|
||||
{
|
||||
return __sync_fetch_and_add (val, add);
|
||||
return gcc_sync_fetch_and_add (val, add);
|
||||
}
|
||||
|
||||
static inline gint64 InterlockedRead64(volatile gint64 *src)
|
||||
{
|
||||
/* Kind of a hack, but GCC doesn't give us anything better. */
|
||||
return __sync_fetch_and_add (src, 0);
|
||||
return gcc_sync_fetch_and_add (src, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -393,122 +426,6 @@ static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
|
||||
InterlockedExchange64 (dst, val);
|
||||
}
|
||||
|
||||
#elif defined(__ia64__)
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
static inline gint32 InterlockedCompareExchange(gint32 volatile *dest,
|
||||
gint32 exch, gint32 comp)
|
||||
{
|
||||
gint32 old;
|
||||
guint64 real_comp;
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
old = _InterlockedCompareExchange (dest, exch, comp);
|
||||
#else
|
||||
/* cmpxchg4 zero extends the value read from memory */
|
||||
real_comp = (guint64)(guint32)comp;
|
||||
asm volatile ("mov ar.ccv = %2 ;;\n\t"
|
||||
"cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t"
|
||||
: "=r" (old) : "r" (dest), "r" (real_comp), "r" (exch));
|
||||
#endif
|
||||
|
||||
return(old);
|
||||
}
|
||||
|
||||
static inline gpointer InterlockedCompareExchangePointer(gpointer volatile *dest,
|
||||
gpointer exch, gpointer comp)
|
||||
{
|
||||
gpointer old;
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
old = _InterlockedCompareExchangePointer (dest, exch, comp);
|
||||
#else
|
||||
asm volatile ("mov ar.ccv = %2 ;;\n\t"
|
||||
"cmpxchg8.acq %0 = [%1], %3, ar.ccv\n\t"
|
||||
: "=r" (old) : "r" (dest), "r" (comp), "r" (exch));
|
||||
#endif
|
||||
|
||||
return(old);
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedIncrement(gint32 volatile *val)
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
return _InterlockedIncrement (val);
|
||||
#else
|
||||
gint32 old;
|
||||
|
||||
do {
|
||||
old = *val;
|
||||
} while (InterlockedCompareExchange (val, old + 1, old) != old);
|
||||
|
||||
return old + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedDecrement(gint32 volatile *val)
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
return _InterlockedDecrement (val);
|
||||
#else
|
||||
gint32 old;
|
||||
|
||||
do {
|
||||
old = *val;
|
||||
} while (InterlockedCompareExchange (val, old - 1, old) != old);
|
||||
|
||||
return old - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedExchange(gint32 volatile *dest, gint32 new_val)
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
return _InterlockedExchange (dest, new_val);
|
||||
#else
|
||||
gint32 res;
|
||||
|
||||
do {
|
||||
res = *dest;
|
||||
} while (InterlockedCompareExchange (dest, new_val, res) != res);
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline gpointer InterlockedExchangePointer(gpointer volatile *dest, gpointer new_val)
|
||||
{
|
||||
#ifdef __INTEL_COMPILER
|
||||
return (gpointer)_InterlockedExchange64 ((gint64*)dest, (gint64)new_val);
|
||||
#else
|
||||
gpointer res;
|
||||
|
||||
do {
|
||||
res = *dest;
|
||||
} while (InterlockedCompareExchangePointer (dest, new_val, res) != res);
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
|
||||
{
|
||||
gint32 old;
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
old = _InterlockedExchangeAdd (val, add);
|
||||
#else
|
||||
do {
|
||||
old = *val;
|
||||
} while (InterlockedCompareExchange (val, old + add, old) != old);
|
||||
|
||||
return old;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define WAPI_NO_ATOMIC_ASM
|
||||
|
@ -29,7 +29,6 @@
|
||||
typedef struct {
|
||||
gpointer p;
|
||||
MonoHazardousFreeFunc free_func;
|
||||
HazardFreeLocking locking;
|
||||
} DelayedFreeItem;
|
||||
|
||||
/* The hazard table */
|
||||
@ -191,7 +190,7 @@ mono_hazard_pointer_get (void)
|
||||
mono_jit_info_table_add(), which doesn't have to care about hazards
|
||||
because it holds the respective domain lock. */
|
||||
gpointer
|
||||
get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
|
||||
mono_get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
|
||||
{
|
||||
gpointer p;
|
||||
|
||||
@ -287,26 +286,6 @@ mono_hazard_pointer_restore_for_signal_handler (int small_id)
|
||||
overflow_busy [small_id] = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
try_free_delayed_free_item (HazardFreeContext context)
|
||||
{
|
||||
DelayedFreeItem item;
|
||||
gboolean popped = mono_lock_free_array_queue_pop (&delayed_free_queue, &item);
|
||||
|
||||
if (!popped)
|
||||
return FALSE;
|
||||
|
||||
if ((context == HAZARD_FREE_ASYNC_CTX && item.locking == HAZARD_FREE_MAY_LOCK) ||
|
||||
(is_pointer_hazardous (item.p))) {
|
||||
mono_lock_free_array_queue_push (&delayed_free_queue, &item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
item.free_func (item.p);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* mono_thread_hazardous_try_free:
|
||||
* @p: the pointer to free
|
||||
@ -348,7 +327,7 @@ mono_thread_hazardous_try_free (gpointer p, MonoHazardousFreeFunc free_func)
|
||||
void
|
||||
mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func)
|
||||
{
|
||||
DelayedFreeItem item = { p, free_func, HAZARD_FREE_MAY_LOCK };
|
||||
DelayedFreeItem item = { p, free_func };
|
||||
|
||||
InterlockedIncrement (&hazardous_pointer_count);
|
||||
|
||||
@ -366,19 +345,48 @@ mono_hazard_pointer_install_free_queue_size_callback (MonoHazardFreeQueueSizeCal
|
||||
queue_size_cb = cb;
|
||||
}
|
||||
|
||||
static void
|
||||
try_free_delayed_free_items (guint32 limit)
|
||||
{
|
||||
GArray *hazardous = NULL;
|
||||
DelayedFreeItem item;
|
||||
guint32 freed = 0;
|
||||
|
||||
// Free all the items we can and re-add the ones we can't to the queue.
|
||||
while (mono_lock_free_array_queue_pop (&delayed_free_queue, &item)) {
|
||||
if (is_pointer_hazardous (item.p)) {
|
||||
if (!hazardous)
|
||||
hazardous = g_array_sized_new (FALSE, FALSE, sizeof (DelayedFreeItem), delayed_free_queue.num_used_entries);
|
||||
|
||||
g_array_append_val (hazardous, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
item.free_func (item.p);
|
||||
freed++;
|
||||
|
||||
if (limit && freed == limit)
|
||||
break;
|
||||
}
|
||||
|
||||
if (hazardous) {
|
||||
for (gint i = 0; i < hazardous->len; i++)
|
||||
mono_lock_free_array_queue_push (&delayed_free_queue, &g_array_index (hazardous, DelayedFreeItem, i));
|
||||
|
||||
g_array_free (hazardous, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mono_thread_hazardous_try_free_all (void)
|
||||
{
|
||||
while (try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX))
|
||||
;
|
||||
try_free_delayed_free_items (0);
|
||||
}
|
||||
|
||||
void
|
||||
mono_thread_hazardous_try_free_some (void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i)
|
||||
try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX);
|
||||
try_free_delayed_free_items (10);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -20,23 +20,13 @@ typedef struct {
|
||||
|
||||
typedef void (*MonoHazardousFreeFunc) (gpointer p);
|
||||
|
||||
typedef enum {
|
||||
HAZARD_FREE_MAY_LOCK,
|
||||
HAZARD_FREE_NO_LOCK,
|
||||
} HazardFreeLocking;
|
||||
|
||||
typedef enum {
|
||||
HAZARD_FREE_SAFE_CTX,
|
||||
HAZARD_FREE_ASYNC_CTX,
|
||||
} HazardFreeContext;
|
||||
|
||||
MONO_API gboolean mono_thread_hazardous_try_free (gpointer p, MonoHazardousFreeFunc free_func);
|
||||
void mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func);
|
||||
MONO_API void mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func);
|
||||
|
||||
void mono_thread_hazardous_try_free_all (void);
|
||||
MONO_API void mono_thread_hazardous_try_free_all (void);
|
||||
void mono_thread_hazardous_try_free_some (void);
|
||||
MonoThreadHazardPointers* mono_hazard_pointer_get (void);
|
||||
gpointer get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
|
||||
MONO_API MonoThreadHazardPointers* mono_hazard_pointer_get (void);
|
||||
gpointer mono_get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
|
||||
|
||||
#define mono_hazard_pointer_set(hp,i,v) \
|
||||
do { g_assert ((i) >= 0 && (i) < HAZARD_POINTER_COUNT); \
|
||||
|
@ -170,7 +170,7 @@ desc_alloc (void)
|
||||
for (;;) {
|
||||
gboolean success;
|
||||
|
||||
desc = (Descriptor *) get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
|
||||
desc = (Descriptor *) mono_get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
|
||||
if (desc) {
|
||||
Descriptor *next = desc->next;
|
||||
success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc);
|
||||
|
@ -133,7 +133,7 @@ mono_lock_free_queue_enqueue (MonoLockFreeQueue *q, MonoLockFreeQueueNode *node)
|
||||
for (;;) {
|
||||
MonoLockFreeQueueNode *next;
|
||||
|
||||
tail = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->tail, hp, 0);
|
||||
tail = (MonoLockFreeQueueNode *) mono_get_hazardous_pointer ((gpointer volatile*)&q->tail, hp, 0);
|
||||
mono_memory_read_barrier ();
|
||||
/*
|
||||
* We never dereference next so we don't need a
|
||||
@ -243,7 +243,7 @@ mono_lock_free_queue_dequeue (MonoLockFreeQueue *q)
|
||||
for (;;) {
|
||||
MonoLockFreeQueueNode *tail, *next;
|
||||
|
||||
head = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->head, hp, 0);
|
||||
head = (MonoLockFreeQueueNode *) mono_get_hazardous_pointer ((gpointer volatile*)&q->head, hp, 0);
|
||||
tail = (MonoLockFreeQueueNode*)q->tail;
|
||||
mono_memory_read_barrier ();
|
||||
next = head->next;
|
||||
|
@ -303,5 +303,9 @@ typedef SSIZE_T ssize_t;
|
||||
#define MONO_COLD
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
|
||||
#define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#endif
|
||||
|
||||
#endif /* __UTILS_MONO_COMPILER_H__*/
|
||||
|
||||
|
@ -164,7 +164,7 @@ mono_conc_hashtable_lookup (MonoConcurrentHashTable *hash_table, gpointer key)
|
||||
hp = mono_hazard_pointer_get ();
|
||||
|
||||
retry:
|
||||
table = (conc_table *)get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
|
||||
table = (conc_table *)mono_get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
|
||||
table_mask = table->table_size - 1;
|
||||
kvs = table->kvs;
|
||||
i = hash & table_mask;
|
||||
|
@ -19,7 +19,7 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-arm.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#if defined(HAVE_SYS_AUXV_H) && !defined(PLATFORM_ANDROID)
|
||||
#include <sys/auxv.h>
|
||||
@ -34,15 +34,6 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
gboolean mono_hwcap_arm_is_v5 = FALSE;
|
||||
gboolean mono_hwcap_arm_is_v6 = FALSE;
|
||||
gboolean mono_hwcap_arm_is_v7 = FALSE;
|
||||
gboolean mono_hwcap_arm_has_vfp = FALSE;
|
||||
gboolean mono_hwcap_arm_has_vfp3 = FALSE;
|
||||
gboolean mono_hwcap_arm_has_vfp3_d16 = FALSE;
|
||||
gboolean mono_hwcap_arm_has_thumb = FALSE;
|
||||
gboolean mono_hwcap_arm_has_thumb2 = FALSE;
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
@ -202,16 +193,3 @@ mono_hwcap_arch_init (void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print(FILE *f)
|
||||
{
|
||||
g_fprintf (f, "mono_hwcap_arm_is_v5 = %i\n", mono_hwcap_arm_is_v5);
|
||||
g_fprintf (f, "mono_hwcap_arm_is_v6 = %i\n", mono_hwcap_arm_is_v6);
|
||||
g_fprintf (f, "mono_hwcap_arm_is_v7 = %i\n", mono_hwcap_arm_is_v7);
|
||||
g_fprintf (f, "mono_hwcap_arm_has_vfp = %i\n", mono_hwcap_arm_has_vfp);
|
||||
g_fprintf (f, "mono_hwcap_arm_has_vfp3 = %i\n", mono_hwcap_arm_has_vfp3);
|
||||
g_fprintf (f, "mono_hwcap_arm_has_vfp3_d16 = %i\n", mono_hwcap_arm_has_vfp3_d16);
|
||||
g_fprintf (f, "mono_hwcap_arm_has_thumb = %i\n", mono_hwcap_arm_has_thumb);
|
||||
g_fprintf (f, "mono_hwcap_arm_has_thumb2 = %i\n", mono_hwcap_arm_has_thumb2);
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_ARM_H__
|
||||
#define __MONO_UTILS_HWCAP_ARM_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
extern gboolean mono_hwcap_arm_is_v5;
|
||||
extern gboolean mono_hwcap_arm_is_v6;
|
||||
extern gboolean mono_hwcap_arm_is_v7;
|
||||
extern gboolean mono_hwcap_arm_has_vfp;
|
||||
extern gboolean mono_hwcap_arm_has_vfp3;
|
||||
extern gboolean mono_hwcap_arm_has_vfp3_d16;
|
||||
extern gboolean mono_hwcap_arm_has_thumb;
|
||||
extern gboolean mono_hwcap_arm_has_thumb2;
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_ARM_H__ */
|
@ -1,25 +1,13 @@
|
||||
/*
|
||||
* mono-hwcap-arm64.c: ARM hardware feature detection
|
||||
* mono-hwcap-arm64.c: ARM64 hardware feature detection
|
||||
*
|
||||
* Copyright 2013 Xamarin Inc
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-arm64.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#if defined(MONO_CROSS_COMPILE)
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mono_hwcap_print(FILE *f)
|
||||
{
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_ARM64_H__
|
||||
#define __MONO_UTILS_HWCAP_ARM64_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#endif
|
16
mono/utils/mono-hwcap-cross.c
Normal file
16
mono/utils/mono-hwcap-cross.c
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* mono-hwcap-cross.c: No-op hardware feature detection
|
||||
*
|
||||
* Author:
|
||||
* Alex Rønne Petersen (alexrp@xamarin.com)
|
||||
*
|
||||
* Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
}
|
@ -19,15 +19,9 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-ia64.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
/* Nothing needed here yet. */
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE *f)
|
||||
{
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_IA64_H__
|
||||
#define __MONO_UTILS_HWCAP_IA64_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
/* Nothing needed here yet. */
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_IA64_H__ */
|
@ -19,15 +19,9 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-mips.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
/* Nothing needed here yet. */
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE *f)
|
||||
{
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_MIPS_H__
|
||||
#define __MONO_UTILS_HWCAP_MIPS_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
/* Nothing needed here yet. */
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_MIPS_H__ */
|
@ -19,19 +19,13 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-ppc.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
|
||||
#include <string.h>
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
gboolean mono_hwcap_ppc_has_icache_snoop = FALSE;
|
||||
gboolean mono_hwcap_ppc_is_isa_2x = FALSE;
|
||||
gboolean mono_hwcap_ppc_is_isa_64 = FALSE;
|
||||
gboolean mono_hwcap_ppc_has_move_fpr_gpr = FALSE;
|
||||
gboolean mono_hwcap_ppc_has_multiple_ls_units = FALSE;
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
@ -66,13 +60,3 @@ mono_hwcap_arch_init (void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE* f)
|
||||
{
|
||||
g_fprintf (f, "mono_hwcap_ppc_has_icache_snoop = %i\n", mono_hwcap_ppc_has_icache_snoop);
|
||||
g_fprintf (f, "mono_hwcap_ppc_is_isa_2x = %i\n", mono_hwcap_ppc_is_isa_2x);
|
||||
g_fprintf (f, "mono_hwcap_ppc_is_isa_64 = %i\n", mono_hwcap_ppc_is_isa_64);
|
||||
g_fprintf (f, "mono_hwcap_ppc_has_move_fpr_gpr = %i\n", mono_hwcap_ppc_has_move_fpr_gpr);
|
||||
g_fprintf (f, "mono_hwcap_ppc_has_multiple_ls_units = %i\n", mono_hwcap_ppc_has_multiple_ls_units);
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_PPC_H__
|
||||
#define __MONO_UTILS_HWCAP_PPC_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
extern gboolean mono_hwcap_ppc_has_icache_snoop;
|
||||
extern gboolean mono_hwcap_ppc_is_isa_2x;
|
||||
extern gboolean mono_hwcap_ppc_is_isa_64;
|
||||
extern gboolean mono_hwcap_ppc_has_move_fpr_gpr;
|
||||
extern gboolean mono_hwcap_ppc_has_multiple_ls_units;
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_PPC_H__ */
|
@ -19,22 +19,117 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-s390x.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
facilityList_t facs;
|
||||
typedef struct {
|
||||
uint8_t n3:1; // 000 - N3 instructions
|
||||
uint8_t zi:1; // 001 - z/Arch installed
|
||||
uint8_t za:1; // 002 - z/Arch active
|
||||
uint8_t date:1; // 003 - DAT-enhancement
|
||||
uint8_t idtes:1; // 004 - IDTE-segment tables
|
||||
uint8_t idter:1; // 005 - IDTE-region tables
|
||||
uint8_t asnlx:1; // 006 - ASN-LX reuse
|
||||
uint8_t stfle:1; // 007 - STFLE
|
||||
uint8_t edat1:1; // 008 - EDAT 1
|
||||
uint8_t srs:1; // 009 - Sense-Running-Status
|
||||
uint8_t csske:1; // 010 - Conditional SSKE
|
||||
uint8_t ctf:1; // 011 - Configuration-topology
|
||||
uint8_t ibm01:1; // 012 - Assigned to IBM
|
||||
uint8_t ipter:1; // 013 - IPTE-range
|
||||
uint8_t nqks:1; // 014 - Nonquiescing key-setting
|
||||
uint8_t ibm02:1; // 015 - Assigned to IBM
|
||||
uint8_t etf2:1; // 016 - Extended translation 2
|
||||
uint8_t msa:1; // 017 - Message security assist 1
|
||||
uint8_t ld:1; // 018 - Long displacement
|
||||
uint8_t ldh:1; // 019 - Long displacement high perf
|
||||
uint8_t mas:1; // 020 - HFP multiply-add-subtract
|
||||
uint8_t eif:1; // 021 - Extended immediate
|
||||
uint8_t etf3:1; // 022 - Extended translation 3
|
||||
uint8_t hux:1; // 023 - HFP unnormalized extension
|
||||
uint8_t etf2e:1; // 024 - Extended translation enhanced 2
|
||||
uint8_t stckf:1; // 025 - Store clock fast
|
||||
uint8_t pe:1; // 026 - Parsing enhancement
|
||||
uint8_t mvcos:1; // 027 - Move with optional specs
|
||||
uint8_t tods:1; // 028 - TOD steering
|
||||
uint8_t x000:1; // 029 - Undefined
|
||||
uint8_t etf3e:1; // 030 - ETF3 enhancement
|
||||
uint8_t ecput:1; // 031 - Extract CPU time
|
||||
uint8_t csst:1; // 032 - Compare swap and store
|
||||
uint8_t csst2:1; // 033 - Compare swap and store 2
|
||||
uint8_t gie:1; // 034 - General instructions extension
|
||||
uint8_t ee:1; // 035 - Execute extensions
|
||||
uint8_t em:1; // 036 - Enhanced monitor
|
||||
uint8_t fpe:1; // 037 - Floating point extension
|
||||
uint8_t x001:1; // 038 - Undefined
|
||||
uint8_t ibm03:1; // 039 - Assigned to IBM
|
||||
uint8_t spp:1; // 040 - Set program parameters
|
||||
uint8_t fpse:1; // 041 - FP support enhancement
|
||||
uint8_t dfp:1; // 042 - DFP
|
||||
uint8_t dfph:1; // 043 - DFP high performance
|
||||
uint8_t pfpo:1; // 044 - PFPO instruction
|
||||
uint8_t multi:1; // 045 - Multiple inc load/store on CC 1
|
||||
uint8_t ibm04:1; // 046 - Assigned to IBM
|
||||
uint8_t cmpsce:1; // 047 - CMPSC enhancement
|
||||
uint8_t dfpzc:1; // 048 - DFP zoned conversion
|
||||
uint8_t misc:1; // 049 - Multiple inc load and trap
|
||||
uint8_t ctx:1; // 050 - Constrained transactional-execution
|
||||
uint8_t ltlb:1; // 051 - Local TLB clearing
|
||||
uint8_t ia:1; // 052 - Interlocked access
|
||||
uint8_t lsoc2:1; // 053 - Load/store on CC 2
|
||||
uint8_t x002:1; // 054 - Undefined
|
||||
uint8_t ibm05:1; // 055 - Assigned to IBM
|
||||
uint8_t x003:1; // 056 - Undefined
|
||||
uint8_t msa5:1; // 057 - Message security assist 5
|
||||
uint8_t x004:1; // 058 - Undefined
|
||||
uint8_t x005:1; // 059 - Undefined
|
||||
uint8_t x006:1; // 060 - Undefined
|
||||
uint8_t x007:1; // 061 - Undefined
|
||||
uint8_t ibm06:1; // 062 - Assigned to IBM
|
||||
uint8_t x008:1; // 063 - Undefined
|
||||
uint8_t x009:1; // 064 - Undefined
|
||||
uint8_t ibm07:1; // 065 - Assigned to IBM
|
||||
uint8_t rrbm:1; // 066 - Reset reference bits multiple
|
||||
uint8_t cmc:1; // 067 - CPU measurement counter
|
||||
uint8_t cms:1; // 068 - CPU Measurement sampling
|
||||
uint8_t ibm08:1; // 069 - Assigned to IBM
|
||||
uint8_t ibm09:1; // 070 - Assigned to IBM
|
||||
uint8_t ibm10:1; // 071 - Assigned to IBM
|
||||
uint8_t ibm11:1; // 072 - Assigned to IBM
|
||||
uint8_t txe:1; // 073 - Transactional execution
|
||||
uint8_t sthy:1; // 074 - Store hypervisor information
|
||||
uint8_t aefsi:1; // 075 - Access exception fetch/store indication
|
||||
uint8_t msa3:1; // 076 - Message security assist 3
|
||||
uint8_t msa4:1; // 077 - Message security assist 4
|
||||
uint8_t edat2:1; // 078 - Enhanced DAT 2
|
||||
uint8_t x010:1; // 079 - Undefined
|
||||
uint8_t dfppc:1; // 080 - DFP packed conversion
|
||||
uint8_t x011:7; // 081-87 - Undefined
|
||||
uint8_t x012[5]; // 088-127 - Undefined
|
||||
uint8_t ibm12:1; // 128 - Assigned to IBM
|
||||
uint8_t vec:1; // 129 - Vector facility
|
||||
uint8_t x013:6; // 130-135 - Undefined
|
||||
uint8_t x014:6; // 136-141 - Undefined
|
||||
uint8_t sccm:1; // 142 - Store CPU counter multiple
|
||||
uint8_t ibm13:1; // 143 - Assigned to IBM
|
||||
uint8_t x015[14]; // 144-256 Undefined
|
||||
} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
int lFacs = sizeof(facs) / 8;
|
||||
facilityList_t facs;
|
||||
int lFacs = sizeof (facs) / 8;
|
||||
|
||||
__asm__ (" lgfr 0,%1\n"
|
||||
" .insn s,0xb2b00000,%0\n"
|
||||
: "=m" (facs) : "r" (lFacs) : "0", "cc");
|
||||
}
|
||||
__asm__ __volatile__ (
|
||||
"lgfr\t0,%1\n\t"
|
||||
".insn\ts,0xb2b00000,%0\n\t"
|
||||
: "=m" (facs)
|
||||
: "r" (lFacs)
|
||||
: "0", "cc"
|
||||
);
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE *f)
|
||||
{
|
||||
mono_hwcap_s390x_has_fpe = facs.fpe;
|
||||
mono_hwcap_s390x_has_vec = facs.vec;
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_S390X_H__
|
||||
#define __MONO_UTILS_HWCAP_S390X_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
typedef struct __FACLIST__ {
|
||||
uint8_t n3:1; // 000 - N3 instructions
|
||||
uint8_t zi:1; // 001 - z/Arch installed
|
||||
uint8_t za:1; // 002 - z/Arch active
|
||||
uint8_t date:1; // 003 - DAT-enhancement
|
||||
uint8_t idtes:1; // 004 - IDTE-segment tables
|
||||
uint8_t idter:1; // 005 - IDTE-region tables
|
||||
uint8_t asnlx:1; // 006 - ASN-LX reuse
|
||||
uint8_t stfle:1; // 007 - STFLE
|
||||
uint8_t edat1:1; // 008 - EDAT 1
|
||||
uint8_t srs:1; // 009 - Sense-Running-Status
|
||||
uint8_t csske:1; // 010 - Conditional SSKE
|
||||
uint8_t ctf:1; // 011 - Configuration-topology
|
||||
uint8_t ibm01:1; // 012 - Assigned to IBM
|
||||
uint8_t ipter:1; // 013 - IPTE-range
|
||||
uint8_t nqks:1; // 014 - Nonquiescing key-setting
|
||||
uint8_t ibm02:1; // 015 - Assigned to IBM
|
||||
uint8_t etf2:1; // 016 - Extended translation 2
|
||||
uint8_t msa:1; // 017 - Message security assist 1
|
||||
uint8_t ld:1; // 018 - Long displacement
|
||||
uint8_t ldh:1; // 019 - Long displacement high perf
|
||||
uint8_t mas:1; // 020 - HFP multiply-add-subtract
|
||||
uint8_t eif:1; // 021 - Extended immediate
|
||||
uint8_t etf3:1; // 022 - Extended translation 3
|
||||
uint8_t hux:1; // 023 - HFP unnormalized extension
|
||||
uint8_t etf2e:1; // 024 - Extended translation enhanced 2
|
||||
uint8_t stckf:1; // 025 - Store clock fast
|
||||
uint8_t pe:1; // 026 - Parsing enhancement
|
||||
uint8_t mvcos:1; // 027 - Move with optional specs
|
||||
uint8_t tods:1; // 028 - TOD steering
|
||||
uint8_t x000:1; // 029 - Undefined
|
||||
uint8_t etf3e:1; // 030 - ETF3 enhancement
|
||||
uint8_t ecput:1; // 031 - Extract CPU time
|
||||
uint8_t csst:1; // 032 - Compare swap and store
|
||||
uint8_t csst2:1; // 033 - Compare swap and store 2
|
||||
uint8_t gie:1; // 034 - General instructions extension
|
||||
uint8_t ee:1; // 035 - Execute extensions
|
||||
uint8_t em:1; // 036 - Enhanced monitor
|
||||
uint8_t fpe:1; // 037 - Floating point extension
|
||||
uint8_t x001:1; // 038 - Undefined
|
||||
uint8_t ibm03:1; // 039 - Assigned to IBM
|
||||
uint8_t spp:1; // 040 - Set program parameters
|
||||
uint8_t fpse:1; // 041 - FP support enhancement
|
||||
uint8_t dfp:1; // 042 - DFP
|
||||
uint8_t dfph:1; // 043 - DFP high performance
|
||||
uint8_t pfpo:1; // 044 - PFPO instruction
|
||||
uint8_t multi:1; // 045 - Multiple inc load/store on CC 1
|
||||
uint8_t ibm04:1; // 046 - Assigned to IBM
|
||||
uint8_t cmpsce:1; // 047 - CMPSC enhancement
|
||||
uint8_t dfpzc:1; // 048 - DFP zoned conversion
|
||||
uint8_t misc:1; // 049 - Multiple inc load and trap
|
||||
uint8_t ctx:1; // 050 - Constrained transactional-execution
|
||||
uint8_t ltlb:1; // 051 - Local TLB clearing
|
||||
uint8_t ia:1; // 052 - Interlocked access
|
||||
uint8_t lsoc2:1; // 053 - Load/store on CC 2
|
||||
uint8_t x002:1; // 054 - Undefined
|
||||
uint8_t ibm05:1; // 055 - Assigned to IBM
|
||||
uint8_t x003:1; // 056 - Undefined
|
||||
uint8_t msa5:1; // 057 - Message security assist 5
|
||||
uint8_t x004:1; // 058 - Undefined
|
||||
uint8_t x005:1; // 059 - Undefined
|
||||
uint8_t x006:1; // 060 - Undefined
|
||||
uint8_t x007:1; // 061 - Undefined
|
||||
uint8_t ibm06:1; // 062 - Assigned to IBM
|
||||
uint8_t x008:1; // 063 - Undefined
|
||||
uint8_t x009:1; // 064 - Undefined
|
||||
uint8_t ibm07:1; // 065 - Assigned to IBM
|
||||
uint8_t rrbm:1; // 066 - Reset reference bits multiple
|
||||
uint8_t cmc:1; // 067 - CPU measurement counter
|
||||
uint8_t cms:1; // 068 - CPU Measurement sampling
|
||||
uint8_t ibm08:1; // 069 - Assigned to IBM
|
||||
uint8_t ibm09:1; // 070 - Assigned to IBM
|
||||
uint8_t ibm10:1; // 071 - Assigned to IBM
|
||||
uint8_t ibm11:1; // 072 - Assigned to IBM
|
||||
uint8_t txe:1; // 073 - Transactional execution
|
||||
uint8_t sthy:1; // 074 - Store hypervisor information
|
||||
uint8_t aefsi:1; // 075 - Access exception fetch/store indication
|
||||
uint8_t msa3:1; // 076 - Message security assist 3
|
||||
uint8_t msa4:1; // 077 - Message security assist 4
|
||||
uint8_t edat2:1; // 078 - Enhanced DAT 2
|
||||
uint8_t x010:1; // 079 - Undefined
|
||||
uint8_t dfppc:1; // 080 - DFP packed conversion
|
||||
uint8_t x011:7; // 081-87 - Undefined
|
||||
uint8_t x012[5]; // 088-127 - Undefined
|
||||
uint8_t ibm12:1; // 128 - Assigned to IBM
|
||||
uint8_t vec:1; // 129 - Vector facility
|
||||
uint8_t x013:6; // 130-135 - Undefined
|
||||
uint8_t x014:6; // 136-141 - Undefined
|
||||
uint8_t sccm:1; // 142 - Store CPU counter multiple
|
||||
uint8_t ibm13:1; // 143 - Assigned to IBM
|
||||
uint8_t x015[14]; // 144-256 Undefined
|
||||
} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
|
||||
|
||||
extern facilityList_t facs;
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_S390X_H__ */
|
@ -19,26 +19,22 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-sparc.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(__linux__)
|
||||
#include <sys/systeminfo.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
gboolean mono_hwcap_sparc_is_v9 = FALSE;
|
||||
|
||||
void
|
||||
mono_hwcap_arch_init (void)
|
||||
{
|
||||
char buf [1024];
|
||||
|
||||
#if !defined(__linux__)
|
||||
if (!sysinfo (SI_ISALIST, buf, 1024))
|
||||
g_assert_not_reached ();
|
||||
g_assert (sysinfo (SI_ISALIST, buf, 1024));
|
||||
#else
|
||||
/* If the page size is 8192, we're on a 64-bit SPARC, which
|
||||
* in turn means a v9 or better.
|
||||
@ -51,9 +47,3 @@ mono_hwcap_arch_init (void)
|
||||
|
||||
mono_hwcap_sparc_is_v9 = strstr (buf, "sparcv9");
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE *f)
|
||||
{
|
||||
g_fprintf (f, "mono_hwcap_sparc_is_v9 = %i\n", mono_hwcap_sparc_is_v9);
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_SPARC_H__
|
||||
#define __MONO_UTILS_HWCAP_SPARC_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
extern gboolean mono_hwcap_sparc_is_v9;
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_SPARC_H__ */
|
56
mono/utils/mono-hwcap-vars.h
Normal file
56
mono/utils/mono-hwcap-vars.h
Normal file
@ -0,0 +1,56 @@
|
||||
#include "config.h"
|
||||
|
||||
#if defined (TARGET_ARM)
|
||||
|
||||
MONO_HWCAP_VAR(arm_is_v5)
|
||||
MONO_HWCAP_VAR(arm_is_v6)
|
||||
MONO_HWCAP_VAR(arm_is_v7)
|
||||
MONO_HWCAP_VAR(arm_has_vfp)
|
||||
MONO_HWCAP_VAR(arm_has_vfp3)
|
||||
MONO_HWCAP_VAR(arm_has_vfp3_d16)
|
||||
MONO_HWCAP_VAR(arm_has_thumb)
|
||||
MONO_HWCAP_VAR(arm_has_thumb2)
|
||||
|
||||
#elif defined (TARGET_ARM64)
|
||||
|
||||
// Nothing here yet.
|
||||
|
||||
#elif defined (TARGET_IA64)
|
||||
|
||||
// Nothing here yet.
|
||||
|
||||
#elif defined (TARGET_MIPS)
|
||||
|
||||
// Nothing here yet.
|
||||
|
||||
#elif defined (TARGET_POWERPC) || defined (TARGET_POWERPC64)
|
||||
|
||||
MONO_HWCAP_VAR(ppc_has_icache_snoop)
|
||||
MONO_HWCAP_VAR(ppc_is_isa_2x)
|
||||
MONO_HWCAP_VAR(ppc_is_isa_64)
|
||||
MONO_HWCAP_VAR(ppc_has_move_fpr_gpr)
|
||||
MONO_HWCAP_VAR(ppc_has_multiple_ls_units)
|
||||
|
||||
#elif defined (TARGET_S390X)
|
||||
|
||||
MONO_HWCAP_VAR(s390x_has_fpe)
|
||||
MONO_HWCAP_VAR(s390x_has_vec)
|
||||
|
||||
#elif defined (TARGET_SPARC) || defined (TARGET_SPARC64)
|
||||
|
||||
MONO_HWCAP_VAR(sparc_is_v9)
|
||||
|
||||
#elif defined (TARGET_X86) || defined (TARGET_AMD64)
|
||||
|
||||
MONO_HWCAP_VAR(x86_is_xen)
|
||||
MONO_HWCAP_VAR(x86_has_cmov)
|
||||
MONO_HWCAP_VAR(x86_has_fcmov)
|
||||
MONO_HWCAP_VAR(x86_has_sse1)
|
||||
MONO_HWCAP_VAR(x86_has_sse2)
|
||||
MONO_HWCAP_VAR(x86_has_sse3)
|
||||
MONO_HWCAP_VAR(x86_has_ssse3)
|
||||
MONO_HWCAP_VAR(x86_has_sse41)
|
||||
MONO_HWCAP_VAR(x86_has_sse42)
|
||||
MONO_HWCAP_VAR(x86_has_sse4a)
|
||||
|
||||
#endif
|
@ -19,27 +19,15 @@
|
||||
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
*/
|
||||
|
||||
#include "mono/utils/mono-hwcap-x86.h"
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
gboolean mono_hwcap_x86_is_xen = FALSE;
|
||||
gboolean mono_hwcap_x86_has_cmov = FALSE;
|
||||
gboolean mono_hwcap_x86_has_fcmov = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse1 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse2 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse3 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_ssse3 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse41 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse42 = FALSE;
|
||||
gboolean mono_hwcap_x86_has_sse4a = FALSE;
|
||||
|
||||
static gboolean
|
||||
cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx)
|
||||
{
|
||||
@ -162,18 +150,3 @@ mono_hwcap_arch_init (void)
|
||||
mono_hwcap_x86_is_xen = !access ("/proc/xen", F_OK);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (FILE *f)
|
||||
{
|
||||
g_fprintf (f, "mono_hwcap_x86_is_xen = %i\n", mono_hwcap_x86_is_xen);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_cmov = %i\n", mono_hwcap_x86_has_cmov);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_fcmov = %i\n", mono_hwcap_x86_has_fcmov);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse1 = %i\n", mono_hwcap_x86_has_sse1);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse2 = %i\n", mono_hwcap_x86_has_sse2);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse3 = %i\n", mono_hwcap_x86_has_sse3);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_ssse3 = %i\n", mono_hwcap_x86_has_ssse3);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse41 = %i\n", mono_hwcap_x86_has_sse41);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse42 = %i\n", mono_hwcap_x86_has_sse42);
|
||||
g_fprintf (f, "mono_hwcap_x86_has_sse4a = %i\n", mono_hwcap_x86_has_sse4a);
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
#ifndef __MONO_UTILS_HWCAP_X86_H__
|
||||
#define __MONO_UTILS_HWCAP_X86_H__
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
extern gboolean mono_hwcap_x86_is_xen;
|
||||
extern gboolean mono_hwcap_x86_has_cmov;
|
||||
extern gboolean mono_hwcap_x86_has_fcmov;
|
||||
extern gboolean mono_hwcap_x86_has_sse1;
|
||||
extern gboolean mono_hwcap_x86_has_sse2;
|
||||
extern gboolean mono_hwcap_x86_has_sse3;
|
||||
extern gboolean mono_hwcap_x86_has_ssse3;
|
||||
extern gboolean mono_hwcap_x86_has_sse41;
|
||||
extern gboolean mono_hwcap_x86_has_sse42;
|
||||
extern gboolean mono_hwcap_x86_has_sse4a;
|
||||
|
||||
#endif /* __MONO_UTILS_HWCAP_X86_H__ */
|
@ -24,6 +24,10 @@
|
||||
|
||||
#include "mono/utils/mono-hwcap.h"
|
||||
|
||||
#define MONO_HWCAP_VAR(NAME) gboolean mono_hwcap_ ## NAME = FALSE;
|
||||
#include "mono/utils/mono-hwcap-vars.h"
|
||||
#undef MONO_HWCAP_VAR
|
||||
|
||||
static gboolean hwcap_inited = FALSE;
|
||||
|
||||
void
|
||||
@ -35,19 +39,21 @@ mono_hwcap_init (void)
|
||||
if (hwcap_inited)
|
||||
return;
|
||||
|
||||
#ifdef MONO_CROSS_COMPILE
|
||||
/*
|
||||
* If we're cross-compiling, we want to be as
|
||||
* conservative as possible so that we produce
|
||||
* code that's portable. Default to that.
|
||||
*/
|
||||
if (!conservative)
|
||||
conservative = "1";
|
||||
#endif
|
||||
|
||||
if (!conservative || strncmp (conservative, "1", 1))
|
||||
mono_hwcap_arch_init ();
|
||||
|
||||
if (verbose && !strncmp (verbose, "1", 1))
|
||||
mono_hwcap_print (stdout);
|
||||
mono_hwcap_print ();
|
||||
}
|
||||
|
||||
void
|
||||
mono_hwcap_print (void)
|
||||
{
|
||||
g_print ("[mono-hwcap] Detected following hardware capabilities:\n\n");
|
||||
|
||||
#define MONO_HWCAP_VAR(NAME) g_print ("\t" #NAME " = %s\n", mono_hwcap_ ## NAME ? "yes" : "no");
|
||||
#include "mono/utils/mono-hwcap-vars.h"
|
||||
#undef MONO_HWCAP_VAR
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
|
@ -8,6 +8,10 @@
|
||||
|
||||
#include "mono/utils/mono-compiler.h"
|
||||
|
||||
#define MONO_HWCAP_VAR(NAME) extern gboolean mono_hwcap_ ## NAME;
|
||||
#include "mono/utils/mono-hwcap-vars.h"
|
||||
#undef MONO_HWCAP_VAR
|
||||
|
||||
/* Call this function to perform hardware feature detection. Until
|
||||
* this function has been called, all feature variables will be
|
||||
* FALSE as a default.
|
||||
@ -17,17 +21,14 @@
|
||||
* result in an inconsistent state of the variables. Further,
|
||||
* feature variables should not be read *while* this function is
|
||||
* executing.
|
||||
*
|
||||
* To get at feature variables, include the appropriate header,
|
||||
* e.g. mono-hwcap-x86.h for x86(-64).
|
||||
*/
|
||||
void mono_hwcap_init (void);
|
||||
|
||||
/* Implemented in mono-hwcap-$TARGET.c. Do not call. */
|
||||
void mono_hwcap_arch_init (void);
|
||||
|
||||
/* Print detected features to the given file. */
|
||||
void mono_hwcap_print (FILE *f);
|
||||
/* Print detected features to stdout. */
|
||||
void mono_hwcap_print (void);
|
||||
|
||||
/* Please note: If you're going to use the Linux auxiliary vector
|
||||
* to detect CPU features, don't use any of the constant names in
|
||||
|
@ -25,7 +25,7 @@ mask (gpointer n, uintptr_t bit)
|
||||
}
|
||||
|
||||
gpointer
|
||||
get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
|
||||
mono_lls_get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
|
||||
{
|
||||
gpointer p;
|
||||
|
||||
@ -56,28 +56,21 @@ get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers
|
||||
/*
|
||||
Initialize @list and will use @free_node_func to release memory.
|
||||
If @free_node_func is null the caller is responsible for releasing node memory.
|
||||
If @free_node_func may lock, @free_node_func_locking must be
|
||||
HAZARD_FREE_MAY_LOCK; otherwise, HAZARD_FREE_NO_LOCK. It is ignored if
|
||||
@free_node_func is null.
|
||||
*/
|
||||
void
|
||||
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking)
|
||||
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *))
|
||||
{
|
||||
list->head = NULL;
|
||||
list->free_node_func = free_node_func;
|
||||
list->locking = free_node_func_locking;
|
||||
}
|
||||
|
||||
/*
|
||||
Search @list for element with key @key.
|
||||
@context specifies whether the function is being called from a lock-free (i.e.
|
||||
signal handler or world stopped) context. It is only relevant if a node free
|
||||
function was given.
|
||||
The nodes next, cur and prev are returned in @hp.
|
||||
Returns true if a node with key @key was found.
|
||||
*/
|
||||
gboolean
|
||||
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context)
|
||||
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key)
|
||||
{
|
||||
MonoLinkedListSetNode *cur, *next;
|
||||
MonoLinkedListSetNode **prev;
|
||||
@ -95,12 +88,12 @@ try_again:
|
||||
*/
|
||||
mono_hazard_pointer_set (hp, 2, prev);
|
||||
|
||||
cur = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer*)prev, hp, 1);
|
||||
cur = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer*)prev, hp, 1);
|
||||
|
||||
while (1) {
|
||||
if (cur == NULL)
|
||||
return FALSE;
|
||||
next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer*)&cur->next, hp, 0);
|
||||
next = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer*)&cur->next, hp, 0);
|
||||
cur_key = cur->key;
|
||||
|
||||
/*
|
||||
@ -137,15 +130,12 @@ try_again:
|
||||
|
||||
/*
|
||||
Insert @value into @list.
|
||||
@context specifies whether the function is being called from a lock-free (i.e.
|
||||
signal handler or world stopped) context. It is only relevant if a node free
|
||||
function was given.
|
||||
The nodes value, cur and prev are returned in @hp.
|
||||
Return true if @value was inserted by this call. If it returns FALSE, it's the caller
|
||||
resposibility to release memory.
|
||||
*/
|
||||
gboolean
|
||||
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
|
||||
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
|
||||
{
|
||||
MonoLinkedListSetNode *cur, **prev;
|
||||
/*We must do a store barrier before inserting
|
||||
@ -153,7 +143,7 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
|
||||
mono_memory_barrier ();
|
||||
|
||||
while (1) {
|
||||
if (mono_lls_find (list, hp, value->key, context))
|
||||
if (mono_lls_find (list, hp, value->key))
|
||||
return FALSE;
|
||||
cur = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 1);
|
||||
prev = (MonoLinkedListSetNode **) mono_hazard_pointer_get_val (hp, 2);
|
||||
@ -169,18 +159,15 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
|
||||
|
||||
/*
|
||||
Search @list for element with key @key and remove it.
|
||||
@context specifies whether the function is being called from a lock-free (i.e.
|
||||
signal handler or world stopped) context. It is only relevant if a node free
|
||||
function was given.
|
||||
The nodes next, cur and prev are returned in @hp
|
||||
Returns true if @value was removed by this call.
|
||||
*/
|
||||
gboolean
|
||||
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
|
||||
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
|
||||
{
|
||||
MonoLinkedListSetNode *cur, **prev, *next;
|
||||
while (1) {
|
||||
if (!mono_lls_find (list, hp, value->key, context))
|
||||
if (!mono_lls_find (list, hp, value->key))
|
||||
return FALSE;
|
||||
|
||||
next = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 0);
|
||||
@ -198,9 +185,9 @@ mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
|
||||
mono_memory_write_barrier ();
|
||||
mono_hazard_pointer_clear (hp, 1);
|
||||
if (list->free_node_func)
|
||||
mono_thread_hazardous_try_free (value, list->free_node_func);
|
||||
mono_thread_hazardous_queue_free (value, list->free_node_func);
|
||||
} else
|
||||
mono_lls_find (list, hp, value->key, context);
|
||||
mono_lls_find (list, hp, value->key);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user