Imported Upstream version 4.6.0.243

Former-commit-id: ff34202749e8df2aa83f2578b16260b444f50987
This commit is contained in:
Xamarin Public Jenkins (auto-signing) 2016-09-09 07:19:48 +00:00
parent 804b15604f
commit 3cc9601fd9
113 changed files with 1476 additions and 4439 deletions

View File

@ -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,

View File

@ -1,3 +1,7 @@
.de Sp
.if t .sp .5v
.if n .sp
..
.TH mprof-report 1 ""
.SH The Mono log profiler
.PP
@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -450,7 +450,7 @@ namespace System.Net
newWebHeaders.Add(headerName,webHeaders[headerName]);
}
webHeaders = newWebHeaders;
this.webHeaders = newWebHeaders;
}
}

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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 ()

View 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 ();
}
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -1 +1 @@
0e58c3fba67bf21766014677b5f894f7637162d9
c490c7433c000c0ca9ff7be0753080941738fdbc

View File

@ -1 +1 @@
8ad53def268a4750474dee2731ef4039642458aa
c3bbfb8e3d0bb1d4648a456800a8f616d8a28016

View File

@ -1 +1 @@
4ed6e201e6785a6e9e44a113d2be4c9fd569673c
8410f10f87dea9524681b3f688dab2f70afbf9b5

View File

@ -1 +1 @@
9d728aa18a9d89c58a94469c86f374658f784ccd
d2b12594e92c61982d88980ec4bfaeb7c3bdf9ab

View File

@ -38,7 +38,11 @@ namespace Microsoft.Win32.SafeHandles {
[SecurityCritical]
protected override bool ReleaseHandle()
{
#if MONO
return true;
#else
return Win32Native.CloseHandle(handle);
#endif
}
}

View File

@ -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
View 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 ();
}
}

View File

@ -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>

View File

@ -15,4 +15,12 @@ class PragmaNewLinesParsing
{
return;
}
#pragma warning disable 618
#pragma warning restore 618
void OneMore ()
{
return;
}
}

View File

@ -1 +1 @@
720ef10c534ff81a6c9296b3f09a50987144d5a9
216a310da0866d4efac81f4c8a3bcdc849ad8891

View File

@ -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)
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)
if (!refOnly && prevent_running_reference_assembly (ass, &error))
goto leave;
g_assert (ass);
if (refass == NULL) {
refass = mono_assembly_get_object_checked (domain, ass, &error);
if (!is_ok (&error))
goto leave;
}
if (refass == NULL)
mono_error_set_pending_exception (&error);
else
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

View File

@ -0,0 +1 @@
7bd02ff37eea77a111cb30ce2d3b64953d487736

View File

@ -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,8 +475,22 @@ 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 ();

View File

@ -1 +1 @@
17da478b5e9c1f089d76de0bc275da6ab5e21077
56e12ad673e2765956a4fc89dade62a15656a02f

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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);

View File

@ -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 ();

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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:

View File

@ -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:

View File

@ -1 +1 @@
95fb4f0f463f11376bc66366d33b0ada31e655e7
573c53e6293cd2939965dca9b67122cfc812637e

View File

@ -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)
{
}

View File

@ -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__ */

View File

@ -1 +1 @@
3bcf4cb71650d65d78892cb857793dfc5e9ff723
a907decc82e6ebd6fbd2f02741729d50fcfe07b4

View File

@ -1 +1 @@
aa7acf5abc72eb26d1200dce837653f7885f2eab
3f41fb3fc226e85aa23b373990dd4e5738d6d28d

View File

@ -1 +1 @@
a708eb3eb22b244fef50931de958816f2d0f4ece
2eac36939370f203a0ed0b3ea7e284bc90b21527

View File

@ -1 +1 @@
d88a6c99a8f362bb690424ace4462d58f3d913d9
357e260799833ed8d4a1bf415c148853bf610e39

View File

@ -1 +1 @@
2fe69c378a64914c4bb35bf1a52a00153609255b
1bf1ba6fa13f613a176781c0d4a9c16183273460

View File

@ -1 +1 @@
5d6ebc7b6bc126975df54bdc38c29d247d5ca8d0
783896f15681743acb6001dad302705db271bee9

View File

@ -1 +1 @@
3089a8546b1d3a4d605535a775c1f57d27eb793f
7d2c0d8b8cfda73cacd3b6847b37f7c5dd523da4

View File

@ -1 +1 @@
352a868b87f98ab2000dd24c33320aee1b63b2a5
c4ae82e0cbcbda75f4f963ba3f352e7d90dc4c14

View File

@ -1 +1 @@
3fe40d2cfc28fdd8a055b003ad58785d5cbd3427
a1094afa173fbe0baeb75c2ff221e0e9b73ae7e9

View File

@ -1 +1 @@
022f8a5e790b8ea9334d4fa61bb7f92c99229c9f
5003bfe025403fa2d02c9709b18d04fa2e26b491

View File

@ -1 +1 @@
badf12b33b3bf1d72f1466b48e8c8a0aeb517e88
6a3a6c0aa4e1c0a792e0d4bcc355138b97d67f68

View File

@ -1 +1 @@
#define FULL_VERSION "Stable 4.6.0.182/3ed2bba"
#define FULL_VERSION "Stable 4.6.0.243/dea2155"

View File

@ -1 +1 @@
e8d53afea686ed76588370c99fe74beac2c0718b
b213528caaa35b55a02a43f0c8b2329a40eeab75

View File

@ -1 +1 @@
99e68567571dcf59b3759f143d2642e0861c06de
40e4187280464b96aac6aa5ea5d1f8539689ea02

View File

@ -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_THROW_NO_BT = 0 << 7,
TYPE_THROW_BT = 1 << 7,
TYPE_CLAUSE = 1 << 4,
TYPE_EXCEPTION_BT = 1 << 7,
/* 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 {

View File

@ -418,7 +418,7 @@ uintptr_t
process_id (void)
{
#ifdef HOST_WIN32
return 0; /* FIXME */
return GetCurrentProcessId ();
#else
return (uintptr_t)getpid ();
#endif

View File

@ -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

View File

@ -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:

View File

@ -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

View 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;
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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@

View File

@ -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

View File

@ -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

View File

@ -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); \

View File

@ -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);

View File

@ -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;

View File

@ -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__*/

View File

@ -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;

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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)
{
}

View File

@ -1,6 +0,0 @@
#ifndef __MONO_UTILS_HWCAP_ARM64_H__
#define __MONO_UTILS_HWCAP_ARM64_H__
#include "mono/utils/mono-hwcap.h"
#endif

View 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)
{
}

View File

@ -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)
{
}

View File

@ -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__ */

View File

@ -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)
{
}

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View 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

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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");
}

View File

@ -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

View File

@ -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