Merge pull request #4935 from lambdageek/dev-handles-may
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Wed, 31 May 2017 18:34:20 +0000 (14:34 -0400)
committerGitHub <noreply@github.com>
Wed, 31 May 2017 18:34:20 +0000 (14:34 -0400)
[coop handles] w32event, w32handle and DNS icalls

98 files changed:
external/api-snapshot
external/bockbuild
external/cecil
external/corefx
mcs/class/Facades/System.Data.Common/AssemblyInfo.cs
mcs/class/Facades/System.Data.Common/TypeForwarders.cs
mcs/class/Facades/System.Diagnostics.StackTrace/AssemblyInfo.cs
mcs/class/Facades/System.Diagnostics.StackTrace/TypeForwarders.cs
mcs/class/Facades/System.Diagnostics.Tracing/AssemblyInfo.cs
mcs/class/Facades/System.Globalization.Extensions/AssemblyInfo.cs
mcs/class/Facades/System.Net.Ping/AssemblyInfo.cs
mcs/class/Facades/System.Net.Sockets/AssemblyInfo.cs
mcs/class/Facades/System.Net.Sockets/TypeForwarders.cs
mcs/class/Facades/System.Runtime.InteropServices.RuntimeInformation/Assembly/AssemblyInfo.cs
mcs/class/Facades/System.Runtime.InteropServices.RuntimeInformation/Makefile
mcs/class/Facades/System.Runtime.InteropServices.RuntimeInformation/System.Runtime.InteropServices/RuntimeInformation.cs
mcs/class/Facades/System.Runtime.Serialization.Primitives/AssemblyInfo.cs
mcs/class/Facades/System.Runtime.Serialization.Primitives/TypeForwarders.cs
mcs/class/Facades/System.Security.Cryptography.Algorithms/AssemblyInfo.cs
mcs/class/Facades/System.Security.Cryptography.Algorithms/TypeForwarders.cs
mcs/class/Facades/System.Security.SecureString/AssemblyInfo.cs
mcs/class/Facades/System.Threading.Overlapped/AssemblyInfo.cs
mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs
mcs/class/Facades/System.ValueTuple/AssemblyInfo.cs
mcs/class/Facades/System.Xml.XPath.XDocument/AssemblyInfo.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.dll.sources
mcs/class/Mono.Posix/Assembly/AssemblyInfo.cs
mcs/class/Mono.Posix/Mono.Posix.NETStandard-netstandard_2_0.csproj [new file with mode: 0644]
mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs
mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs
mcs/class/Mono.Posix/Test/Mono.Unix.Native/StdlibTest.cs
mcs/class/System/System.Net.Configuration/DefaultProxySection.cs
mcs/class/System/System.Net.Configuration/ProxyElement.cs
mcs/class/System/System.Net.NetworkInformation/Ping.cs
mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.platformnotsupported.cs [new file with mode: 0644]
mcs/class/System/common.sources
mcs/class/System/common_networking.sources
mcs/class/System/monotouch_watch_System.dll.sources
mcs/class/aot-compiler/Makefile
mcs/class/corlib/Assembly/AssemblyInfo.cs
mcs/errors/cs0535-7.cs [new file with mode: 0644]
mcs/errors/cs0535-8.cs [new file with mode: 0644]
mcs/mcs/expression.cs
mcs/mcs/import.cs
mcs/mcs/parameter.cs
mcs/mcs/pending.cs
mcs/mcs/property.cs
mcs/mcs/statement.cs
mcs/tests/test-944-lib.cs [new file with mode: 0644]
mcs/tests/test-944.cs [new file with mode: 0644]
mcs/tests/test-945.cs [new file with mode: 0644]
mcs/tests/test-async-92.cs [new file with mode: 0644]
mcs/tests/test-async-93.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mono/metadata/Makefile.am
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/jit-info.c
mono/metadata/mempool-internals.h
mono/metadata/mono-conc-hash.c [new file with mode: 0644]
mono/metadata/mono-conc-hash.h [new file with mode: 0644]
mono/metadata/reflection-cache.h
mono/metadata/reflection.c
mono/metadata/sre.c
mono/mini/Makefile.am.in
mono/mini/MemoryIntrinsics.il [new file with mode: 0644]
mono/mini/aot-runtime.c
mono/mini/debugger-agent.c
mono/mini/decompose.c
mono/mini/interp/interp-internals.h
mono/mini/interp/interp-stubs.c [new file with mode: 0644]
mono/mini/interp/interp.c
mono/mini/interp/interp.h
mono/mini/interp/mintops.c
mono/mini/interp/mintops.def
mono/mini/interp/transform.c
mono/mini/memory-access.c
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-exceptions.c
mono/mini/mini-generic-sharing.c
mono/mini/mini-runtime.c
mono/mini/mini.h
mono/mini/tramp-arm.c
mono/mini/unaligned.cs [new file with mode: 0644]
mono/tests/Makefile.am
mono/tests/cominterop.cs
mono/tests/libtest.c
mono/tests/marshal2.cs
msvc/libmono-static.vcxproj
msvc/libmono-static.vcxproj.filters
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters
packaging/.gitignore [new file with mode: 0644]
packaging/MacSDK/mono.py
packaging/MacSDK/xamarin-gtk-theme.py

index 366b5e92d77e4e6e62a6965073097b48a59c1bdc..bb16afac3deaa1cd8f798668b04b5510cfcd53ba 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 366b5e92d77e4e6e62a6965073097b48a59c1bdc
+Subproject commit bb16afac3deaa1cd8f798668b04b5510cfcd53ba
index c783777342f4d39b58f3c2e6a1659eedf504ac87..4f39b930ed66009c54f2326451644ca9d06e4d30 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c783777342f4d39b58f3c2e6a1659eedf504ac87
+Subproject commit 4f39b930ed66009c54f2326451644ca9d06e4d30
index 0b523fa7e0f2f83cc67e4c19f1f769e68d717562..f64903c0e069224aaac7de243fa0a3b17684b4dd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0b523fa7e0f2f83cc67e4c19f1f769e68d717562
+Subproject commit f64903c0e069224aaac7de243fa0a3b17684b4dd
index 5b7e0d739fa65bb7b1c2230df875d37a55b74d10..e49886bd091487abfbf5de934a451c5a8fe7f4c5 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5b7e0d739fa65bb7b1c2230df875d37a55b74d10
+Subproject commit e49886bd091487abfbf5de934a451c5a8fe7f4c5
index 452d0c245ffcb61bd4b9278053ea76e500e71f3f..07a4d102d1796837984158e38f331253c2827e0c 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.1.0.0")]
+[assembly: AssemblyVersion ("4.2.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 24bd6ae8da7ded5bbc574655d7723359812e3522..feba11981fe6b86171b1669c1558c3419f8796c8 100644 (file)
 // 
 
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DBNull))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.AcceptRejectRule))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandBehavior))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.CatalogLocation))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DataAdapter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DataColumnMapping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DataColumnMappingCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DataTableMapping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DataTableMappingCollection))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbColumn))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbCommand))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbCommandBuilder))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnection))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnectionStringBuilder))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataAdapter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataReader))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataReaderExtensions))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataRecord))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataSourceEnumerator))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbEnumerator))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbMetaDataCollectionNames))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbMetaDataColumnNames))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameterCollection))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbProviderFactory))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbProviderSpecificTypePropertyAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbTransaction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.GroupByBehavior))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.IDbColumnSchemaGenerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.IdentifierCase))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.RowUpdatedEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.RowUpdatingEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.SchemaTableColumn))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.SchemaTableOptionalColumn))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.SupportedJoinOperators))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConflictOption))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConnectionState))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Constraint))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConstraintCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConstraintException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DBConcurrencyException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataColumn))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataColumnChangeEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataColumnChangeEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataColumnCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRelation))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRelationCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRow))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowAction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowBuilder))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowChangeEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowChangeEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowState))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowView))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataSet))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataSetDateTime))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataSysDescriptionAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTable))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableClearEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableClearEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableNewRowEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableNewRowEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTableReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataView))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataViewManager))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataViewRowState))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataViewSetting))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataViewSettingCollection))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DbType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DeletedRowInaccessibleException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DuplicateNameException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.EvaluateException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.FillErrorEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.FillErrorEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ForeignKeyConstraint))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IColumnMapping))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IColumnMappingCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataAdapter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameterCollection))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataReader))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataRecord))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbCommand))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbConnection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbDataAdapter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbDataParameter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbTransaction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ITableMapping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ITableMappingCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.InRowChangingEventException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.InternalDataCollectionBase))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.InvalidConstraintException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.InvalidExpressionException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IsolationLevel))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.KeyRestrictionBehavior))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.LoadOption))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MappingType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MergeFailedEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MergeFailedEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MissingMappingAction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MissingPrimaryKeyException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.MissingSchemaAction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.NoNullAllowedException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ParameterDirection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.PropertyCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ReadOnlyException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.RowNotInTableException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Rule))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SchemaSerializationMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SchemaType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SerializationFormat))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlDbType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.INullable))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlAlreadyFilledException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlBinary))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlBoolean))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlByte))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlBytes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlChars))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlCompareOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlDateTime))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlDecimal))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlDouble))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlGuid))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlInt16))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlInt32))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlInt64))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlMoney))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlNotFilledException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlNullValueException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlSingle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlString))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlTruncateException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlTypeException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.SqlXml))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.StorageState))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventArgs))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StatementCompletedEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StatementCompletedEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StatementType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StrongTypingException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SyntaxErrorException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.UniqueConstraint))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.UpdateRowSource))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.UpdateStatus))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.VersionNotFoundException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.XmlReadMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.XmlWriteMode))]
 
 
index 74545a8a222a372e587cfe45912e1c0ab9b3de88..23257c24867cb35d7e9f2aa1fe161cd3fd9873c4 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.2.0")]
+[assembly: AssemblyVersion ("4.1.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 3643429a219efa4bb5011e6c17bbd9b5b76d4a58..b68327ecf21613f0c5729a34510107b4d648d139 100644 (file)
 
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackFrame))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackTrace))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolBinder))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolBinder1))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolDocument))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolDocumentWriter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolMethod))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolNamespace))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolScope))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolVariable))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.ISymbolWriter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.SymAddressKind))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.SymDocumentType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.SymLanguageType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.SymLanguageVendor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.SymbolStore.SymbolToken))]
 
index a6d882dd4ffd3e234b3ad64d13d2ad36285037e0..8cecf7a0b4986ac653609e0b773b09adcb9494c5 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.1.0.0")]
+[assembly: AssemblyVersion ("4.2.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index ab67b29b11b4457d3c005b3b0668b4855452c68d..c58e46ad97cd03eec0191076f9b3b7c6882de677 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.1.0")]
+[assembly: AssemblyVersion ("4.1.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 00d2b6bddb2fe7371f93ed0258940b0dcbb22139..2e1f8f16a6a41d60889e8963aa2766fe786cafc9 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyVersion ("4.0.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index b81cf3cf99abac106e5c922123fe7d11147c762c..1f3248cdf39d82cfb661a82dfd907eec8d7b2608 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.1.0.0")]
+[assembly: AssemblyVersion ("4.2.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 7fd2f2898cdbcfd89116ffd99c280713c1d756c5..ed555c0a82988cd5fa52a27d8e910f3df120b62a 100644 (file)
@@ -27,6 +27,7 @@
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.LingerOption))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.MulticastOption))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.NetworkStream))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.ProtocolFamily))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.ProtocolType))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.SelectMode))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Sockets.SendPacketsElement))]
index c0542a288f6a3711f878485bbb17934a5ea7b8fc..e354927ba507725ab8d869277536fa1f93c48ced 100644 (file)
@@ -39,7 +39,7 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.1.0")]
+[assembly: AssemblyVersion ("4.0.3.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
 
index c3005ea20a0baa87fa2e422659b82ba7dc5de0b1..fe76e860baae4b28b3d64e4d1af2e7a2eb99b108 100644 (file)
@@ -12,7 +12,7 @@ LIBRARY = System.Runtime.InteropServices.RuntimeInformation.dll
 RESX_RESOURCE_STRING = ../../../../external/corefx/src/System.Runtime.InteropServices.RuntimeInformation/src/Resources/Strings.resx
 
 KEY_FILE = ../../msfinal.pub
-SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699,436
 LIB_REFS = System
 LIB_MCS_FLAGS = $(SIGN_FLAGS) /unsafe
 
index d775167495ea166dcb5719a25ea83b3e87cd3577..4a515083c48f827fc1a950eb1d6a52b018daa0b3 100644 (file)
@@ -35,12 +35,9 @@ namespace System.Runtime.InteropServices
 {
        public static class RuntimeInformation
        {
-               [DllImport ("__Internal")]
-               extern static string mono_get_runtime_build_info ();
-
                public static string FrameworkDescription {
                        get {
-                               return mono_get_runtime_build_info ();
+                               return "Mono " + Mono.Runtime.GetDisplayName ();
                        }
                }
 
index 44acc9076159aac7fec5134bccb4d7ade50dc871..9ae9343c470cf1cadd05ea070de42e3981d8ed83 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.1.1.0")]
+[assembly: AssemblyVersion ("4.2.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 57b2d4db09ccb3689b3f37c1bf4f47cfcb634ab4..ea71c80449cbc24b0d332ebaaa2b06a3928fb11b 100644 (file)
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.DataContractAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.DataMemberAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.EnumMemberAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.ExportOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.ExtensionDataObject))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IExtensibleDataObject))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IgnoreDataMemberAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.InvalidDataContractException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.KnownTypeAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.OnDeserializedAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.OnDeserializingAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.OnSerializingAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.StreamingContext))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.InvalidDataContractException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.StreamingContextStates))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.XmlSerializableServices))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.XPathQueryGenerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.XsdDataContractExporter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IFragmentCapableXmlDictionaryWriter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IStreamProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IXmlBinaryReaderInitializer))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IXmlBinaryWriterInitializer))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IXmlTextReaderInitializer))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.IXmlTextWriterInitializer))]
index c41572f45bf7c5ee4ac35cbc46e16cb41b7861e1..3e0e376278743f2bb215ea7e98ff666907de1734 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.2.0.0")]
+[assembly: AssemblyVersion ("4.3.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index ff615bbfdac7d82fd5326235874360d984396fc8..2a7c09f471414c43021bbe3c9442a31b403cf066 100644 (file)
 // 
 
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Aes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AesManaged))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AsymmetricKeyExchangeDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AsymmetricKeyExchangeFormatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AsymmetricSignatureDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AsymmetricSignatureFormatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptoConfig))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DeriveBytes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DES))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DSA))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DSAParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DSASignatureDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.DSASignatureFormatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECCurve))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECDiffieHellmanPublicKey))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECDsa))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECPoint))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.HMACMD5))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.HMACSHA1))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.HMACSHA256))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.HMACSHA384))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.HMACSHA512))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.MaskGenerationMethod))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.MD5))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.PKCS1MaskGenerationMethod))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RandomNumberGenerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RC2))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Rfc2898DeriveBytes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Rijndael))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RijndaelManaged))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSA))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAEncryptionPadding))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAEncryptionPaddingMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAOAEPKeyExchangeDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAOAEPKeyExchangeFormatter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAPKCS1KeyExchangeDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAPKCS1KeyExchangeFormatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAPKCS1SignatureDeformatter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSAPKCS1SignatureFormatter))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSASignaturePadding))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSASignaturePaddingMode))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA1))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA1Managed))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA256))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA256Managed))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA384))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA384Managed))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA512))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SHA512Managed))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.SignatureDescription))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.TripleDES))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECCurve))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECParameters))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECPoint))]
index 72ee369b0447cc2719c42207db0355f7b680a9d3..47dba143f04fae46a969f90676facd1854f1ddfa 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyVersion ("4.1.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 84dca4216ad47ba8403ae53d48c06b865e0e49c4..3566d5fbcb33f7bebe32ddb9c0cd17a8a9157d32 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.1.0")]
+[assembly: AssemblyVersion ("4.1.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 6610d8849e04c02e163be58b2ebd58daf1215f05..70d43c05ae383e81e0fdb95a47abc8f80f180ca9 100644 (file)
@@ -22,5 +22,6 @@
 
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.IOCompletionCallback))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.NativeOverlapped))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Overlapped))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.PreAllocatedOverlapped))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadPoolBoundHandle))]
index fda0d3b249e56454dfded6370b77d28df2ad9099..a0747feed57e5794be6d1effca4facefae981a65 100644 (file)
@@ -30,6 +30,6 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.1.0")]
+[assembly: AssemblyVersion ("4.0.3.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
index 00626f58ee46f56355ee28425b68be5541218ce6..f2e8ea4a59d60d5aac7d5c77734260c7266c261e 100644 (file)
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.1.0")]
+[assembly: AssemblyVersion ("4.1.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
 
index 76f1c417a02f400a9c9318712cda76b030df122c..c8779956f39ef8786d805eb0ebab2c94922c5076 100644 (file)
@@ -58,9 +58,6 @@ corefx/SR.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversions.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/COperators.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/AggregateDeclaration.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/Declaration.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/GlobalAttributeDeclaration.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Declarations/NamespaceDeclaration.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExplicitConversion.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionBinder.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/ExpressionKind.cs
@@ -91,7 +88,6 @@ corefx/SR.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/EventSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/FieldSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/IndexerSymbol.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/LabelSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/LocalVariableSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/MethodOrPropertySymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/MethodSymbol.cs
@@ -109,13 +105,11 @@ corefx/SR.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymbolTable.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactory.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/SymFactoryBase.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/TransparentIdentifierMemberSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/TypeParameterSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/UnresolvedAggregateSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Symbols/VariableSymbol.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ArrayIndex.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ArrayInitialization.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ArrayLength.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Assignment.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/BinaryOperator.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Block.cs
@@ -125,7 +119,6 @@ corefx/SR.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Class.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/CompoundOperator.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Concatenate.cs
-../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/ConditionalOperator.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Constant.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/Event.cs
 ../../../external/corefx/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Tree/EXPR.cs
index e26c50b01cde1b892035effbd81e3348ff5379c5..ce6b749678d9c5c296dcef1ea33bf45f7021dfe3 100644 (file)
@@ -34,9 +34,16 @@ using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Security.Permissions;
 
-[assembly: AssemblyVersion (Consts.FxVersion)]
 
+
+#if MONO_POSIX_NETSTANDARD_BUILD
+[assembly: AssemblyVersion ("1.0.0.0")]
+[assembly: AssemblyTitle("Mono.Posix.NETStandard.dll")]
+#else
+[assembly: AssemblyVersion (Consts.FxVersion)]
 [assembly: AssemblyTitle("Mono.Posix.dll")]
+#endif
+
 [assembly: AssemblyDescription("Unix Integration Classes")]
 
 [assembly: CLSCompliant (true)]
@@ -48,9 +55,11 @@ using System.Security.Permissions;
 
 */
 
+#if !MONO_POSIX_NETSTANDARD_BUILD
+// We are using ../Open.snk for MONO_POSIX_NETSTANDARD_BUILD
 [assembly: AssemblyDelaySign (true)]
 [assembly: AssemblyKeyFile ("../mono.pub")]
-
+#endif
 /*
  * TODO:
  * 
diff --git a/mcs/class/Mono.Posix/Mono.Posix.NETStandard-netstandard_2_0.csproj b/mcs/class/Mono.Posix/Mono.Posix.NETStandard-netstandard_2_0.csproj
new file mode 100644 (file)
index 0000000..8563586
--- /dev/null
@@ -0,0 +1,35 @@
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+  <PropertyGroup>\r
+    <TargetFramework>netstandard2.0</TargetFramework>\r
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r
+    <AssemblyName>Mono.Posix.NETStandard</AssemblyName>\r
+    <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>\r
+    <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>\r
+    <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>\r
+    <EnableDefaultItems>false</EnableDefaultItems>\r
+    <SignAssembly>true</SignAssembly>\r
+    <DelaySign>true</DelaySign>\r
+    <AssemblyOriginatorKeyFile>..\Open.snk</AssemblyOriginatorKeyFile>\r
+    <!--<BaseIntermediateOutputPath>obj-netstandard2.0</BaseIntermediateOutputPath>\r
+    <IntermediateOutputPath>obj-netstandard2.0</IntermediateOutputPath>-->\r
+  </PropertyGroup>\r
+\r
+  <PropertyGroup>\r
+    <DefineConstants>$(DefineConstants);MONO_POSIX_NETSTANDARD_BUILD</DefineConstants>\r
+  </PropertyGroup>\r
+\r
+  <PropertyGroup Condition="'$(ForceUseLibC)' == 'true'">\r
+    <DefineConstants>$(DefineConstants);FORCE_USE_LIBC_NOT_MSVC</DefineConstants>\r
+  </PropertyGroup>\r
+\r
+  <ItemGroup>\r
+    <Compile Include=".\Assembly\**\*.cs" />\r
+    <Compile Include=".\Mono.Posix\**\*.cs" />\r
+    <Compile Include=".\Mono.Unix\**\*.cs" />\r
+    <Compile Include=".\Mono.Unix.Native\**\*.cs" />\r
+    <Compile Include="..\..\build\common\Locale.cs" />\r
+    <Compile Remove=".\Mono.Unix.Native\CdeclFunction.cs" />\r
+  </ItemGroup>\r
+\r
+</Project>\r
index dbabb29c7f1b70c9544914abb197388d7af0a1ab..59b66ca26fb29dc0e61bfc05ece530bffe03bf18 100644 (file)
@@ -309,6 +309,7 @@ namespace Mono.Unix.Native {
        public delegate void SignalHandler (int signal);
 
 
+#if !NETSTANDARD2_0
        internal class XPrintfFunctions
        {
                internal delegate object XPrintf (object[] parameters);
@@ -335,6 +336,7 @@ namespace Mono.Unix.Native {
                        syslog = new XPrintf (_syslog.Invoke);
                }
        }
+#endif
 
        //
        // Convention: Functions that are part of the C standard library go here.
@@ -378,7 +380,11 @@ namespace Mono.Unix.Native {
        //
        public class Stdlib
        {
+#if FORCE_USE_LIBC_NOT_MSVC
+               internal const string LIBC = "c";
+#else
                internal const string LIBC = "msvcrt";
+#endif
                internal const string MPH  = "MonoPosixHelper";
 
                // It is possible for Mono.Posix and MonoPosixHelper to get out of sync,
@@ -771,6 +777,7 @@ namespace Mono.Unix.Native {
                        return sys_fprintf (stream, "%s", message);
                }
 
+#if !NETSTANDARD2_0
                [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
                                "Use fprintf (IntPtr, string) instead.")]
                public static int fprintf (IntPtr stream, string format, params object[] parameters)
@@ -781,6 +788,7 @@ namespace Mono.Unix.Native {
                        Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
                        return (int) XPrintfFunctions.fprintf (_parameters);
                }
+#endif
 
                /* SKIP: fscanf(3) */
 
@@ -793,6 +801,7 @@ namespace Mono.Unix.Native {
                        return sys_printf ("%s", message);
                }
 
+#if !NETSTANDARD2_0
                [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
                                "Use printf (string) instead.")]
                public static int printf (string format, params object[] parameters)
@@ -802,6 +811,7 @@ namespace Mono.Unix.Native {
                        Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
                        return (int) XPrintfFunctions.printf (_parameters);
                }
+#endif
 
                /* SKIP: scanf(3) */
 
@@ -823,6 +833,7 @@ namespace Mono.Unix.Native {
                        return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
                }
 
+#if !NETSTANDARD2_0
                [CLSCompliant (false)]
                [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
                                "Use snprintf (StringBuilder, string) instead.")]
@@ -853,6 +864,7 @@ namespace Mono.Unix.Native {
                        Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
                        return (int) XPrintfFunctions.snprintf (_parameters);
                }
+#endif
 
                /*
                 * SKIP:
index 4ae330d5b46f74420f5ed35603c04f4f6cae15fc..c750e5fa86b353b625f01b0f5d1227c6a43c4dc4 100644 (file)
@@ -4387,6 +4387,7 @@ namespace Mono.Unix.Native {
                        return UnixMarshal.EscapeFormatString (message, new char[]{'m'});
                }
 
+#if !NETSTANDARD2_0
                [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
                                "Use syslog(SyslogFacility, SyslogLevel, string) instead.")]
                public static int syslog (SyslogFacility facility, SyslogLevel level, 
@@ -4415,6 +4416,7 @@ namespace Mono.Unix.Native {
                        Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
                        return (int) XPrintfFunctions.syslog (_parameters);
                }
+#endif
 
                [DllImport (MPH, SetLastError=true,
                                EntryPoint="Mono_Posix_Syscall_closelog")]
index aa0c06b76c61b87b2f76f222457d2069badf59ac..e429af7f726cc3ade48060848ba35b91604988a5 100644 (file)
@@ -56,7 +56,7 @@ namespace MonoTests.Mono.Unix.Native {
                        Assert.IsFalse (NativeConvert.ToSignum (st.signalReceived) == Signum.SIGURG,
                                        "#IH: Signal Handler invoked when it should have been removed!");
                }
-
+#if !NETCOREAPP2_0
                [Test]
                // MSVCRT.DLL doesn't export snprintf(3).
                [Category ("NotDotNet")]
@@ -92,6 +92,7 @@ namespace MonoTests.Mono.Unix.Native {
                        Assert.AreEqual (s.ToString(), expected,
                                        "#SNPF: printf of many builtin types failed");
                }
+#endif
        }
 }
 
index 84e50a619d6a57f3ed03cb770bece9d664e6d9ae..2019ff147ada8755c24dd360369272f9d852f4ab 100644 (file)
@@ -61,8 +61,10 @@ namespace System.Net.Configuration
                        properties = new ConfigurationPropertyCollection ();
 
                        properties.Add (bypassListProp);
+                       properties.Add (enabledProp);
                        properties.Add (moduleProp);
                        properties.Add (proxyProp);
+                       properties.Add (useDefaultCredentialsProp);
                }
 
                public DefaultProxySection ()
index bce70c4277ca1876cd8b5a961e86481e1f8053e0..bbe366aa292700e84a3a9cd9dc5893cbc24b5f3d 100644 (file)
@@ -62,6 +62,7 @@ namespace System.Net.Configuration
 
                        properties = new ConfigurationPropertyCollection ();
                                                                    
+                       properties.Add (autoDetectProp);
                        properties.Add (bypassOnLocalProp);
                        properties.Add (proxyAddressProp);
                        properties.Add (scriptLocationProp);
index f1f5936be75cab98e14fe59bf44fafafe3cef09f..0ef32ad34334afc54328783b840d15ef2bb45380 100644 (file)
@@ -207,17 +207,6 @@ namespace System.Net.NetworkInformation {
                        return Send (addresses [0], timeout, buffer, options);
                }
 
-               static IPAddress GetNonLoopbackIPV4 ()
-               {
-#pragma warning disable 618
-                       foreach (IPAddress addr in Dns.GetHostByName (Dns.GetHostName ()).AddressList)
-                               if (!IPAddress.IsLoopback (addr) && addr.AddressFamily == AddressFamily.InterNetwork)
-                                       return addr;
-#pragma warning restore 618
-
-                       throw new InvalidOperationException ("Could not resolve non-loopback IP address for localhost");
-               }
-
                public PingReply Send (IPAddress address, int timeout, byte [] buffer, PingOptions options)
                {
                        if (address == null)
@@ -243,8 +232,7 @@ namespace System.Net.NetworkInformation {
                private PingReply SendPrivileged (IPAddress address, int timeout, byte [] buffer, PingOptions options)
                {
                        IPEndPoint target = new IPEndPoint (address, 0);
-                       IPEndPoint client = new IPEndPoint (GetNonLoopbackIPV4 (), 0);
-
+                       
                        // FIXME: support IPv6
                        using (Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)) {
                                if (options != null) {
@@ -264,7 +252,7 @@ namespace System.Net.NetworkInformation {
                                // receive
                                bytes = new byte [100];
                                do {
-                                       EndPoint endpoint = client;
+                                       EndPoint endpoint = target;
                                        SocketError error = 0;
                                        int rc = s.ReceiveFrom (bytes, 0, 100, SocketFlags.None,
                                                        ref endpoint, out error);
diff --git a/mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.platformnotsupported.cs b/mcs/class/System/System.Net.WebSockets/HttpListenerWebSocketContext.platformnotsupported.cs
new file mode 100644 (file)
index 0000000..99fc21b
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// HttpListenerWebSocketContext.platformnotsupported.cs
+//
+// Author:
+//       Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (c) 2017 Xamarin Inc. (http://www.xamarin.com)
+//
+// 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.
+//
+
+namespace System.Net.WebSockets
+{
+       public partial class HttpListenerWebSocketContext : System.Net.WebSockets.WebSocketContext
+       {
+               const string EXCEPTION_MESSAGE = "System.Net.WebSockets.HttpListenerWebSocketContext is not supported on the current platform.";
+
+               private HttpListenerWebSocketContext() { }
+               public override System.Net.CookieCollection CookieCollection { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override System.Collections.Specialized.NameValueCollection Headers { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override bool IsAuthenticated { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override bool IsLocal { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override bool IsSecureConnection { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override string Origin { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override System.Uri RequestUri { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override string SecWebSocketKey { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override System.Collections.Generic.IEnumerable<string> SecWebSocketProtocols { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override string SecWebSocketVersion { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override System.Security.Principal.IPrincipal User { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+               public override System.Net.WebSockets.WebSocket WebSocket { get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); } }
+       }
+}
\ No newline at end of file
index 61e5b6472b96582b820051cf9f4e7de47e65aa85..f20e501c6878d4a4eb5487887e2de1265b12d68b 100644 (file)
@@ -918,8 +918,6 @@ corefx/SR.cs
 ../../../external/corefx/src/System.Net.WebSockets.Client/src/System/Net/WebSockets/ClientWebSocketOptions.cs
 ../../../external/corefx/src/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
 
-../../../external/corefx/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
-
 ../../../external/corefx/src/System.Private.Uri/src/System/UriBuilder.cs
 
 ../../../external/corefx/src/System.Runtime.Extensions/src/System/CodeDom/Compiler/IndentedTextWriter.cs
index 548180b26cb54581b23037a3fba50b27d110973b..f161a1657e9e8f21a53aeb135f7a0271d4ea5b82 100644 (file)
@@ -51,3 +51,5 @@ System.Net/WebConnectionStream.cs
 ../referencesource/System/net/System/Net/Sockets/TCPClient.cs
 ../referencesource/System/net/System/Net/Sockets/TCPListener.cs
 ../referencesource/System/net/System/Net/Sockets/UDPClient.cs
+
+../../../external/corefx/src/System.Net.HttpListener/src/System/Net/WebSockets/HttpListenerWebSocketContext.cs
index ad5e4c7bee884a6c7cc123110d6a27ecf7e6567b..c639ae74fae81646c705daed98799b1a5629ab9e 100644 (file)
@@ -19,4 +19,5 @@ System.Net/HttpWebRequest.platformnotsupported.cs
 System.Net/HttpWebResponse.platformnotsupported.cs
 System.Net/ServicePoint.platformnotsupported.cs
 System.Net/ServicePointManager.platformnotsupported.cs
+System.Net.WebSockets/HttpListenerWebSocketContext.platformnotsupported.cs
 ../Mono.Security/Mono.Security.X509.Extensions/AuthorityKeyIdentifierExtension.cs
index 9cd987fabb54d3737dabbaf25aa38a4dba2c437f..d070a293e3680d8ed0e22f05c90918f313f93dd2 100644 (file)
@@ -8,7 +8,7 @@ thisdir = class/aot-compiler
 
 include ../../build/rules.make
 
-the_libdir = $(topdir)/class/lib/$(PROFILE)/
+the_libdir = $(topdir)/class/lib/$(PROFILE_DIRECTORY)/
 CSC_DIR = $(dir $(CSC_LOCATION))
 # The directory where the AOT images are stored
 images_dir = $(the_libdir)
@@ -38,6 +38,8 @@ runtime_dep = $(dir $(RUNTIME))/../mono/mini/mono
 PROGRAM_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)
 LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)
 
+LOG_FILE = $(PROFILE_DIRECTORY)_aot.log
+
 ifndef SKIP_AOT
 
 profile_file:=$(wildcard $(topdir)/class/lib/build/csc.*.aotprofile)
@@ -50,32 +52,32 @@ endif
 
 ifdef PLATFORM_AOT_SUFFIX
 $(mcs_aot_image): $(mcs_exe) $(mscorlib_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(mcs_aot_image) --debug $(mcs_exe) || cat $(PROFILE)_aot.log || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(mcs_aot_image) --debug $(mcs_exe) || cat $(LOG_FILE) || (cat $(LOG_FILE); exit 1)
 
 $(csc_aot_image): $(csc_exe) $(mscorlib_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_aot_image) --debug $(csc_exe) || cat $(PROFILE)_aot.log || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_aot_image) --debug $(csc_exe) || cat $(LOG_FILE) || (cat $(LOG_FILE); exit 1)
 
 $(mscorlib_aot_image): $(mscorlib_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg) --debug $(mscorlib_dll) || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg) --debug $(mscorlib_dll) || (cat $(LOG_FILE); exit 1)
 
 $(csc_MC_image): $(csc_MC_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_MC_image) --debug $(csc_MC_dll) || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_MC_image) --debug $(csc_MC_dll) || (cat $(LOG_FILE); exit 1)
 
 $(csc_MCS_image): $(csc_MCS_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_MCS_image) --debug $(csc_MCS_dll) || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_MCS_image) --debug $(csc_MCS_dll) || (cat $(LOG_FILE); exit 1)
 
 $(csc_SRM_image): $(csc_SRM_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_SRM_image) --debug --apply-bindings=$(csc_exe).config $(csc_SRM_dll) || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_SRM_image) --debug --apply-bindings=$(csc_exe).config $(csc_SRM_dll) || (cat $(LOG_FILE); exit 1)
 
 $(csc_SCI_image): $(csc_SCI_dll) $(runtime_dep)
-       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_SCI_image) --debug $(csc_SCI_dll) || (cat $(PROFILE)_aot.log; exit 1)
+       $(Q_AOT) MONO_PATH='$(the_libdir)' > $(LOG_FILE) 2>&1 $(RUNTIME) --aot=bind-to-runtime-version$(profile_arg),outfile=$(csc_SCI_image) --debug $(csc_SCI_dll) || (cat $(LOG_FILE); exit 1)
 
 ifdef ENABLE_AOT
 
 CSC_IMAGES = $(csc_aot_image) $(csc_SRM_image) $(csc_SCI_image) $(csc_MC_image) $(csc_MCS_image)
 
 clean-local:
-       -rm -f $(mscorlib_aot_image) $(mcs_aot_image) $(CSC_IMAGES) $(PROFILE)_aot.log
+       -rm -f $(mscorlib_aot_image) $(mcs_aot_image) $(CSC_IMAGES) $(LOG_FILE)
 
 # AOT build profile to speed up build
 ifeq ($(PROFILE),build)
index 6e1e9ef1264ab13c08957d9d6938eeed71c9497a..54b21cdf3ba79901f7b577047b3c3222d27b4ef3 100644 (file)
@@ -79,6 +79,8 @@ using System.Runtime.InteropServices;
 [assembly: InternalsVisibleTo ("System.Runtime.WindowsRuntime, PublicKey=00000000000000000400000000000000")]
 [assembly: InternalsVisibleTo ("System.Runtime.WindowsRuntime.UI.Xaml, PublicKey=00000000000000000400000000000000")]
 
+[assembly: InternalsVisibleTo ("System.Runtime.InteropServices.RuntimeInformation, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
+
 #if MONOTOUCH
 #if MONOTOUCH_TV
 [assembly: InternalsVisibleTo ("Xamarin.TVOS, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
diff --git a/mcs/errors/cs0535-7.cs b/mcs/errors/cs0535-7.cs
new file mode 100644 (file)
index 0000000..11a7670
--- /dev/null
@@ -0,0 +1,40 @@
+// CS0535: `CC' does not implement interface member `IA.Coordinate.set'
+// Line: 33
+
+using System;
+
+public interface IA
+{
+       object Coordinate {
+               get;
+               set;
+       }
+}
+
+public abstract class CA : IA
+{
+       public abstract object Coordinate {
+               get;
+               set;
+       }
+}
+
+public  partial class CB : CA
+{
+       public override object Coordinate {
+               get {
+                       throw new NotImplementedException ();
+               }
+               set {
+               }
+       }
+}
+
+public class CC : CB, IA
+{
+       public new object Coordinate {
+               get {
+                       throw new NotImplementedException ();
+               }
+       }
+}
diff --git a/mcs/errors/cs0535-8.cs b/mcs/errors/cs0535-8.cs
new file mode 100644 (file)
index 0000000..853794e
--- /dev/null
@@ -0,0 +1,40 @@
+// CS0535: `CC' does not implement interface member `IA.this[int].set'
+// Line: 33
+
+using System;
+
+public interface IA
+{
+       object this[int arg] {
+               get;
+               set;
+       }
+}
+
+public abstract class CA : IA
+{
+       public abstract object this[int arg] {
+               get;
+               set;
+       }
+}
+
+public  partial class CB : CA
+{
+       public override object this[int arg] {
+               get {
+                       throw new NotImplementedException ();
+               }
+               set {
+               }
+       }
+}
+
+public class CC : CB, IA
+{
+       public new object this[int arg] {
+               get {
+                       throw new NotImplementedException ();
+               }
+       }
+}
index c054330db202f339be76b7a07f01626fd207f7fe..9042dcdabad8e5405cbbbc086953ade32d7dfc81 100644 (file)
@@ -7570,14 +7570,21 @@ namespace Mono.CSharp
                        bool is_value_type = type.IsStructOrEnum;
                        VariableReference vr = target as VariableReference;
 
+                       bool prepare_await = ec.HasSet (BuilderContext.Options.AsyncBody) && arguments?.ContainsEmitWithAwait () == true;
+
                        if (target != null && is_value_type && (vr != null || method == null)) {
+                               if (prepare_await) {
+                                       arguments = arguments.Emit (ec, false, true);
+                                       prepare_await = false;
+                               }
+                               
                                target.AddressOf (ec, AddressOp.Store);
                        } else if (vr != null && vr.IsRef) {
                                vr.EmitLoad (ec);
                        }
 
                        if (arguments != null) {
-                               if (ec.HasSet (BuilderContext.Options.AsyncBody) && (arguments.Count > (this is NewInitialize ? 0 : 1)) && arguments.ContainsEmitWithAwait ())
+                               if (prepare_await)
                                        arguments = arguments.Emit (ec, false, true);
 
                                arguments.Emit (ec);
index 87ebf6aac54fb54c69fc2239f9033f11e67498d2..dbec2c0469f603bce116c228d4a3252b2abc85be 100644 (file)
@@ -414,6 +414,9 @@ namespace Mono.CSharp
                                kind = MemberKind.Constructor;
                                returnType = module.Compiler.BuiltinTypes.Void;
                        } else {
+                               var mi = (MethodInfo)mb;
+                               returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter), declaringType);
+
                                //
                                // Detect operators and destructors
                                //
@@ -427,7 +430,7 @@ namespace Mono.CSharp
                                                                kind = MemberKind.Operator;
                                                        }
                                                }
-                                       } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
+                                       } else if (parameters.IsEmpty && name == Destructor.MetadataName && returnType.Kind == MemberKind.Void) {
                                                kind = MemberKind.Destructor;
                                                if (declaringType.BuiltinType == BuiltinTypeSpec.Type.Object) {
                                                        mod &= ~Modifiers.OVERRIDE;
@@ -436,9 +439,6 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               var mi = (MethodInfo) mb;
-                               returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter), declaringType);
-
                                // Cannot set to OVERRIDE without full hierarchy checks
                                // this flag indicates that the method could be override
                                // but further validation is needed
@@ -645,14 +645,7 @@ namespace Mono.CSharp
                                        if (set_param_count == 0) {
                                                set_based_param = ParametersCompiled.EmptyReadOnlyParameters;
                                        } else {
-                                               //
-                                               // Create indexer parameters based on setter method parameters (the last parameter has to be removed)
-                                               //
-                                               var data = new IParameterData[set_param_count];
-                                               var types = new TypeSpec[set_param_count];
-                                               Array.Copy (set.Parameters.FixedParameters, data, set_param_count);
-                                               Array.Copy (set.Parameters.Types, types, set_param_count);
-                                               set_based_param = new ParametersImported (data, types, set.Parameters.HasParams);
+                                               set_based_param = IndexerSpec.CreateParametersFromSetter (set, set_param_count);
                                        }
 
                                        mod = set.Modifiers;
index 275f1013e8b9dfb533215ddeaeb466e4d4a8faf9..1360dbdfd65c3cc4144c8e26b052c4fb200e796f 100644 (file)
@@ -142,6 +142,9 @@ namespace Mono.CSharp {
        }
 
        public class ParamsParameter : Parameter {
+
+               bool ParamsAttributeEmit;
+
                public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
                        base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
                {
@@ -158,13 +161,18 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       var mc = ec as MemberCore;
+                       ParamsAttributeEmit = mc == null || (mc.ModFlags & Modifiers.OVERRIDE) == 0;
+
                        return parameter_type;
                }
 
                public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
                {
                        base.ApplyAttributes (mb, cb, index, pa);
-                       pa.ParamArray.EmitAttribute (builder);
+
+                       if (ParamsAttributeEmit)
+                               pa.ParamArray.EmitAttribute (builder);
                }
        }
 
index 661142822f802a9f55ed7560eb510ca5c30c1f50..507b937e2c904310786e8798ee2196d2ef52dcb2 100644 (file)
@@ -147,7 +147,6 @@ namespace Mono.CSharp {
                        int i = 0;
                        if (abstract_methods != null) {
                                int count = abstract_methods.Length;
-                               pending_implementations [i].methods = new MethodSpec [count];
                                pending_implementations [i].need_proxy = new MethodSpec [count];
 
                                pending_implementations [i].methods = abstract_methods;
@@ -527,7 +526,47 @@ namespace Mono.CSharp {
                bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method)
                {
                        base_method = null;
-                       var base_type = container.BaseType;
+                       bool base_can_implement = true;
+                       TypeSpec lookup_type;
+
+                       //
+                       // Special handling for properties/indexers which cannot have accessors
+                       // implementing an interface found in different types (e.g. current and base)
+                       //
+                       if (mi.IsAccessor && container.Interfaces != null) {
+
+                               bool new_implementation = false;
+                               foreach (var iface in container.Interfaces) {
+                                       if (TypeSpecComparer.IsEqual (iface, iface_type)) {
+                                               new_implementation = true;
+                                               break;
+                                       }
+                               }
+
+                               if (new_implementation) {
+                                       MemberFilter filter;
+                                       if (mi.Parameters.Count > 1) {
+                                               var indexer_params = mi.Name [0] == 'g' ? mi.Parameters : IndexerSpec.CreateParametersFromSetter (mi, mi.Parameters.Count - 1);
+                                               filter = new MemberFilter (MemberCache.IndexerNameAlias, 0, MemberKind.Indexer, indexer_params, null);
+                                       } else {
+                                               var pname = mi.Name.Substring (4);
+                                               filter = MemberFilter.Property (pname, null);
+                                       }
+
+                                       var prop = MemberCache.FindMember (container.CurrentType, filter, BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly);
+                                       if (prop != null && (prop.Modifiers & Modifiers.NEW) != 0)
+                                               base_can_implement = false;
+                               }
+                       }
+
+                       if (base_can_implement) {
+                               lookup_type = container.BaseType;
+
+                               if (lookup_type.ImplementsInterface (iface_type, false))
+                                       return true;
+                       } else {
+                               lookup_type = container.CurrentType;
+                       }
 
                        //
                        // Setup filter with no return type to give better error message
@@ -537,7 +576,7 @@ namespace Mono.CSharp {
                        MethodSpec close_match = null;
 
                        while (true) {
-                               var candidates = MemberCache.FindMembers (base_type, mi.Name, false);
+                               var candidates = MemberCache.FindMembers (lookup_type, mi.Name, !base_can_implement);
                                if (candidates == null) {
                                        base_method = close_match;
                                        return false;
@@ -630,8 +669,11 @@ namespace Mono.CSharp {
                                        break;
                                }
 
-                               base_type = candidates[0].DeclaringType.BaseType;
-                               if (base_type == null) {
+                               if (!base_can_implement)
+                                       return false;
+
+                               lookup_type = candidates[0].DeclaringType.BaseType;
+                               if (lookup_type == null) {
                                        base_method = close_match;
                                        return false;
                                }
@@ -668,10 +710,6 @@ namespace Mono.CSharp {
                        for (i = 0; i < top; i++){
                                TypeSpec type = pending_implementations [i].type;
 
-                               bool base_implements_type = type.IsInterface &&
-                                       container.BaseType != null &&
-                                       container.BaseType.ImplementsInterface (type, false);
-
                                for (int j = 0; j < pending_implementations [i].methods.Count; ++j) {
                                        var mi = pending_implementations[i].methods[j];
                                        if (mi == null)
@@ -686,11 +724,8 @@ namespace Mono.CSharp {
                                                        continue;
                                                }
 
-                                               if (pending_implementations [i].optional)
-                                                       continue;
-
                                                MethodSpec candidate;
-                                               if (base_implements_type || BaseImplements (type, mi, out candidate))
+                                               if (BaseImplements (type, mi, out candidate))
                                                        continue;
 
                                                if (candidate == null) {
index 5d831e940b523b144287c7e0d47f0394e3677147..0d4efedbd1e6465e4df5f4e50eaa67e07e86db7b 100644 (file)
@@ -1793,6 +1793,18 @@ namespace Mono.CSharp
                }
                #endregion
 
+               public static ParametersImported CreateParametersFromSetter (MethodSpec setter, int set_param_count)
+               {
+                       //
+                       // Creates indexer parameters based on setter method parameters (the last parameter has to be removed)
+                       //
+                       var data = new IParameterData [set_param_count];
+                       var types = new TypeSpec [set_param_count];
+                       Array.Copy (setter.Parameters.FixedParameters, data, set_param_count);
+                       Array.Copy (setter.Parameters.Types, types, set_param_count);
+                       return new ParametersImported (data, types, setter.Parameters.HasParams);
+               }
+
                public override string GetSignatureForDocumentation ()
                {
                        return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation ();
index 20eb19e6cee8b4fb54b7df5d9ff4e57338f1a680..d500eea093d32debf0b5c50349e69d810d8ccd0d 100644 (file)
@@ -7459,6 +7459,10 @@ namespace Mono.CSharp {
                                                ec.Emit (OpCodes.Br, end);
 
                                        ec.MarkLabel (labels [i + 1]);
+
+                                       ec.EmitInt (0);
+                                       ec.Emit (OpCodes.Stloc, state_variable);
+
                                        c = catch_sm [i];
                                        ec.AsyncThrowVariable = c.Variable;
                                        c.Block.Emit (ec);
diff --git a/mcs/tests/test-944-lib.cs b/mcs/tests/test-944-lib.cs
new file mode 100644 (file)
index 0000000..4c91eff
--- /dev/null
@@ -0,0 +1,9 @@
+// Compiler options: -t:library
+
+public class Class1
+{
+       public byte[] Finalize ()
+       {
+               return null;
+       }
+}
diff --git a/mcs/tests/test-944.cs b/mcs/tests/test-944.cs
new file mode 100644 (file)
index 0000000..4aff1f8
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -r:test-944-lib.dll
+
+public class Class2
+{
+       public static void Main ()
+       {
+               var writer = new Class1();
+               byte[] bytes = writer.Finalize();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-945.cs b/mcs/tests/test-945.cs
new file mode 100644 (file)
index 0000000..398787d
--- /dev/null
@@ -0,0 +1,22 @@
+public abstract class A
+{
+       public abstract void Bind (string [] args);
+}
+
+public class B : A
+{
+       public override void Bind (params string [] args)
+       {
+       }
+
+       public static int Main ()
+       {
+               var m = typeof (B).GetMethod ("Bind");
+               var p = m.GetParameters ();
+               var ca = p[0].GetCustomAttributes (false);
+               if (ca.Length != 0)
+                       return 1;
+               
+               return 0;
+       }
+}
diff --git a/mcs/tests/test-async-92.cs b/mcs/tests/test-async-92.cs
new file mode 100644 (file)
index 0000000..e41ac00
--- /dev/null
@@ -0,0 +1,22 @@
+using System.Threading.Tasks;
+
+public class A
+{
+       public async Task<ValueType> Test1 (int input2)
+       {
+               return new ValueType (await Task.FromResult (12345));
+       }
+
+       public static void Main ()
+       {
+               var a = new A ();
+               a.Test1 (1).Wait ();
+       }
+}
+
+public struct ValueType
+{
+       public ValueType (int field2)
+       {
+       }
+}
diff --git a/mcs/tests/test-async-93.cs b/mcs/tests/test-async-93.cs
new file mode 100644 (file)
index 0000000..249de2a
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using System.Threading.Tasks;
+public class Test
+{
+       public static int Main()
+       {
+               var t = new Test ();
+               t.Entry().Wait();
+               if (t.caughtCounter != 1)
+                       return 1;
+
+               return 0;
+       }
+       int caughtCounter;
+
+       async Task Entry()
+       {
+               for (int i = 0; i < 5; ++i) {
+                       try {
+                               var result = Func(i);
+                               Console.WriteLine($"{i} result {result}");
+                       } catch (Exception e) {
+                               await Nothing();
+                               Console.WriteLine($"{i} caught");
+                               ++caughtCounter;
+                       }
+               }
+       }
+       bool Func(int i)
+       {
+               if (i == 0) {
+                       throw new Exception();
+               } else {
+                       return true;
+               }
+       }
+       async Task Nothing()
+       {
+       }
+}
\ No newline at end of file
index 4882b788602ee9e5fb99495bac6bd98d1c8d546c..ba198950ecb0d34e6f3ae94feaf94a94fdd5f11a 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-943.cs">
+    <type name="MyStruct">
+      <method name="Int32 get_X()" attrs="2182">
+        <size>14</size>
+      </method>
+      <method name="Void set_X(Int32)" attrs="2182">
+        <size>8</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="Int32 Main()" attrs="150">
+        <size>44</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-944.cs">
+    <type name="Class2">
+      <method name="Void Main()" attrs="150">
+        <size>15</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-945.cs">
+    <type name="A">
+      <method name="Void Bind(System.String[])" attrs="1478">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor()" attrs="6276">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="B">
+      <method name="Void Bind(System.String[])" attrs="198">
+        <size>2</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>63</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-95.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
     </type>
     <type name="C+&lt;TestSingleAwait&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>274</size>
+        <size>276</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="C+&lt;TestDoubleAwait&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>419</size>
+        <size>423</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="C+&lt;TestRethrow&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>363</size>
+        <size>367</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Test+&lt;BreakTest&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>903</size>
+        <size>906</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Test+&lt;ContinueTest&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>903</size>
+        <size>906</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Program+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>543</size>
+        <size>545</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Program+&lt;Test2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>398</size>
+        <size>400</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Test+&lt;AsyncWithDeepTry&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>460</size>
+        <size>463</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
   </test>
+  <test name="test-async-92.cs">
+    <type name="A">
+      <method name="System.Threading.Tasks.Task`1[ValueType] Test1(Int32)" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>20</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="ValueType">
+      <method name="Void .ctor(Int32)" attrs="6278">
+        <size>2</size>
+      </method>
+    </type>
+    <type name="A+&lt;Test1&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>174</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-async-93.cs">
+    <type name="Test">
+      <method name="Int32 Main()" attrs="150">
+        <size>46</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Entry()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="Boolean Func(Int32)" attrs="129">
+        <size>24</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Nothing()" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test+&lt;Entry&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>344</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="Test+&lt;Nothing&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>61</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">
     </type>
     <type name="X+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>281</size>
+        <size>283</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="X+&lt;TestGeneric&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>250</size>
+        <size>252</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
     </type>
     <type name="Test+&lt;TestCapturedException&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>491</size>
+        <size>495</size>
       </method>
       <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
         <size>13</size>
index 246eec3b68c4605605751b6ac8490decd568b380..ef9df2a5cb295d6828d0b2bd6aa613e2eee93fed 100644 (file)
@@ -193,6 +193,7 @@ common_sources = \
        mono-endian.c           \
        mono-endian.h           \
        mono-hash.h             \
+       mono-conc-hash.h                \
        mono-mlist.c            \
        mono-mlist.h            \
        mono-perfcounters.c     \
@@ -280,6 +281,7 @@ gc_dependent_sources = \
        gc.c            \
        monitor.c       \
        mono-hash.c     \
+       mono-conc-hash.c        \
        object.c        \
        dynamic-image.c \
        sre.c   \
index ee0695ceccfbdb32dd39229a366fef7f3f01824d..4ed4f39da3dc5d648fa30936fb8d50f1d3fd7974 100644 (file)
@@ -9106,10 +9106,25 @@ mono_class_get_methods (MonoClass* klass, gpointer *iter)
 static MonoMethod*
 mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
 {
-       MonoMethod** method;
+       gboolean static_iter = FALSE;
+
        if (!iter)
                return NULL;
-       if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) {
+
+       /*
+        * If the lowest bit of the iterator is 1, this is an iterator for static metadata,
+        * and the upper bits contain an index. Otherwise, the iterator is a pointer into
+        * klass->methods.
+        */
+       if ((gsize)(*iter) & 1)
+               static_iter = TRUE;
+       /* Use the static metadata only if klass->methods is not yet initialized */
+       if (!static_iter && !(klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)))
+               static_iter = TRUE;
+
+       if (!static_iter) {
+               MonoMethod** methodptr;
+
                if (!*iter) {
                        mono_class_setup_methods (klass);
                        /*
@@ -9119,20 +9134,22 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                        if (!klass->methods)
                                return NULL;
                        /* start from the first */
-                       method = &klass->methods [0];
+                       methodptr = &klass->methods [0];
                } else {
-                       method = (MonoMethod **)*iter;
-                       method++;
+                       methodptr = (MonoMethod **)*iter;
+                       methodptr++;
                }
+               if (*iter)
+                       g_assert ((guint64)(*iter) > 0x100);
                int mcount = mono_class_get_method_count (klass);
-               while (method < &klass->methods [mcount]) {
-                       if (*method && ((*method)->flags & METHOD_ATTRIBUTE_VIRTUAL))
+               while (methodptr < &klass->methods [mcount]) {
+                       if (*methodptr && ((*methodptr)->flags & METHOD_ATTRIBUTE_VIRTUAL))
                                break;
-                       method ++;
+                       methodptr ++;
                }
-               if (method < &klass->methods [mcount]) {
-                       *iter = method;
-                       return *method;
+               if (methodptr < &klass->methods [mcount]) {
+                       *iter = methodptr;
+                       return *methodptr;
                } else {
                        return NULL;
                }
@@ -9144,7 +9161,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                if (!*iter) {
                        start_index = 0;
                } else {
-                       start_index = GPOINTER_TO_UINT (*iter);
+                       start_index = GPOINTER_TO_UINT (*iter) >> 1;
                }
 
                int first_idx = mono_class_get_first_method_idx (klass);
@@ -9165,7 +9182,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                        mono_error_cleanup (&error); /* FIXME don't swallow the error */
 
                        /* Add 1 here so the if (*iter) check fails */
-                       *iter = GUINT_TO_POINTER (i + 1);
+                       *iter  = GUINT_TO_POINTER (((i + 1) << 1) | 1);
                        return res;
                } else {
                        return NULL;
index 86309ef20234d4dd559726f0c9fcfe1a32f08e32..d522657b62f0b97efa9792ba77734e29d2882e12 100644 (file)
@@ -1090,7 +1090,7 @@ mono_cominterop_get_invoke (MonoMethod *method)
        for (i = 1; i <= sig->param_count; i++)
                mono_mb_emit_ldarg (mb, i);
 
-       if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+       if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || mono_class_is_interface (method->klass)) {
                MonoMethod * native_wrapper = mono_cominterop_get_native_wrapper(method);
                mono_mb_emit_managed_call (mb, native_wrapper, NULL);
        }
index c9fb4add3dd46edb349dc33e980c637972a8d059..6d8042c07680206f4ed4778cf056266fa67bba2f 100644 (file)
@@ -12,6 +12,7 @@
 #include <mono/metadata/lock-tracer.h>
 #include <mono/utils/mono-codeman.h>
 #include <mono/metadata/mono-hash.h>
+#include <mono/metadata/mono-conc-hash.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-internal-hash.h>
 #include <mono/metadata/mempool-internals.h>
@@ -69,6 +70,7 @@ struct _MonoJitInfoTable
 {
        MonoDomain             *domain;
        int                     num_chunks;
+       int                     num_valid;
        MonoJitInfoTableChunk  *chunks [MONO_ZERO_LEN_ARRAY];
 };
 
@@ -241,6 +243,8 @@ struct _MonoJitInfo {
         * d.tramp_info contains additional data in this case.
         */
        gboolean    is_trampoline:1;
+       /* Whenever this jit info refers to an interpreter method */
+       gboolean    is_interp:1;
 
        /* FIXME: Embed this after the structure later*/
        gpointer    gc_info; /* Currently only used by SGen */
@@ -336,7 +340,7 @@ struct _MonoDomain {
        MonoGHashTable     *ldstr_table;
        /* hashtables for Reflection handles */
        MonoGHashTable     *type_hash;
-       MonoGHashTable     *refobject_hash;
+       MonoConcGHashTable     *refobject_hash;
        /* maps class -> type initialization exception object */
        MonoGHashTable    *type_init_exception_hash;
        /* maps delegate trampoline addr -> delegate object */
index 2e6a52170078f5487e79fb00c2df5e32508b741b..7a12a7f4f727df945ec2a21815c6dbece75bce0b 100644 (file)
@@ -1037,10 +1037,6 @@ mono_domain_free (MonoDomain *domain, gboolean force)
 
        mono_debug_domain_unload (domain);
 
-       mono_appdomains_lock ();
-       appdomains_list [domain->domain_id] = NULL;
-       mono_appdomains_unlock ();
-
        /* must do this early as it accesses fields and types */
        if (domain->special_static_fields) {
                mono_alloc_special_static_data_free (domain->special_static_fields);
@@ -1214,6 +1210,10 @@ mono_domain_free (MonoDomain *domain, gboolean force)
 
        mono_gc_deregister_root ((char*)&(domain->MONO_DOMAIN_FIRST_GC_TRACKED));
 
+       mono_appdomains_lock ();
+       appdomains_list [domain->domain_id] = NULL;
+       mono_appdomains_unlock ();
+
        /* FIXME: anything else required ? */
 
        mono_gc_free_fixed (domain);
index cf9992615e836ad1ce9f8c074b9dfef1f59d5d7f..085fb67a3759d029dbfafca2fab6a61251d04c7c 100644 (file)
@@ -62,21 +62,7 @@ static MonoJitInfoFindInAot jit_info_find_in_aot_func = NULL;
 static int
 jit_info_table_num_elements (MonoJitInfoTable *table)
 {
-       int i;
-       int num_elements = 0;
-
-       for (i = 0; i < table->num_chunks; ++i) {
-               MonoJitInfoTableChunk *chunk = table->chunks [i];
-               int chunk_num_elements = chunk->num_elements;
-               int j;
-
-               for (j = 0; j < chunk_num_elements; ++j) {
-                       if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j]))
-                               ++num_elements;
-               }
-       }
-
-       return num_elements;
+       return table->num_valid;
 }
 
 static MonoJitInfoTableChunk*
@@ -96,6 +82,7 @@ mono_jit_info_table_new (MonoDomain *domain)
        table->domain = domain;
        table->num_chunks = 1;
        table->chunks [0] = jit_info_table_new_chunk ();
+       table->num_valid = 0;
 
        return table;
 }
@@ -397,6 +384,7 @@ jit_info_table_realloc (MonoJitInfoTable *old)
        result = (MonoJitInfoTable *)g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*) * num_chunks);
        result->domain = old->domain;
        result->num_chunks = num_chunks;
+       result->num_valid = old->num_valid;
 
        for (i = 0; i < num_chunks; ++i)
                result->chunks [i] = jit_info_table_new_chunk ();
@@ -469,6 +457,7 @@ jit_info_table_copy_and_split_chunk (MonoJitInfoTable *table, MonoJitInfoTableCh
 
        new_table->domain = table->domain;
        new_table->num_chunks = table->num_chunks + 1;
+       new_table->num_valid = table->num_valid;
 
        j = 0;
        for (i = 0; i < table->num_chunks; ++i) {
@@ -517,6 +506,7 @@ jit_info_table_copy_and_purify_chunk (MonoJitInfoTable *table, MonoJitInfoTableC
 
        new_table->domain = table->domain;
        new_table->num_chunks = table->num_chunks;
+       new_table->num_valid = table->num_valid;
 
        j = 0;
        for (i = 0; i < table->num_chunks; ++i) {
@@ -651,6 +641,8 @@ jit_info_table_add (MonoDomain *domain, MonoJitInfoTable *volatile *table_ptr, M
        chunk->last_code_end = (gint8*)chunk->data [chunk->num_elements - 1]->code_start
                + chunk->data [chunk->num_elements - 1]->code_size;
 
+       ++table->num_valid;
+
        /* Debugging code, should be removed. */
        //jit_info_table_check (table);
 }
@@ -732,6 +724,7 @@ jit_info_table_remove (MonoJitInfoTable *table, MonoJitInfo *ji)
        g_assert (chunk->data [pos] == ji);
 
        chunk->data [pos] = mono_jit_info_make_tombstone (chunk, ji);
+       --table->num_valid;
 
        /* Debugging code, should be removed. */
        //jit_info_table_check (table);
index d2cf14781b077e8f00e6371770e1996bdb0c3f7f..3458232139c4d3a83dac251c024476ef30e19fd8 100644 (file)
@@ -61,6 +61,20 @@ g_slist_append_mempool (MonoMemPool *mp, GSList *list, gpointer data)
                return new_list;
 }
 
+static inline GList*
+g_list_append_mempool (MonoMemPool *mp, GList *list, gpointer data)
+{
+       GList *new_list;
+
+       new_list = (GList *) mono_mempool_alloc0 (mp, sizeof (GList));
+       new_list->data = data;
+       new_list->prev = g_list_last (list);
+       if (new_list->prev)
+               new_list->prev->next = new_list;
+
+       return list ? list : new_list;
+}
+
 char*
 mono_mempool_strdup_vprintf (MonoMemPool *pool, const char *format, va_list args);
 
diff --git a/mono/metadata/mono-conc-hash.c b/mono/metadata/mono-conc-hash.c
new file mode 100644 (file)
index 0000000..c0bdb02
--- /dev/null
@@ -0,0 +1,454 @@
+/**
+ * \file
+ * Conc GC aware Hashtable implementation
+ *
+ * Author:
+ *   Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ */
+#include <config.h>
+#include <stdio.h>
+#include <math.h>
+#include <glib.h>
+#include "mono-conc-hash.h"
+#include "metadata/gc-internals.h"
+#include <mono/utils/checked-build.h>
+#include <mono/utils/mono-threads-coop.h>
+
+#ifdef HAVE_BOEHM_GC
+#define mg_new0(type,n)  ((type *) GC_MALLOC(sizeof(type) * (n)))
+#define mg_new(type,n)   ((type *) GC_MALLOC(sizeof(type) * (n)))
+#define mg_free(x)       do { } while (0)
+#else
+#define mg_new0(x,n)     g_new0(x,n)
+#define mg_new(type,n)   g_new(type,n)
+#define mg_free(x)       g_free(x)
+#endif
+
+#define INITIAL_SIZE 32
+#define LOAD_FACTOR 0.75f
+#define PTR_TOMBSTONE ((gpointer)(ssize_t)-1)
+/* Expand ration must be a power of two */
+#define EXPAND_RATIO 2
+
+typedef struct {
+       int table_size;
+       MonoGHashGCType gc_type;
+       void **keys;
+       void **values;
+} conc_table;
+
+struct _MonoConcGHashTable {
+       volatile conc_table *table; /* goes to HP0 */
+       GHashFunc hash_func;
+       GEqualFunc equal_func;
+       int element_count;
+       int overflow_count;
+       GDestroyNotify key_destroy_func;
+       GDestroyNotify value_destroy_func;
+       MonoGHashGCType gc_type;
+       MonoGCRootSource source;
+       const char *msg;
+};
+
+
+static conc_table*
+conc_table_new (MonoConcGHashTable *hash, int size)
+{
+#ifdef HAVE_SGEN_GC
+       conc_table *table = mg_new0 (conc_table, 1);
+#else
+       conc_table *table = mono_gc_alloc_fixed (sizeof (conc_table), MONO_GC_ROOT_DESCR_FOR_FIXED (sizeof (conc_table)), hash->source, hash->msg);
+#endif
+       
+       table->keys = mg_new0 (void*, size);
+       table->values = mg_new0 (void*, size);
+       table->table_size = size;
+       table->gc_type = hash->gc_type;
+
+#ifdef HAVE_SGEN_GC
+       if (hash->gc_type & MONO_HASH_KEY_GC)
+               mono_gc_register_root_wbarrier ((char*)table->keys, sizeof (MonoObject*) * size, mono_gc_make_vector_descr (), hash->source, hash->msg);
+       if (hash->gc_type & MONO_HASH_VALUE_GC)
+               mono_gc_register_root_wbarrier ((char*)table->values, sizeof (MonoObject*) * size, mono_gc_make_vector_descr (), hash->source, hash->msg);
+#endif
+
+       return table;
+}
+
+static void
+conc_table_free (gpointer ptr)
+{
+       conc_table *table = (conc_table *)ptr;
+#ifdef HAVE_SGEN_GC
+       if (table->gc_type & MONO_HASH_KEY_GC)
+               mono_gc_deregister_root ((char*)table->keys);
+       if (table->gc_type & MONO_HASH_VALUE_GC)
+               mono_gc_deregister_root ((char*)table->values);
+#endif
+
+       mg_free (table->keys);
+       mg_free (table->values);
+#ifdef HAVE_SGEN_GC
+       mg_free (table);
+#else
+       mono_gc_free_fixed (table);
+#endif
+}
+
+static void
+conc_table_lf_free (conc_table *table)
+{
+       mono_thread_hazardous_try_free (table, conc_table_free);
+}
+
+
+static gboolean
+key_is_tombstone (MonoConcGHashTable *hash, gpointer ptr)
+{
+       if (hash->gc_type & MONO_HASH_KEY_GC)
+               return ptr == mono_domain_get()->ephemeron_tombstone;
+       return ptr == PTR_TOMBSTONE;
+}
+
+/*
+A common problem with power of two hashtables is that it leads of bad clustering when dealing
+with aligned numbers.
+
+The solution here is to mix the bits from two primes plus the hash itself, it produces a better spread
+than just the numbers.
+*/
+
+static MONO_ALWAYS_INLINE int
+mix_hash (int hash)
+{
+       return ((hash * 215497) >> 16) ^ (hash * 1823231 + hash);
+}
+
+
+static inline void
+set_key (conc_table *table, int slot, gpointer key)
+{
+       gpointer *key_addr = &table->keys [slot];
+       if (table->gc_type & MONO_HASH_KEY_GC)
+               mono_gc_wbarrier_generic_store (key_addr, key);
+       else
+               *key_addr = key;
+}
+
+static inline void
+set_key_to_tombstone (conc_table *table, int slot)
+{
+       gpointer *key_addr = &table->keys [slot];
+       if (table->gc_type & MONO_HASH_KEY_GC)
+               mono_gc_wbarrier_generic_store (key_addr, mono_domain_get()->ephemeron_tombstone);
+       else
+               *key_addr = PTR_TOMBSTONE;
+}
+
+static inline void
+set_value (conc_table *table, int slot, gpointer value)
+{
+       gpointer *value_addr = &table->values [slot];
+       if (table->gc_type & MONO_HASH_VALUE_GC)
+               mono_gc_wbarrier_generic_store (value_addr, value);
+       else
+               *value_addr = value;
+}
+
+static MONO_ALWAYS_INLINE void
+insert_one_local (conc_table *table, GHashFunc hash_func, gpointer key, gpointer value)
+{
+       int table_mask = table->table_size - 1;
+       int hash = mix_hash (hash_func (key));
+       int i = hash & table_mask;
+
+       while (table->keys [i])
+               i = (i + 1) & table_mask;
+
+       set_key (table, i, key);
+       set_value (table, i, value);
+}
+
+static void
+expand_table (MonoConcGHashTable *hash_table)
+{
+       conc_table *old_table = (conc_table*)hash_table->table;
+       conc_table *new_table = conc_table_new (hash_table, old_table->table_size * EXPAND_RATIO);
+       int i;
+
+       for (i = 0; i < old_table->table_size; ++i) {
+               if (old_table->keys [i] && !key_is_tombstone (hash_table, old_table->keys [i]))
+                       insert_one_local (new_table, hash_table->hash_func, old_table->keys [i], old_table->values [i]);
+       }
+
+       mono_memory_barrier ();
+       hash_table->table = new_table;
+       hash_table->overflow_count = (int)(new_table->table_size * LOAD_FACTOR);
+       conc_table_lf_free (old_table); 
+}
+
+
+MonoConcGHashTable *
+mono_conc_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type, MonoGCRootSource source, const char *msg)
+{
+       MonoConcGHashTable *hash;
+
+       if (!hash_func)
+               hash_func = g_direct_hash;
+
+       hash = g_new0 (MonoConcGHashTable, 1);
+       hash->hash_func = hash_func;
+       hash->equal_func = key_equal_func;
+
+       hash->element_count = 0;
+       hash->overflow_count = (int)(INITIAL_SIZE * LOAD_FACTOR);
+       hash->gc_type = type;
+       hash->source = source;
+       hash->msg = msg;
+
+       hash->table = conc_table_new (hash, INITIAL_SIZE);
+
+       if (type > MONO_HASH_KEY_VALUE_GC)
+               g_error ("wrong type for gc hashtable");
+
+       return hash;
+}
+
+gpointer
+mono_conc_g_hash_table_lookup (MonoConcGHashTable *hash, gconstpointer key)
+{
+       gpointer orig_key, value;
+
+       if (mono_conc_g_hash_table_lookup_extended (hash, key, &orig_key, &value))
+               return value;
+       else
+               return NULL;
+}
+
+gboolean
+mono_conc_g_hash_table_lookup_extended (MonoConcGHashTable *hash_table, gconstpointer key, gpointer *orig_key_ptr, gpointer *value_ptr)
+{
+       MonoThreadHazardPointers* hp;
+       conc_table *table;
+       int hash, i, table_mask;
+       hash = mix_hash (hash_table->hash_func (key));
+       hp = mono_hazard_pointer_get ();
+
+retry:
+       table = (conc_table *)mono_get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
+       table_mask = table->table_size - 1;
+       i = hash & table_mask;
+
+       if (G_LIKELY (!hash_table->equal_func)) {
+               while (table->keys [i]) {
+                       gpointer orig_key = table->keys [i];
+                       if (key == orig_key) {
+                               gpointer value;
+                               /* The read of keys must happen before the read of values */
+                               mono_memory_barrier ();
+                               value = table->values [i];
+
+                               /* We just read a value been deleted, try again. */
+                               if (G_UNLIKELY (!value))
+                                       goto retry;
+
+                               mono_hazard_pointer_clear (hp, 0);
+
+                               *orig_key_ptr = orig_key;
+                               *value_ptr = value;
+                               return TRUE;
+                       }
+                       i = (i + 1) & table_mask;
+               }
+       } else {
+               GEqualFunc equal = hash_table->equal_func;
+
+               while (table->keys [i]) {
+                       gpointer orig_key = table->keys [i];
+                       if (!key_is_tombstone (hash_table, orig_key) && equal (key, orig_key)) {
+                               gpointer value;
+                               /* The read of keys must happen before the read of values */
+                               mono_memory_barrier ();
+                               value = table->values [i];
+
+                               /* We just read a value been deleted, try again. */
+                               if (G_UNLIKELY (!value))
+                                       goto retry;
+
+                               mono_hazard_pointer_clear (hp, 0);
+                               *orig_key_ptr = orig_key;
+                               *value_ptr = value;
+                               return TRUE;
+
+                       }
+                       i = (i + 1) & table_mask;
+               }
+       }
+
+       /* The table might have expanded and the value is now on the newer table */
+       mono_memory_barrier ();
+       if (hash_table->table != table)
+               goto retry;
+
+       mono_hazard_pointer_clear (hp, 0);
+
+       *orig_key_ptr = NULL;
+       *value_ptr = NULL;
+       return FALSE;
+}
+
+void
+mono_conc_g_hash_table_foreach (MonoConcGHashTable *hash_table, GHFunc func, gpointer user_data)
+{
+       int i;
+       conc_table *table = (conc_table*)hash_table->table;
+
+       for (i = 0; i < table->table_size; ++i) {
+               if (table->keys [i] && !key_is_tombstone (hash_table, table->keys [i])) {
+                       func (table->keys [i], table->values [i], user_data);
+               }
+       }       
+}
+
+void
+mono_conc_g_hash_table_destroy (MonoConcGHashTable *hash_table)
+{
+       if (hash_table->key_destroy_func || hash_table->value_destroy_func) {
+               int i;
+               conc_table *table = (conc_table*)hash_table->table;
+
+               for (i = 0; i < table->table_size; ++i) {
+                       if (table->keys [i] && !key_is_tombstone (hash_table, table->keys [i])) {
+                               if (hash_table->key_destroy_func)
+                                       (hash_table->key_destroy_func) (table->keys [i]);
+                               if (hash_table->value_destroy_func)
+                                       (hash_table->value_destroy_func) (table->values [i]);
+                       }
+               }
+       }
+       conc_table_free ((gpointer)hash_table->table);
+       g_free (hash_table);
+}
+
+/* Return NULL on success or the old value in failure */
+gpointer
+mono_conc_g_hash_table_insert (MonoConcGHashTable *hash_table, gpointer key, gpointer value)
+{
+       conc_table *table;
+       int hash, i, table_mask;
+
+       g_assert (key != NULL);
+       g_assert (value != NULL);
+
+       hash = mix_hash (hash_table->hash_func (key));
+
+       if (hash_table->element_count >= hash_table->overflow_count)
+               expand_table (hash_table);
+
+       table = (conc_table*)hash_table->table;
+       table_mask = table->table_size - 1;
+       i = hash & table_mask;
+
+       if (!hash_table->equal_func) {
+               for (;;) {
+                       gpointer cur_key = table->keys [i];
+                       if (!cur_key || key_is_tombstone (hash_table, cur_key)) {
+                               set_value (table, i, value);
+
+                               /* The write to values must happen after the write to keys */
+                               mono_memory_barrier ();
+                               set_key (table, i, key);
+                               ++hash_table->element_count;
+                               return NULL;
+                       }
+                       if (key == cur_key) {
+                               gpointer value = table->values [i];
+                               return value;
+                       }
+                       i = (i + 1) & table_mask;
+               }
+       } else {
+               GEqualFunc equal = hash_table->equal_func;
+               for (;;) {
+                       gpointer cur_key = table->keys [i];
+                       if (!cur_key || key_is_tombstone (hash_table, cur_key)) {
+                               set_value (table, i, value);
+                               /* The write to values must happen after the write to keys */
+                               mono_memory_barrier ();
+                               set_key (table, i, key);
+                               ++hash_table->element_count;
+                               return NULL;
+                       }
+                       if (equal (key, cur_key)) {
+                               gpointer value = table->values [i];
+                               return value;
+                       }
+                       i = (i + 1) & table_mask;
+               }
+       }
+}
+
+gpointer
+mono_conc_g_hash_table_remove (MonoConcGHashTable *hash_table, gconstpointer key)
+{
+       conc_table *table;
+       int hash, i, table_mask;
+
+       g_assert (key != NULL);
+
+       hash = mix_hash (hash_table->hash_func (key));
+
+       table = (conc_table*)hash_table->table;
+       table_mask = table->table_size - 1;
+       i = hash & table_mask;
+
+       if (!hash_table->equal_func) {
+               for (;;) {
+                       gpointer cur_key = table->keys [i];
+                       if (!cur_key) {
+                               return NULL; /*key not found*/
+                       }
+
+                       if (key == cur_key) {
+                               gpointer value = table->values [i];
+                               table->values [i] = NULL;
+                               mono_memory_barrier ();
+                               set_key_to_tombstone (table, i);
+
+                               --hash_table->element_count;
+
+                               if (hash_table->key_destroy_func != NULL)
+                                       (*hash_table->key_destroy_func) (cur_key);
+                               if (hash_table->value_destroy_func != NULL)
+                                       (*hash_table->value_destroy_func) (value);
+
+                               return value;
+                       }
+                       i = (i + 1) & table_mask;
+               }
+       } else {
+               GEqualFunc equal = hash_table->equal_func;
+               for (;;) {
+                       gpointer cur_key = table->keys [i];
+                       if (!cur_key) {
+                               return NULL; /*key not found*/
+                       }
+
+                       if (!key_is_tombstone (hash_table, cur_key) && equal (key, cur_key)) {
+                               gpointer value = table->values [i];
+                               table->values [i] = NULL;
+                               mono_memory_barrier ();
+                               set_key_to_tombstone (table, i);
+
+                               if (hash_table->key_destroy_func != NULL)
+                                       (*hash_table->key_destroy_func) (cur_key);
+                               if (hash_table->value_destroy_func != NULL)
+                                       (*hash_table->value_destroy_func) (value);
+                               return value;
+                       }
+
+                       i = (i + 1) & table_mask;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mono/metadata/mono-conc-hash.h b/mono/metadata/mono-conc-hash.h
new file mode 100644 (file)
index 0000000..67b77ef
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * \file
+ * GC-aware concurrent hashtable, based on utils/mono-conc-hashtable
+ */
+
+#ifndef __MONO_CONC_G_HASH_H__
+#define __MONO_CONC_G_HASH_H__
+
+#include <mono/metadata/mono-hash.h>
+
+
+typedef struct _MonoConcGHashTable MonoConcGHashTable;
+
+MonoConcGHashTable * mono_conc_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type, MonoGCRootSource source, const char *msg);
+gpointer mono_conc_g_hash_table_lookup (MonoConcGHashTable *hash, gconstpointer key);
+gboolean mono_conc_g_hash_table_lookup_extended (MonoConcGHashTable *hash, gconstpointer key, gpointer *orig_key, gpointer *value);
+void mono_conc_g_hash_table_foreach (MonoConcGHashTable *hash, GHFunc func, gpointer user_data);
+void mono_conc_g_hash_table_destroy (MonoConcGHashTable *hash);
+gpointer mono_conc_g_hash_table_insert (MonoConcGHashTable *h, gpointer k, gpointer v);
+gpointer mono_conc_g_hash_table_remove (MonoConcGHashTable *hash, gconstpointer key);
+
+#endif /* __MONO_CONC_G_HASH_H__ */
index 5a0e06102b0f13916188cae94c77280996beaa7f..594556fb68a13421102fcc88566cb0dbc62c634d 100644 (file)
@@ -48,16 +48,17 @@ cache_object (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObject* o
        ReflectedEntry pe;
        pe.item = item;
        pe.refclass = klass;
+
        mono_domain_lock (domain);
        if (!domain->refobject_hash)
-               domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");
+               domain->refobject_hash = mono_conc_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");
 
-       obj = (MonoObject*) mono_g_hash_table_lookup (domain->refobject_hash, &pe);
+       obj = (MonoObject*) mono_conc_g_hash_table_lookup (domain->refobject_hash, &pe);
        if (obj == NULL) {
                ReflectedEntry *e = ALLOC_REFENTRY;
                e->item = item;
                e->refclass = klass;
-               mono_g_hash_table_insert (domain->refobject_hash, e, o);
+               mono_conc_g_hash_table_insert (domain->refobject_hash, e, o);
                obj = o;
        }
        mono_domain_unlock (domain);
@@ -71,16 +72,17 @@ cache_object_handle (MonoDomain *domain, MonoClass *klass, gpointer item, MonoOb
        ReflectedEntry pe;
        pe.item = item;
        pe.refclass = klass;
+
        mono_domain_lock (domain);
        if (!domain->refobject_hash)
-               domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");
+               domain->refobject_hash = mono_conc_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");
 
-       MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_g_hash_table_lookup (domain->refobject_hash, &pe));
+       MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_conc_g_hash_table_lookup (domain->refobject_hash, &pe));
        if (MONO_HANDLE_IS_NULL (obj)) {
                ReflectedEntry *e = ALLOC_REFENTRY;
                e->item = item;
                e->refclass = klass;
-               mono_g_hash_table_insert (domain->refobject_hash, e, MONO_HANDLE_RAW (o));
+               mono_conc_g_hash_table_insert (domain->refobject_hash, e, MONO_HANDLE_RAW (o));
                MONO_HANDLE_ASSIGN (obj, o);
        }
        mono_domain_unlock (domain);
@@ -96,11 +98,11 @@ check_object_handle (MonoDomain* domain, MonoClass *klass, gpointer item)
        ReflectedEntry e;
        e.item = item;
        e.refclass = klass;
-       mono_domain_lock (domain);
-       if (!domain->refobject_hash)
-               domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");
-       MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_g_hash_table_lookup (domain->refobject_hash, &e));
-       mono_domain_unlock (domain);
+       MonoConcGHashTable *hash = domain->refobject_hash;
+       if (!hash)
+               return MONO_HANDLE_NEW (MonoObject, NULL);
+
+       MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_conc_g_hash_table_lookup (hash, &e));
        return obj;
 }
 
@@ -116,6 +118,8 @@ check_or_construct_handle (MonoDomain *domain, MonoClass *klass, gpointer item,
                return obj;
        MONO_HANDLE_ASSIGN (obj, construct (domain, klass, item, user_data, error));
        return_val_if_nok (error, NULL);
+       if (MONO_HANDLE_IS_NULL (obj))
+               return obj;
        /* note no caching if there was an error in construction */
        return cache_object_handle (domain, klass, item, obj);
 }
index fe80ea7027c03b5533976f925c5f114680c065d8..ee9681e1d27dce1033d9bcbe6b2867327c2f3801 100644 (file)
@@ -186,8 +186,9 @@ clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
 
                pe.item = o;
                pe.refclass = klass;
-               if (mono_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
-                       mono_g_hash_table_remove (domain->refobject_hash, &pe);
+
+               if (mono_conc_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
+                       mono_conc_g_hash_table_remove (domain->refobject_hash, &pe);
                        FREE_REFENTRY (orig_pe);
                }
        }
@@ -208,9 +209,9 @@ mono_reflection_cleanup_domain (MonoDomain *domain)
        if (domain->refobject_hash) {
 /*let's avoid scanning the whole hashtable if not needed*/
 #ifdef REFENTRY_REQUIRES_CLEANUP
-               mono_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
+               mono_conc_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
 #endif
-               mono_g_hash_table_destroy (domain->refobject_hash);
+               mono_conc_g_hash_table_destroy (domain->refobject_hash);
                domain->refobject_hash = NULL;
        }
 }
@@ -1209,6 +1210,7 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        HANDLE_FUNCTION_RETURN_OBJ (result);
 }
 
+/* WARNING: This method can return NULL on sucess */
 static MonoReflectionMethodBodyHandle
 method_body_object_construct (MonoDomain *domain, MonoClass *unused_class, MonoMethod *method, gpointer user_data, MonoError *error)
 {
index b50434bc1feca744de19cc559bf63b873dac06d3..47dd369faf6f1e608c4f9f79dc95de23364ac246 100644 (file)
@@ -1650,10 +1650,18 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *
                        goto leave;
                g_assert (base);
                gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
-               if (rank == 0) //single dimentional array
-                       result = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
-               else
-                       result = &mono_bounded_array_class_get (mono_class_from_mono_type (base), rank, TRUE)->byval_arg;
+               MonoClass *eclass = mono_class_from_mono_type (base);
+               result = mono_image_new0 (eclass->image, MonoType, 1);
+               if (rank == 0)  {
+                       result->type = MONO_TYPE_SZARRAY;
+                       result->data.klass = eclass;
+               } else {
+                       MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
+                       result->type = MONO_TYPE_ARRAY;
+                       result->data.array = at;
+                       at->eklass = eclass;
+                       at->rank = rank;
+               }
                MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
        } else if (is_sre_byref (klass)) {
                MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
index e0db07a52b4a8042be12b8a32a6e8b42ae7826e1..a08d93b4137fe71b2f60d77b25010a51bd3d5638 100755 (executable)
@@ -401,6 +401,9 @@ interp_sources =    \
        interp/mintops.def      \
        interp/mintops.c        \
        interp/transform.c
+else
+interp_sources = \
+       interp/interp-stubs.c
 endif
 
 if ENABLE_LLVM
@@ -502,6 +505,8 @@ test_sources =                      \
        aot-tests.cs \
        gc-test.cs \
        gshared.cs \
+       unaligned.cs    \
+       MemoryIntrinsics.il     \
        mixed.cs
 
 if NACL_CODEGEN
@@ -521,6 +526,7 @@ regtests_UNIVERSAL = \
        devirtualization.exe \
        generics.exe \
        basic-simd.exe \
+       unaligned.exe   \
        basic-vectors.exe
 
 if NACL_CODEGEN
@@ -654,6 +660,9 @@ nacl.exe: nacl.cs TestDriver.dll
 generics.exe: generics.cs TestDriver.dll generics-variant-types.dll
        $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:generics-variant-types.dll -r:$(CLASS)/System.Core.dll
 
+unaligned.exe: unaligned.cs TestDriver.dll MemoryIntrinsics.dll
+       $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:MemoryIntrinsics.dll
+
 %.exe: %.cs TestDriver.dll
        $(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll
 
@@ -666,6 +675,9 @@ TestDriver.dll: $(srcdir)/TestDriver.cs $(srcdir)/TestHelpers.cs
 generics-variant-types.dll: generics-variant-types.il
        $(ILASM) -dll -output=$@ $<
 
+MemoryIntrinsics.dll: MemoryIntrinsics.il
+       $(ILASM) -dll -output=$@ $<
+
 if NACL_CODEGEN
 GENMDESC_OPTS=--nacl
 else !NACL_CODEGEN
@@ -770,6 +782,7 @@ gsharedvtcheck:
        $(MAKE) fullaotcheck GSHAREDVT=1
 
 fullaot_regtests = $(regtests) aot-tests.exe $(if $(GSHAREDVT),gshared.exe)
+fullaot_testing_deps = generics-variant-types.dll TestDriver.dll MemoryIntrinsics.dll
 
 FULLAOT_LIBS_UNIVERSAL = \
        mscorlib.dll \
@@ -795,17 +808,18 @@ FULLAOT_LIBS_DISABLED += \
        System.Configuration.dll
 endif
 
+
 FULLAOT_LIBS = $(filter-out $(FULLAOT_LIBS_DISABLED),$(FULLAOT_LIBS_UNIVERSAL))
 
 FULLAOT_TMP_DIR=$(top_builddir)/mono/mini/fullaot-tmp
 
 # This currently only works on amd64/arm
-fullaotcheck: $(mono) $(fullaot_regtests)
+fullaotcheck: $(mono) $(fullaot_regtests) $(fullaot_testing_deps)
        rm -rf $(FULLAOT_TMP_DIR)
        mkdir $(FULLAOT_TMP_DIR)
        $(MAKE) fullaot-libs AOT_FLAGS="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)$(INVARIANT_AOT_OPTIONS)" GSHAREDVT=$(GSHAREDVT)
-       cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll $(FULLAOT_TMP_DIR)/
-       MONO_PATH=$(FULLAOT_TMP_DIR) $(top_builddir)/runtime/mono-wrapper $(MOBILE_RUNTIME_ARG) $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)$(INVARIANT_AOT_OPTIONS)" $(FULLAOT_TMP_DIR)/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
+       cp $(regtests) $(fullaot_regtests) $(fullaot_testing_deps) $(FULLAOT_TMP_DIR)/
+       MONO_PATH=$(FULLAOT_TMP_DIR) $(top_builddir)/runtime/mono-wrapper $(MOBILE_RUNTIME_ARG) $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)$(INVARIANT_AOT_OPTIONS)" $(FULLAOT_TMP_DIR)/{*.dll,*.exe} || exit 1
        ln -s $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),$$PWD/mono) $(FULLAOT_TMP_DIR)/
        for i in $(fullaot_regtests); do echo $$i; MONO_PATH=$(FULLAOT_TMP_DIR) $(top_builddir)/runtime/mono-wrapper $(MOBILE_RUNTIME_ARG) --full-aot $(FULLAOT_TMP_DIR)/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
 
@@ -827,8 +841,8 @@ llvmonlycheck: mono $(llvmonly_regtests)
        rm -rf fullaot-tmp
        mkdir fullaot-tmp
        $(MAKE) fullaot-libs AOT_FLAGS="llvmonly,$(MONO_FULLAOT_ADDITIONAL_ARGS)$(INVARIANT_AOT_OPTIONS)"
-       cp $(llvmonly_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
-       MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper  $(MOBILE_RUNTIME_ARG) --aot=llvmonly fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
+       cp $(llvmonly_regtests) $(fullaot_testing_deps) fullaot-tmp/
+       MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper  $(MOBILE_RUNTIME_ARG) --aot=llvmonly fullaot-tmp/{*.dll,*.exe} || exit 1
        ln -s $$PWD/mono fullaot-tmp/
        for i in $(llvmonly_regtests); do echo $$i; MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(MOBILE_RUNTIME_ARG) --llvmonly fullaot-tmp/$$i --exclude '!BITCODE' || exit 1; done
 
diff --git a/mono/mini/MemoryIntrinsics.il b/mono/mini/MemoryIntrinsics.il
new file mode 100644 (file)
index 0000000..dd4c9b5
--- /dev/null
@@ -0,0 +1,180 @@
+.assembly extern mscorlib
+{
+       .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
+       .ver 4:0:0:0
+}
+
+.assembly 'MemoryIntrinsics'
+{
+       .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78  63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )
+       .hash algorithm 0x00008004
+       .ver 0:0:0:0
+}
+.module 'instrics-lib.dll'
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+.namespace Mono {
+       .class public abstract auto ansi sealed beforefieldinit Intrinsics extends [mscorlib]System.Object
+       {
+               .method public hidebysig static void  Cpobj<T>(void* 'to', void* from) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       cpobj !!T
+                       ret
+               }
+
+               .method public hidebysig static !!T Ldobj<T>(void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void Stobj<T>(void* 'to', !!T 'value') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void LdobjStObjPair<T>(void* 'to', void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldobj !!T
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void Cpblk(void* 'to', void* 'from', int32 size) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       cpblk
+                       ret
+               }
+
+               .method public hidebysig static void Initblk<T>(void* 'to', int32 'value', int32 'size') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       initblk
+                       ret
+               }
+
+               //Unaligned intrinsics
+               .method public hidebysig static void UnalignedCpobj<T>(void* 'to', void* from) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       cpobj !!T
+                       ret
+               }
+
+               .method public hidebysig static !!T UnalignedLdobj<T>(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedStobj<T>(void* 'to', !!T 'value') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedLdobjStObjPair<T>(void* 'to', void* 'from') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       unaligned. 1
+                       ldobj !!T
+                       stobj !!T
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedCpblk(void* 'to', void* 'from', int32 size) cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       unaligned. 1
+                       cpblk
+                       ret
+               }
+
+               .method public hidebysig static void UnalignedInit(void* 'to', int32 'value', int32 'size') cil managed
+               {
+                       ldarg.0
+                       ldarg.1
+                       ldarg.2
+                       unaligned. 1
+                       initblk
+                       ret
+               }
+
+               //Unaligned ldind
+               .method public hidebysig static int16 UnalignedLdInd2(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i2
+                       ret
+               }
+
+               .method public hidebysig static int32 UnalignedLdInd4(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i4
+                       ret
+               }
+
+               .method public hidebysig static int64 UnalignedLdInd8(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i8
+                       ret
+               }
+
+               .method public hidebysig static float32 UnalignedLdIndR4(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.r4
+                       ret
+               }
+
+               .method public hidebysig static float64 UnalignedLdIndR8(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.r8
+                       ret
+               }
+
+               .method public hidebysig static native int UnalignedLdIndI(void* 'from') cil managed
+               {
+                       ldarg.0
+                       unaligned. 1
+                       ldind.i
+                       ret
+               }
+
+       }
+}
index 782106c45e17b519200a104fc6a09695e0e22758..30ef9a64ad7bc9628a0e2a5a52c7306b469dd6d1 100644 (file)
@@ -3941,9 +3941,11 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
                                        if (!method)
                                                return NULL;
                                }
-                               full_name = mono_method_full_name (method, TRUE);
-                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: NOT FOUND: %s.", full_name);
-                               g_free (full_name);
+                               if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
+                                       full_name = mono_method_full_name (method, TRUE);
+                                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: NOT FOUND: %s.", full_name);
+                                       g_free (full_name);
+                               }
                        }
                        return NULL;
                }
index c639fa9e756e5c095b0e73f81b1c78b94651d6a8..bfdddb37547e5dac5d9f4f094b1084d87b359826 100644 (file)
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/networking.h>
 #include <mono/utils/mono-proclib.h>
+#include <mono/utils/w32api.h>
 #include "debugger-agent.h"
 #include "mini.h"
 #include "seq-points.h"
-#include <mono/utils/w32api.h>
+#include "interp/interp.h"
 
 /*
  * On iOS we can't use System.Environment.Exit () as it will do the wrong
@@ -137,6 +138,7 @@ typedef struct
        MonoContext ctx;
        MonoDebugMethodJitInfo *jit;
        MonoJitInfo *ji;
+       MonoInterpFrameHandle interp_frame;
        int flags;
        mgreg_t *reg_locations [MONO_MAX_IREGS];
        /*
@@ -2480,6 +2482,35 @@ static void invoke_method (void);
  * SUSPEND/RESUME
  */
 
+static MonoJitInfo*
+get_top_method_ji (gpointer ip, MonoDomain **domain, gpointer *out_ip)
+{
+       MonoJitInfo *ji;
+
+       if (out_ip)
+               *out_ip = ip;
+
+       ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, domain);
+       if (!ji) {
+               /* Could be an interpreter method */
+
+               MonoLMF *lmf = mono_get_lmf ();
+               MonoInterpFrameHandle *frame;
+
+               g_assert (((guint64)lmf->previous_lmf) & 2);
+               MonoLMFExt *ext = (MonoLMFExt*)lmf;
+
+               g_assert (ext->interp_exit);
+               frame = ext->interp_exit_data;
+               ji = mono_interp_frame_get_jit_info (frame);
+               if (domain)
+                       *domain = mono_domain_get ();
+               if (out_ip)
+                       *out_ip = mono_interp_frame_get_ip (frame);
+       }
+       return ji;
+}
+
 /*
  * save_thread_context:
  *
@@ -2619,13 +2650,23 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji)
                         * suspended when it returns to managed code, so the parent's ctx should
                         * remain valid.
                         */
+                       MonoThreadUnwindState *state = mono_thread_info_get_suspend_state (info);
+
                        data.last_frame_set = FALSE;
-                       mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &data);
+                       mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, state, MONO_UNWIND_SIGNAL_SAFE, &data);
                        if (data.last_frame_set) {
                                gpointer jit_tls = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data;
 
                                memcpy (&tls->async_last_frame, &data.last_frame, sizeof (StackFrameInfo));
 
+                               if (data.last_frame.type == FRAME_TYPE_INTERP_TO_MANAGED) {
+                                       /*
+                                        * Store the current lmf instead of the parent one, since that
+                                        * contains the interp exit data.
+                                        */
+                                       data.lmf = state->unwind_data [MONO_UNWIND_DATA_LMF];
+                               }
+
                                copy_unwind_state_from_frame_data (&tls->async_state, &data, jit_tls);
                                copy_unwind_state_from_frame_data (&tls->context, &data, jit_tls);
                        } else {
@@ -2751,8 +2792,8 @@ process_suspend (DebuggerTlsData *tls, MonoContext *ctx)
                return;
        }
 
-       ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
-
+       ji = get_top_method_ji (ip, NULL, NULL);
+       g_assert (ji);
        /* Can't suspend in these methods */
        method = jinfo_get_method (ji);
        if (method->klass == mono_defaults.string_class && (!strcmp (method->name, "memset") || strstr (method->name, "memcpy")))
@@ -3051,7 +3092,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
        SeqPoint sp;
        int flags = 0;
 
-       if (info->type != FRAME_TYPE_MANAGED) {
+       if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) {
                if (info->type == FRAME_TYPE_DEBUGGER_INVOKE) {
                        /* Mark the last frame as an invoke frame */
                        if (ud->frames)
@@ -3104,6 +3145,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
        frame->native_offset = info->native_offset;
        frame->flags = flags;
        frame->ji = info->ji;
+       frame->interp_frame = info->interp_frame;
        if (info->reg_locations)
                memcpy (frame->reg_locations, info->reg_locations, MONO_MAX_IREGS * sizeof (mgreg_t*));
        if (ctx) {
@@ -4096,7 +4138,7 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
 
        send_type_load (method->klass);
 
-       if (!result)
+       if (!result && jinfo)
                add_pending_breakpoints (method, jinfo);
 }
 
@@ -4229,11 +4271,15 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
        if (it.seq_point.native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
                DEBUG_PRINTF (1, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset);
        } else if (count == 0) {
+               if (ji->is_interp) {
+                       mono_interp_set_breakpoint (ji, inst->ip);
+               } else {
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
-               mono_arch_set_breakpoint (ji, inst->ip);
+                       mono_arch_set_breakpoint (ji, inst->ip);
 #else
-               NOT_IMPLEMENTED;
+                       NOT_IMPLEMENTED;
 #endif
+               }
        }
 
        DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:[il=0x%x,native=0x%x] [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, (int)it.seq_point.native_offset, inst->ip, count);
@@ -4255,7 +4301,10 @@ remove_breakpoint (BreakpointInstance *inst)
        g_assert (count > 0);
 
        if (count == 1 && inst->native_offset != SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
-               mono_arch_clear_breakpoint (ji, ip);
+               if (ji->is_interp)
+                       mono_interp_clear_breakpoint (ji, ip);
+               else
+                       mono_arch_clear_breakpoint (ji, ip);
                DEBUG_PRINTF (1, "[dbg] Clear breakpoint at %s [%p].\n", mono_method_full_name (jinfo_get_method (ji), TRUE), ip);
        }
 #else
@@ -4372,12 +4421,15 @@ set_bp_in_method (MonoDomain *domain, MonoMethod *method, MonoSeqPointInfo *seq_
                /* Might be AOTed code */
                mono_class_init (method->klass);
                code = mono_aot_get_method_checked (domain, method, &oerror);
-               g_assert (code);
-               mono_error_assert_ok (&oerror);
-               ji = mono_jit_info_table_find (domain, (char *)code);
+               if (code) {
+                       mono_error_assert_ok (&oerror);
+                       ji = mono_jit_info_table_find (domain, (char *)code);
+               } else {
+                       /* Might be interpreted */
+                       ji = mono_interp_find_jit_info (domain, method);
+               }
                g_assert (ji);
        }
-       g_assert (code);
 
        insert_breakpoint (seq_points, domain, ji, bp, error);
 }
@@ -4636,16 +4688,15 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t
                }
        }
 
-       MonoDebugMethodAsyncInfo* asyncMethod = mono_debug_lookup_method_async_debug_info (method);
-       if (asyncMethod) {
-               for (int i = 0; i < asyncMethod->num_awaits; i++)
-               {
-                       if (asyncMethod->yield_offsets[i] == sp->il_offset || asyncMethod->resume_offsets[i] == sp->il_offset) {
-                               mono_debug_free_method_async_debug_info (asyncMethod);
+       MonoDebugMethodAsyncInfo* async_method = mono_debug_lookup_method_async_debug_info (method);
+       if (async_method) {
+               for (int i = 0; i < async_method->num_awaits; i++) {
+                       if (async_method->yield_offsets[i] == sp->il_offset || async_method->resume_offsets[i] == sp->il_offset) {
+                               mono_debug_free_method_async_debug_info (async_method);
                                return FALSE;
                        }
                }
-               mono_debug_free_method_async_debug_info (asyncMethod);
+               mono_debug_free_method_async_debug_info (async_method);
        }
 
        if (req->size != STEP_SIZE_LINE)
@@ -4756,7 +4807,7 @@ get_notify_debugger_of_wait_completion_method ()
 }
 
 static void
-process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
+process_breakpoint (DebuggerTlsData *tls, gboolean from_signal)
 {
        MonoJitInfo *ji;
        guint8 *ip;
@@ -4777,11 +4828,27 @@ process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
 
        ip = (guint8 *)MONO_CONTEXT_GET_IP (ctx);
        ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
+
+       if (!ji) {
+               /* Interpreter */
+               // FIXME: Pass a flag instead to detect this
+               MonoLMF *lmf = mono_get_lmf ();
+               MonoInterpFrameHandle *frame;
+
+               g_assert (((guint64)lmf->previous_lmf) & 2);
+               MonoLMFExt *ext = (MonoLMFExt*)lmf;
+
+               g_assert (ext->interp_exit);
+               frame = ext->interp_exit_data;
+               ji = mono_interp_frame_get_jit_info (frame);
+               ip = mono_interp_frame_get_ip (frame);
+       }
+
        g_assert (ji && !ji->is_trampoline);
        method = jinfo_get_method (ji);
 
        /* Compute the native offset of the breakpoint from the ip */
-       native_offset = ip - (guint8*)ji->code_start;   
+       native_offset = ip - (guint8*)ji->code_start;
 
        /* 
         * Skip the instruction causing the breakpoint signal.
@@ -4936,9 +5003,9 @@ process_signal_event (void (*func) (DebuggerTlsData*, gboolean))
 }
 
 static void
-process_breakpoint (void)
+process_breakpoint_from_signal (void)
 {
-       process_signal_event (process_breakpoint_inner);
+       process_signal_event (process_breakpoint);
 }
 
 static void
@@ -4980,19 +5047,30 @@ mono_debugger_agent_breakpoint_hit (void *sigctx)
         * problems, like the original signal is disabled, libgc can't handle altstack, etc.
         * So set up the signal context to return to the real breakpoint handler function.
         */
-       resume_from_signal_handler (sigctx, process_breakpoint);
+       resume_from_signal_handler (sigctx, process_breakpoint_from_signal);
 }
 
+typedef struct {
+       gboolean found;
+       MonoContext *ctx;
+} UserBreakCbData;
+
 static gboolean
-user_break_cb (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
+user_break_cb (StackFrameInfo *frame, MonoContext *ctx, gpointer user_data)
 {
+       UserBreakCbData *data = user_data;
+
+       if (frame->type == FRAME_TYPE_INTERP_TO_MANAGED) {
+               data->found = TRUE;
+               return TRUE;
+       }
        if (frame->managed) {
-               *(MonoContext*)data = *ctx;
+               data->found = TRUE;
+               *data->ctx = *ctx;
 
                return TRUE;
-       } else {
-               return FALSE;
        }
+       return FALSE;
 }
 
 /*
@@ -5005,11 +5083,15 @@ mono_debugger_agent_user_break (void)
                MonoContext ctx;
                int suspend_policy;
                GSList *events;
+               UserBreakCbData data;
+
+               memset (&data, 0, sizeof (UserBreakCbData));
+               data.ctx = &ctx;
 
                /* Obtain a context */
                MONO_CONTEXT_SET_IP (&ctx, NULL);
-               mono_walk_stack_with_ctx (user_break_cb, NULL, (MonoUnwindOptions)0, &ctx);
-               g_assert (MONO_CONTEXT_GET_IP (&ctx) != NULL);
+               mono_walk_stack_with_ctx (user_break_cb, NULL, (MonoUnwindOptions)0, &data);
+               g_assert (data.found);
 
                mono_loader_lock ();
                events = create_event_list (EVENT_KIND_USER_BREAK, NULL, NULL, NULL, &suspend_policy);
@@ -5051,8 +5133,6 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
        SeqPoint sp;
        MonoSeqPointInfo *info;
 
-       ip = (guint8 *)MONO_CONTEXT_GET_IP (ctx);
-
        /* Skip the instruction causing the single step */
        if (from_signal)
                mono_arch_skip_single_step (ctx);
@@ -5072,14 +5152,15 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
        if (mono_thread_internal_current () != ss_req->thread)
                return;
 
-       if (log_level > 0) {
-               ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
+       ip = (guint8 *)MONO_CONTEXT_GET_IP (ctx);
+
+       ji = get_top_method_ji (ip, &domain, (gpointer*)&ip);
+       g_assert (ji && !ji->is_trampoline);
 
+       if (log_level > 0) {
                DEBUG_PRINTF (1, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer) (gsize) mono_native_thread_id_get (), ss_depth_to_string (ss_req->depth), mono_method_full_name (jinfo_get_method (ji), TRUE), MONO_CONTEXT_GET_IP (ctx), (int)((guint8*)MONO_CONTEXT_GET_IP (ctx) - (guint8*)ji->code_start), MONO_CONTEXT_GET_SP (ctx), ss_req->last_sp);
        }
 
-       ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
-       g_assert (ji && !ji->is_trampoline);
        method = jinfo_get_method (ji);
        g_assert (method);
 
@@ -5114,8 +5195,10 @@ process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
         * The ip points to the instruction causing the single step event, which is before
         * the offset recorded in the seq point map, so find the next seq point after ip.
         */
-       if (!mono_find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp))
+       if (!mono_find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp)) {
+               g_assert_not_reached ();
                return;
+       }
 
        il_offset = sp.il_offset;
 
@@ -5230,7 +5313,7 @@ debugger_agent_breakpoint_from_context (MonoContext *ctx)
        mono_thread_state_init_from_monoctx (&tls->restore_state, ctx);
        memcpy (&tls->handler_ctx, ctx, sizeof (MonoContext));
 
-       process_breakpoint_inner (tls, FALSE);
+       process_breakpoint (tls, FALSE);
 
        memcpy (ctx, &tls->restore_state.ctx, sizeof (MonoContext));
        memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState));
@@ -5250,8 +5333,10 @@ start_single_stepping (void)
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
        int val = InterlockedIncrement (&ss_count);
 
-       if (val == 1)
+       if (val == 1) {
                mono_arch_start_single_stepping ();
+               mono_interp_start_single_stepping ();
+       }
 #else
        g_assert_not_reached ();
 #endif
@@ -5263,8 +5348,10 @@ stop_single_stepping (void)
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
        int val = InterlockedDecrement (&ss_count);
 
-       if (val == 0)
+       if (val == 0) {
                mono_arch_stop_single_stepping ();
+               mono_interp_stop_single_stepping ();
+       }
 #else
        g_assert_not_reached ();
 #endif
@@ -6707,6 +6794,24 @@ set_var (MonoType *t, MonoDebugVarInfo *var, MonoContext *ctx, MonoDomain *domai
        }
 }
 
+static void
+set_interp_var (MonoType *t, gpointer addr, guint8 *val_buf)
+{
+       int size;
+
+       if (t->byref) {
+               addr = *(gpointer*)addr;
+               g_assert (addr);
+       }
+
+       if (MONO_TYPE_IS_REFERENCE (t))
+               size = sizeof (gpointer);
+       else
+               size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
+
+       memcpy (addr, val_buf, size);
+}
+
 static void
 clear_event_request (int req_id, int etype)
 {
@@ -9376,7 +9481,13 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                // FIXME: Check that the ip change is safe
 
                DEBUG_PRINTF (1, "[dbg] Setting IP to %s:0x%0x(0x%0x)\n", tls->frames [0]->actual_method->name, (int)sp.il_offset, (int)sp.native_offset);
-               MONO_CONTEXT_SET_IP (&tls->restore_state.ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset);
+
+               if (tls->frames [0]->ji->is_interp) {
+                       MonoJitTlsData *jit_data = ((MonoThreadInfo*)thread->thread_info)->jit_data;
+                       mono_interp_set_resume_state (jit_data, NULL, tls->frames [0]->interp_frame, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset);
+               } else {
+                       MONO_CONTEXT_SET_IP (&tls->restore_state.ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset);
+               }
                break;
        }
        default:
@@ -9442,7 +9553,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        sig = mono_method_signature (frame->actual_method);
 
-       if (!jit->has_var_info || !mono_get_seq_points (frame->domain, frame->actual_method))
+       if (!(jit->has_var_info || frame->ji->is_interp) || !mono_get_seq_points (frame->domain, frame->actual_method))
                /*
                 * The method is probably from an aot image compiled without soft-debug, variables might be dead, etc.
                 */
@@ -9463,9 +9574,17 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
                                DEBUG_PRINTF (4, "[dbg]   send arg %d.\n", pos);
 
-                               g_assert (pos >= 0 && pos < jit->num_params);
+                               if (frame->ji->is_interp) {
+                                       guint8 *addr;
+
+                                       addr = mono_interp_frame_get_arg (frame->interp_frame, pos);
+
+                                       buffer_add_value_full (buf, sig->params [pos], addr, frame->domain, FALSE, NULL);
+                               } else {
+                                       g_assert (pos >= 0 && pos < jit->num_params);
 
-                               add_var (buf, jit, sig->params [pos], &jit->params [pos], &frame->ctx, frame->domain, FALSE);
+                                       add_var (buf, jit, sig->params [pos], &jit->params [pos], &frame->ctx, frame->domain, FALSE);
+                               }
                        } else {
                                MonoDebugLocalsInfo *locals;
 
@@ -9475,30 +9594,57 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                        pos = locals->locals [pos].index;
                                        mono_debug_free_locals (locals);
                                }
-                               g_assert (pos >= 0 && pos < jit->num_locals);
 
                                DEBUG_PRINTF (4, "[dbg]   send local %d.\n", pos);
 
-                               add_var (buf, jit, header->locals [pos], &jit->locals [pos], &frame->ctx, frame->domain, FALSE);
+                               if (frame->ji->is_interp) {
+                                       guint8 *addr;
+
+                                       addr = mono_interp_frame_get_local (frame->interp_frame, pos);
+
+                                       buffer_add_value_full (buf, header->locals [pos], addr, frame->domain, FALSE, NULL);
+                               } else {
+                                       g_assert (pos >= 0 && pos < jit->num_locals);
+
+                                       add_var (buf, jit, header->locals [pos], &jit->locals [pos], &frame->ctx, frame->domain, FALSE);
+                               }
                        }
                }
                mono_metadata_free_mh (header);
                break;
        }
        case CMD_STACK_FRAME_GET_THIS: {
+               if (frame->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
+                       return ERR_ABSENT_INFORMATION;
                if (frame->api_method->klass->valuetype) {
                        if (!sig->hasthis) {
                                MonoObject *p = NULL;
                                buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &p, frame->domain);
                        } else {
-                               add_var (buf, jit, &frame->actual_method->klass->this_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
+                               if (frame->ji->is_interp) {
+                                       guint8 *addr;
+
+                                       addr = mono_interp_frame_get_this (frame->interp_frame);
+
+                                       buffer_add_value_full (buf, &frame->actual_method->klass->this_arg, addr, frame->domain, FALSE, NULL);
+                               } else {
+                                       add_var (buf, jit, &frame->actual_method->klass->this_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
+                               }
                        }
                } else {
                        if (!sig->hasthis) {
                                MonoObject *p = NULL;
                                buffer_add_value (buf, &frame->actual_method->klass->byval_arg, &p, frame->domain);
                        } else {
-                               add_var (buf, jit, &frame->api_method->klass->byval_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
+                               if (frame->ji->is_interp) {
+                                       guint8 *addr;
+
+                                       addr = mono_interp_frame_get_this (frame->interp_frame);
+
+                                       buffer_add_value_full (buf, &frame->api_method->klass->byval_arg, addr, frame->domain, FALSE, NULL);
+                               } else {
+                                       add_var (buf, jit, &frame->api_method->klass->byval_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
+                               }
                        }
                }
                break;
@@ -9507,7 +9653,8 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                MonoError error;
                guint8 *val_buf;
                MonoType *t;
-               MonoDebugVarInfo *var;
+               MonoDebugVarInfo *var = NULL;
+               gboolean is_arg = FALSE;
 
                len = decode_int (p, &p, end);
                header = mono_method_get_header_checked (frame->actual_method, &error);
@@ -9523,6 +9670,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
                                t = sig->params [pos];
                                var = &jit->params [pos];
+                               is_arg = TRUE;
                        } else {
                                MonoDebugLocalsInfo *locals;
 
@@ -9546,7 +9694,17 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                        if (err != ERR_NONE)
                                return err;
 
-                       set_var (t, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+                       if (frame->ji->is_interp) {
+                               guint8 *addr;
+
+                               if (is_arg)
+                                       addr = mono_interp_frame_get_arg (frame->interp_frame, pos);
+                               else
+                                       addr = mono_interp_frame_get_local (frame->interp_frame, pos);
+                               set_interp_var (t, addr, val_buf);
+                       } else {
+                               set_var (t, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+                       }
                }
                mono_metadata_free_mh (header);
                break;
@@ -9564,15 +9722,23 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                t = &frame->actual_method->klass->byval_arg;
                /* Checked by the sender */
                g_assert (MONO_TYPE_ISSTRUCT (t));
-               var = jit->this_var;
-               g_assert (var);
 
                val_buf = (guint8 *)g_alloca (mono_class_instance_size (mono_class_from_mono_type (t)));
                err = decode_value (t, frame->domain, val_buf, p, &p, end);
                if (err != ERR_NONE)
                        return err;
 
-               set_var (&frame->actual_method->klass->this_arg, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+               if (frame->ji->is_interp) {
+                       guint8 *addr;
+
+                       addr = mono_interp_frame_get_this (frame->interp_frame);
+                       set_interp_var (&frame->actual_method->klass->this_arg, addr, val_buf);
+               } else {
+                       var = jit->this_var;
+                       g_assert (var);
+
+                       set_var (&frame->actual_method->klass->this_arg, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+               }
                break;
        }
        default:
index 1c3060f162477cc8db01fbc0c64c6eb2c6f3ebbb..93668ac852457377081ddd806f9b8f65ad75b32a 100644 (file)
@@ -1227,8 +1227,8 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
 
                                        EMIT_NEW_VARLOADA ((cfg), (src), src_var, src_var->inst_vtype);
                                        EMIT_NEW_VARLOADA ((cfg), (dest), dest_var, dest_var->inst_vtype);
+                                       mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, 0);
 
-                                       mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
                                        break;
                                }
                                case OP_VZERO:
@@ -1273,7 +1273,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
 
                                        dreg = alloc_preg (cfg);
                                        EMIT_NEW_BIALU_IMM (cfg, dest, OP_ADD_IMM, dreg, ins->inst_destbasereg, ins->inst_offset);
-                                       mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
+                                       mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, 0);
                                        break;
                                }
                                case OP_LOADV_MEMBASE: {
@@ -1290,7 +1290,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
                                        dreg = alloc_preg (cfg);
                                        EMIT_NEW_BIALU_IMM (cfg, src, OP_ADD_IMM, dreg, ins->inst_basereg, ins->inst_offset);
                                        EMIT_NEW_VARLOADA (cfg, dest, dest_var, dest_var->inst_vtype);
-                                       mini_emit_stobj (cfg, dest, src, dest_var->klass, dest_var->backend.is_pinvoke);
+                                       mini_emit_memory_copy (cfg, dest, src, dest_var->klass, dest_var->backend.is_pinvoke, 0);
                                        break;
                                }
                                case OP_OUTARG_VT: {
index cc4cd237c677f3be75f9b93162979168aef28f7d..3b19a6d1bdaba5b7215c34a9ece4020672d6abf7 100644 (file)
@@ -105,6 +105,7 @@ struct _MonoInvocation {
        stackval       *stack_args; /* parent */
        stackval       *stack;
        stackval       *sp; /* For GC stack marking */
+       unsigned char  *locals;
        /* exception info */
        unsigned char  invoke_trap;
        const unsigned short  *ip;
diff --git a/mono/mini/interp/interp-stubs.c b/mono/mini/interp/interp-stubs.c
new file mode 100644 (file)
index 0000000..176e45b
--- /dev/null
@@ -0,0 +1,98 @@
+#include <config.h>
+
+#ifndef ENABLE_INTERPRETER
+
+#include "interp.h"
+
+/* Dummy versions of interpreter functions to avoid ifdefs at call sites */
+
+MonoJitInfo*
+mono_interp_find_jit_info (MonoDomain *domain, MonoMethod *method)
+{
+       return NULL;
+}
+
+void
+mono_interp_set_breakpoint (MonoJitInfo *jinfo, gpointer ip)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_interp_clear_breakpoint (MonoJitInfo *jinfo, gpointer ip)
+{
+       g_assert_not_reached ();
+}
+
+MonoJitInfo*
+mono_interp_frame_get_jit_info (MonoInterpFrameHandle frame)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_interp_frame_get_ip (MonoInterpFrameHandle frame)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_interp_frame_get_arg (MonoInterpFrameHandle frame, int pos)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_interp_frame_get_local (MonoInterpFrameHandle frame, int pos)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_interp_frame_get_this (MonoInterpFrameHandle frame)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+mono_interp_start_single_stepping (void)
+{
+}
+
+void
+mono_interp_stop_single_stepping (void)
+{
+}
+
+void
+mono_interp_set_resume_state (MonoJitTlsData *jit_tls, MonoException *ex, MonoInterpFrameHandle interp_frame, gpointer handler_ip)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_interp_frame_iter_init (MonoInterpStackIter *iter, gpointer interp_exit_data)
+{
+       g_assert_not_reached ();
+}
+
+gboolean
+mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame)
+{
+       g_assert_not_reached ();
+       return FALSE;
+}
+
+#endif
+
index 68d3b3998a457502b485c9df372cd8aea54b47e9..712ad43c11e6a12adbeaeadb681d08fa5ab3d415 100644 (file)
@@ -66,6 +66,7 @@
 
 #include <mono/mini/mini.h>
 #include <mono/mini/jit-icalls.h>
+#include <mono/mini/debugger-agent.h>
 
 #ifdef TARGET_ARM
 #include <mono/mini/mini-arm.h>
@@ -104,6 +105,8 @@ init_frame (MonoInvocation *frame, MonoInvocation *parent_frame, RuntimeMethod *
  * Used for testing.
  */
 GSList *jit_classes;
+/* If TRUE, interpreted code will be interrupted at function entry/backward branches */
+static gboolean ss_enabled;
 
 void ves_exec_method (MonoInvocation *frame);
 
@@ -204,14 +207,27 @@ static void debug_enter (MonoInvocation *frame, int *tracing)
 /* Set the current execution state to the resume state in context */
 #define SET_RESUME_STATE(context) do { \
                ip = (context)->handler_ip;                                             \
+               if (frame->ex) { \
                sp->data.p = frame->ex;                                                                                 \
                ++sp;                                                                                                                   \
+               } \
                frame->ex = NULL;                                                                                               \
                (context)->has_resume_state = 0;                                                                \
                (context)->handler_frame = NULL;                                                                \
                goto main_loop;                                                                                                 \
        } while (0)
 
+static void
+set_context (ThreadContext *context)
+{
+       MonoJitTlsData *jit_tls;
+
+       mono_native_tls_set_value (thread_context_id, context);
+       jit_tls = mono_tls_get_jit_tls ();
+       if (jit_tls)
+               jit_tls->interp_context = context;
+}
+
 static void
 ves_real_abort (int line, MonoMethod *mh,
                const unsigned short *ip, stackval *stack, stackval *sp)
@@ -234,6 +250,19 @@ ves_real_abort (int line, MonoMethod *mh,
                THROW_EX (mono_get_exception_execution_engine (NULL), ip); \
        } while (0);
 
+static RuntimeMethod*
+lookup_runtime_method (MonoDomain *domain, MonoMethod *method)
+{
+       RuntimeMethod *rtm;
+       MonoJitDomainInfo *info;
+
+       info = domain_jit_info (domain);
+       mono_domain_jit_code_hash_lock (domain);
+       rtm = mono_internal_hash_table_lookup (&info->interp_code_hash, method);
+       mono_domain_jit_code_hash_unlock (domain);
+       return rtm;
+}
+
 RuntimeMethod*
 mono_interp_get_runtime_method (MonoDomain *domain, MonoMethod *method, MonoError *error)
 {
@@ -278,6 +307,30 @@ mono_interp_create_trampoline (MonoDomain *domain, MonoMethod *method, MonoError
        return mono_interp_get_runtime_method (domain, method, error);
 }
 
+/*
+ * interp_push_lmf:
+ *
+ * Push an LMF frame on the LMF stack
+ * to mark the transition to native code.
+ * This is needed for the native code to
+ * be able to do stack walks.
+ */
+static void
+interp_push_lmf (MonoLMFExt *ext, MonoInvocation *frame)
+{
+       memset (ext, 0, sizeof (MonoLMFExt));
+       ext->interp_exit = TRUE;
+       ext->interp_exit_data = frame;
+
+       mono_push_lmf (ext);
+}
+
+static void
+interp_pop_lmf (MonoLMFExt *ext)
+{
+       mono_pop_lmf (&ext->lmf);
+}
+
 static inline RuntimeMethod*
 get_virtual_method (MonoDomain *domain, RuntimeMethod *runtime_method, MonoObject *obj)
 {
@@ -378,15 +431,19 @@ stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvo
        case MONO_TYPE_U4:
                result->data.i = *(guint32*)data;
                return;
-       case MONO_TYPE_R4:
-               result->data.f = *(float*)data;
+       case MONO_TYPE_R4: {
+               float tmp;
+               /* memmove handles unaligned case */
+               memmove (&tmp, data, sizeof (float));
+               result->data.f = tmp;
                return;
+    }
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
-               result->data.l = *(gint64*)data;
+               memmove (&result->data.l, data, sizeof (gint64));
                return;
        case MONO_TYPE_R8:
-               result->data.f = *(double*)data;
+               memmove (&result->data.f, data, sizeof (double));
                return;
        case MONO_TYPE_STRING:
        case MONO_TYPE_SZARRAY:
@@ -943,19 +1000,11 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
        context->current_frame = frame;
        context->managed_code = 0;
 
-       /*
-        * Push an LMF frame on the LMF stack
-        * to mark the transition to native code.
-        */
-       memset (&ext, 0, sizeof (ext));
-       ext.interp_exit = TRUE;
-       ext.interp_exit_data = frame;
-
-       mono_push_lmf (&ext);
+       interp_push_lmf (&ext, frame);
 
        mono_interp_enter_icall_trampoline (addr, margs);
 
-       mono_pop_lmf (&ext.lmf);
+       interp_pop_lmf (&ext);
 
        context->managed_code = 1;
        /* domain can only be changed by native code */
@@ -1307,7 +1356,7 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb
        int i, type, isobject = 0;
        void *ret = NULL;
        stackval result;
-       stackval *args = alloca (sizeof (stackval) * (sig->param_count + !!sig->hasthis));
+       stackval *args;
        ThreadContext context_struct;
        MonoInvocation *old_frame = NULL;
        jmp_buf env;
@@ -1323,8 +1372,8 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb
                        context->domain = mono_domain_get ();
                        context->current_frame = old_frame;
                        context->managed_code = 0;
-               } else 
-                       mono_native_tls_set_value (thread_context_id, NULL);
+               } else
+                       set_context (NULL);
                if (exc != NULL)
                        *exc = (MonoObject *)frame.ex;
                return retval;
@@ -1336,7 +1385,7 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb
                context_struct.base_frame = &frame;
                context_struct.env_frame = &frame;
                context_struct.current_env = &env;
-               mono_native_tls_set_value (thread_context_id, context);
+               set_context (context);
        }
        else
                old_frame = context->current_frame;
@@ -1384,6 +1433,7 @@ mono_interp_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoOb
                break;
        }
 
+       args = alloca (sizeof (stackval) * (sig->param_count + !!sig->hasthis));
        if (sig->hasthis)
                args [0].data.p = obj;
 
@@ -1453,13 +1503,14 @@ handle_enum:
        if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
                method = mono_marshal_get_native_wrapper (method, FALSE, FALSE);
        INIT_FRAME (&frame,context->current_frame,args,&result,mono_get_root_domain (),method,error);
+
        if (exc)
                frame.invoke_trap = 1;
        context->managed_code = 1;
        ves_exec_method_with_context (&frame, context, NULL, NULL, -1);
        context->managed_code = 0;
        if (context == &context_struct)
-               mono_native_tls_set_value (thread_context_id, NULL);
+               set_context (NULL);
        else
                context->current_frame = old_frame;
        if (frame.ex != NULL) {
@@ -1519,10 +1570,10 @@ interp_entry (InterpEntryData *data)
                memset (context, 0, sizeof (ThreadContext));
                context_struct.base_frame = &frame;
                context_struct.env_frame = &frame;
-               mono_native_tls_set_value (thread_context_id, context);
-       }
-       else
+               set_context (context);
+       } else {
                old_frame = context->current_frame;
+       }
        context->domain = mono_domain_get ();
 
        args = alloca (sizeof (stackval) * (sig->param_count + (sig->hasthis ? 1 : 0)));
@@ -1615,7 +1666,7 @@ interp_entry (InterpEntryData *data)
        ves_exec_method_with_context (&frame, context, NULL, NULL, -1);
        context->managed_code = 0;
        if (context == &context_struct)
-               mono_native_tls_set_value (thread_context_id, NULL);
+               set_context (NULL);
        else
                context->current_frame = old_frame;
 
@@ -2088,8 +2139,17 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                g_print ("(%p) Transforming %s\n", mono_thread_internal_current (), mn);
                g_free (mn);
 #endif
+
+               MonoLMFExt ext;
+
+               /* Use the parent frame as the current frame is not complete yet */
+               interp_push_lmf (&ext, frame->parent);
+
                frame->ex = mono_interp_transform_method (frame->runtime_method, context);
                context->managed_code = 1;
+
+               interp_pop_lmf (&ext);
+
                if (frame->ex) {
                        rtm = NULL;
                        ip = NULL;
@@ -2112,6 +2172,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
        vtalloc = vt_sp;
 #endif
        locals = (unsigned char *) vt_sp + rtm->vt_stack_size;
+       frame->locals = locals;
        child_frame.parent = frame;
 
        if (filter_exception) {
@@ -2136,10 +2197,18 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                MINT_IN_CASE(MINT_NOP)
                        ++ip;
                        MINT_IN_BREAK;
-               MINT_IN_CASE(MINT_BREAK)
+               MINT_IN_CASE(MINT_BREAK) {
                        ++ip;
-                       G_BREAKPOINT (); /* this is not portable... */
+
+                       MonoLMFExt ext;
+
+                       interp_push_lmf (&ext, frame);
+
+                       mono_debugger_agent_user_break ();
+
+                       interp_pop_lmf (&ext);
                        MINT_IN_BREAK;
+               }
                MINT_IN_CASE(MINT_LDNULL) 
                        sp->data.p = NULL;
                        ++ip;
@@ -2257,6 +2326,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                        vtalloc = vt_sp;
 #endif
                        locals = vt_sp + rtm->vt_stack_size;
+                       frame->locals = locals;
                        ip = rtm->new_body_start; /* bypass storing input args from callers frame */
                        MINT_IN_BREAK;
                }
@@ -2567,15 +2637,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                                }
                        }
 
-                       /*
-                        * Push an LMF frame on the LMF stack
-                        * to mark the transition to compiled code.
-                        */
-                       memset (&ext, 0, sizeof (ext));
-                       ext.interp_exit = TRUE;
-                       ext.interp_exit_data = frame;
-
-                       mono_push_lmf (&ext);
+                       interp_push_lmf (&ext, frame);
 
                        switch (pindex) {
                        case 0: {
@@ -2631,7 +2693,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                                break;
                        }
 
-                       mono_pop_lmf (&ext.lmf);
+                       interp_pop_lmf (&ext);
 
                        if (context->has_resume_state) {
                                /*
@@ -2819,7 +2881,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                        goto exit_frame;
                MINT_IN_CASE(MINT_RET_VOID)
                        if (sp > frame->stack)
-                               g_warning ("ret.void: more values on stack: %d", sp-frame->stack);
+                               g_warning ("ret.void: more values on stack: %d %s", sp-frame->stack, mono_method_full_name (frame->runtime_method->method, TRUE));
                        goto exit_frame;
                MINT_IN_CASE(MINT_RET_VT)
                        i32 = READ32(ip + 1);
@@ -3110,7 +3172,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                                gint offset;
                                ip += 2 * (guint32)sp->data.i;
                                offset = READ32 (ip);
-                               ip = st + offset;
+                               ip = ip + offset;
                        } else {
                                ip = st;
                        }
@@ -3139,7 +3201,8 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_LDIND_I8)
                        ++ip;
-                       sp[-1].data.l = *(gint64*)sp[-1].data.p;
+                       /* memmove handles unaligned case */
+                       memmove (&sp [-1].data.l, sp [-1].data.p, sizeof (gint64));
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_LDIND_I) {
                        guint16 offset = * (guint16 *)(ip + 1);
@@ -3486,10 +3549,13 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context, uns
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_CPOBJ) {
                        c = rtm->data_items[* (guint16 *)(ip + 1)];
-                       g_assert (c->byval_arg.type == MONO_TYPE_VALUETYPE);
+                       g_assert (c->valuetype);
                        /* if this assertion fails, we need to add a write barrier */
                        g_assert (!MONO_TYPE_IS_REFERENCE (&c->byval_arg));
-                       stackval_from_data (&c->byval_arg, &sp [-2], sp [-1].data.p, FALSE);
+                       if (c->byval_arg.type == MONO_TYPE_VALUETYPE)
+                               stackval_from_data (&c->byval_arg, &sp [-2], sp [-1].data.p, FALSE);
+                       else
+                               stackval_from_data (&c->byval_arg, sp [-2].data.p, sp [-1].data.p, FALSE);
                        ip += 2;
                        sp -= 2;
                        MINT_IN_BREAK;
@@ -3661,6 +3727,7 @@ array_constructed:
                        frame->ex_handler = NULL;
                        if (!sp->data.p)
                                sp->data.p = mono_get_exception_null_reference ();
+
                        THROW_EX ((MonoException *)sp->data.p, ip);
                        MINT_IN_BREAK;
                MINT_IN_CASE(MINT_LDFLDA_UNSAFE)
@@ -4513,6 +4580,72 @@ array_constructed:
                        ++ip;
                        mono_jit_set_domain (context->original_domain);
                        MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_SDB_INTR_LOC)
+                       if (G_UNLIKELY (ss_enabled)) {
+                               MonoLMFExt ext;
+                               static void (*ss_tramp) (void);
+
+                               if (!ss_tramp) {
+                                       void *tramp = mini_get_single_step_trampoline ();
+                                       mono_memory_barrier ();
+                                       ss_tramp = tramp;
+                               }
+
+                               /*
+                                * Make this point to the MINT_SDB_SEQ_POINT instruction which follows this since
+                                * the address of that instruction is stored as the seq point address.
+                                */
+                               frame->ip = ip + 1;
+
+                               interp_push_lmf (&ext, frame);
+                               /*
+                                * Use the same trampoline as the JIT. This ensures that
+                                * the debugger has the context for the last interpreter
+                                * native frame.
+                                */
+                               ss_tramp ();
+                               interp_pop_lmf (&ext);
+
+                               if (context->has_resume_state) {
+                                       if (frame == context->handler_frame)
+                                               SET_RESUME_STATE (context);
+                                       else
+                                               goto exit_frame;
+                               }
+                       }
+                       ++ip;
+                       MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_SDB_SEQ_POINT)
+                       /* Just a placeholder for a breakpoint */
+                       ++ip;
+                       MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_SDB_BREAKPOINT) {
+                       MonoLMFExt ext;
+
+                       static void (*bp_tramp) (void);
+                       if (!bp_tramp) {
+                               void *tramp = mini_get_breakpoint_trampoline ();
+                               mono_memory_barrier ();
+                               bp_tramp = tramp;
+                       }
+
+                       frame->ip = ip;
+
+                       interp_push_lmf (&ext, frame);
+                       /* Use the same trampoline as the JIT */
+                       bp_tramp ();
+                       interp_pop_lmf (&ext);
+
+                       if (context->has_resume_state) {
+                               if (frame == context->handler_frame)
+                                       SET_RESUME_STATE (context);
+                               else
+                                       goto exit_frame;
+                       }
+
+                       ++ip;
+                       MINT_IN_BREAK;
+               }
 
 #define RELOP(datamem, op) \
        --sp; \
@@ -5058,7 +5191,7 @@ ves_exec_method (MonoInvocation *frame)
                context_struct.current_env = &env;
                context_struct.search_for_handler = 0;
                context_struct.managed_code = 0;
-               mono_native_tls_set_value (thread_context_id, context);
+               set_context (context);
        }
        frame->ip = NULL;
        frame->parent = context->current_frame;
@@ -5076,7 +5209,7 @@ ves_exec_method (MonoInvocation *frame)
                        mono_unhandled_exception ((MonoObject*)frame->ex);
        }
        if (context->base_frame == frame)
-               mono_native_tls_set_value (thread_context_id, NULL);
+               set_context (NULL);
        else
                context->current_frame = frame->parent;
 }
@@ -5099,7 +5232,7 @@ void
 mono_interp_init ()
 {
        mono_native_tls_alloc (&thread_context_id, NULL);
-       mono_native_tls_set_value (thread_context_id, NULL);
+       set_context (NULL);
 
        mono_interp_transform_init ();
 }
@@ -5275,12 +5408,16 @@ mono_interp_regression_list (int verbose, int count, char *images [])
  *   Set the state the interpeter will continue to execute from after execution returns to the interpreter.
  */
 void
-mono_interp_set_resume_state (MonoException *ex, StackFrameInfo *frame, gpointer handler_ip)
+mono_interp_set_resume_state (MonoJitTlsData *jit_tls, MonoException *ex, MonoInterpFrameHandle interp_frame, gpointer handler_ip)
 {
-       ThreadContext *context = mono_native_tls_get_value (thread_context_id);
+       ThreadContext *context;
+
+       g_assert (jit_tls);
+       context = jit_tls->interp_context;
+       g_assert (context);
 
        context->has_resume_state = TRUE;
-       context->handler_frame = frame->interp_frame;
+       context->handler_frame = interp_frame;
        /* This is on the stack, so it doesn't need a wbarrier */
        context->handler_frame->ex = ex;
        context->handler_ip = handler_ip;
@@ -5326,20 +5463,115 @@ mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame)
 
        memset (frame, 0, sizeof (StackFrameInfo));
        /* pinvoke frames doesn't have runtime_method set */
-       while (iframe && !iframe->runtime_method)
+       while (iframe && !(iframe->runtime_method && iframe->runtime_method->code))
                iframe = iframe->parent;
        if (!iframe)
                return FALSE;
 
        frame->type = FRAME_TYPE_INTERP;
+       // FIXME:
+       frame->domain = mono_domain_get ();
        frame->interp_frame = iframe;
        frame->method = iframe->runtime_method->method;
        frame->actual_method = frame->method;
        /* This is the offset in the interpreter IR */
-       frame->native_offset = iframe->ip - iframe->runtime_method->code;
+       frame->native_offset = (guint8*)iframe->ip - (guint8*)iframe->runtime_method->code;
        frame->ji = iframe->runtime_method->jinfo;
 
        stack_iter->current = iframe->parent;
 
        return TRUE;
 }
+
+MonoJitInfo*
+mono_interp_find_jit_info (MonoDomain *domain, MonoMethod *method)
+{
+       RuntimeMethod* rtm;
+
+       rtm = lookup_runtime_method (domain, method);
+       if (rtm)
+               return rtm->jinfo;
+       else
+               return NULL;
+}
+
+void
+mono_interp_set_breakpoint (MonoJitInfo *jinfo, gpointer ip)
+{
+       guint16 *code = (guint16*)ip;
+       g_assert (*code == MINT_SDB_SEQ_POINT);
+       *code = MINT_SDB_BREAKPOINT;
+}
+
+void
+mono_interp_clear_breakpoint (MonoJitInfo *jinfo, gpointer ip)
+{
+       guint16 *code = (guint16*)ip;
+       g_assert (*code == MINT_SDB_BREAKPOINT);
+       *code = MINT_SDB_SEQ_POINT;
+}
+
+MonoJitInfo*
+mono_interp_frame_get_jit_info (MonoInterpFrameHandle frame)
+{
+       MonoInvocation *iframe = (MonoInvocation*)frame;
+
+       g_assert (iframe->runtime_method);
+       return iframe->runtime_method->jinfo;
+}
+
+gpointer
+mono_interp_frame_get_ip (MonoInterpFrameHandle frame)
+{
+       MonoInvocation *iframe = (MonoInvocation*)frame;
+
+       g_assert (iframe->runtime_method);
+       return (gpointer)iframe->ip;
+}
+
+gpointer
+mono_interp_frame_get_arg (MonoInterpFrameHandle frame, int pos)
+{
+       MonoInvocation *iframe = (MonoInvocation*)frame;
+
+       g_assert (iframe->runtime_method);
+
+       int arg_offset = iframe->runtime_method->arg_offsets [pos + (iframe->runtime_method->hasthis ? 1 : 0)];
+
+       return iframe->args + arg_offset;
+}
+
+gpointer
+mono_interp_frame_get_local (MonoInterpFrameHandle frame, int pos)
+{
+       MonoInvocation *iframe = (MonoInvocation*)frame;
+
+       g_assert (iframe->runtime_method);
+
+       return iframe->locals + iframe->runtime_method->local_offsets [pos];
+}
+
+gpointer
+mono_interp_frame_get_this (MonoInterpFrameHandle frame)
+{
+       MonoInvocation *iframe = (MonoInvocation*)frame;
+
+       g_assert (iframe->runtime_method);
+       g_assert (iframe->runtime_method->hasthis);
+
+       int arg_offset = iframe->runtime_method->arg_offsets [0];
+
+       return iframe->args + arg_offset;
+}
+
+void
+mono_interp_start_single_stepping (void)
+{
+       ss_enabled = TRUE;
+}
+
+void
+mono_interp_stop_single_stepping (void)
+{
+       ss_enabled = FALSE;
+}
index cf922507500bc16adae32d32dd1ed0ccf0283c5f..6abf93a6f0a38c900820258f6b73859f2b35d048 100644 (file)
@@ -28,6 +28,8 @@ struct _MonoInterpStackIter {
        gpointer dummy [8];
 };
 
+typedef gpointer MonoInterpFrameHandle;
+
 int
 mono_interp_regression_list (int verbose, int count, char *images []);
 
@@ -53,7 +55,7 @@ void
 interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUnwindOptions options, void *user_data);
 
 void
-mono_interp_set_resume_state (MonoException *ex, StackFrameInfo *frame, gpointer handler_ip);
+mono_interp_set_resume_state (MonoJitTlsData *jit_tls, MonoException *ex, MonoInterpFrameHandle interp_frame, gpointer handler_ip);
 
 void
 mono_interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip);
@@ -64,4 +66,34 @@ mono_interp_frame_iter_init (MonoInterpStackIter *iter, gpointer interp_exit_dat
 gboolean
 mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame);
 
+MonoJitInfo*
+mono_interp_find_jit_info (MonoDomain *domain, MonoMethod *method);
+
+void
+mono_interp_set_breakpoint (MonoJitInfo *jinfo, gpointer ip);
+
+void
+mono_interp_clear_breakpoint (MonoJitInfo *jinfo, gpointer ip);
+
+MonoJitInfo*
+mono_interp_frame_get_jit_info (MonoInterpFrameHandle frame);
+
+gpointer
+mono_interp_frame_get_ip (MonoInterpFrameHandle frame);
+
+gpointer
+mono_interp_frame_get_arg (MonoInterpFrameHandle frame, int pos);
+
+gpointer
+mono_interp_frame_get_local (MonoInterpFrameHandle frame, int pos);
+
+gpointer
+mono_interp_frame_get_this (MonoInterpFrameHandle frame);
+
+void
+mono_interp_start_single_stepping (void);
+
+void
+mono_interp_stop_single_stepping (void);
+
 #endif /* __MONO_MINI_INTERPRETER_H__ */
index e1c58ecf7a968643c8ac0ae638088dfa4f4aea01..b0fa6358c894a4ea71e3611569634a8eee56c310 100644 (file)
@@ -106,7 +106,7 @@ mono_interp_dis_mintop(const guint16 *base, const guint16 *ip)
                        if (i > 0)
                                g_print (", ");
                        offset = (gint32)READ32 (p);
-                       g_print ("IL_%04x", ip - base + 3 + 2 * sval + offset);
+                       g_print ("IL_%04x", p + offset);
                        p += 2;
                }
                g_print (")");
index 190c6647d08adef26aee2599bfc0bbe2c2be21e1..647e5838607a5b02433365592919a620f745feb6 100644 (file)
@@ -521,3 +521,6 @@ OPDEF(MINT_MONO_JIT_DETACH, "mono_jit_detach", 1, MintOpNoArgs)
 
 // FIXME: MintOp
 OPDEF(MINT_JIT_CALL, "mono_jit_call", 2, MintOpNoArgs)
+OPDEF(MINT_SDB_INTR_LOC, "sdb_intr_loc", 1, MintOpNoArgs)
+OPDEF(MINT_SDB_SEQ_POINT, "sdb_seq_point", 1, MintOpNoArgs)
+OPDEF(MINT_SDB_BREAKPOINT, "sdb_breakpoint", 1, MintOpNoArgs)
index 9354aa8737c61109ddc52c4e8e9744d18e05b506..03e848a42db2775bdbb0e7894d26b371f8daac5e 100644 (file)
@@ -15,6 +15,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/tabledefs.h>
+#include <mono/metadata/seq-points-data.h>
 
 #include <mono/mini/mini.h>
 
@@ -34,6 +35,31 @@ typedef struct
        unsigned char flags;
 } StackInfo;
 
+typedef struct {
+       guint8 *ip;
+       GSList *preds;
+       GSList *seq_points;
+       SeqPoint *last_seq_point;
+
+       // This will hold a list of last sequence points of incoming basic blocks
+       SeqPoint **pred_seq_points;
+       guint num_pred_seq_points;
+} InterpBasicBlock;
+
+typedef enum {
+       RELOC_SHORT_BRANCH,
+       RELOC_LONG_BRANCH,
+       RELOC_SWITCH
+} RelocType;
+
+typedef struct {
+       RelocType type;
+       /* In the interpreter IR */
+       int offset;
+       /* In the IL code */
+       int target;
+} Reloc;
+
 typedef struct
 {
        MonoMethod *method;
@@ -45,7 +71,6 @@ typedef struct
        const unsigned char *in_start;
        int code_size;
        int *in_offsets;
-       int *forward_refs;
        StackInfo **stack_state;
        int *stack_height;
        int *vt_stack_size;
@@ -65,6 +90,14 @@ typedef struct
        void **data_items;
        GHashTable *data_hash;
        int *clause_indexes;
+       gboolean gen_sdb_seq_points;
+       GPtrArray *seq_points;
+       InterpBasicBlock **offset_to_bb;
+       InterpBasicBlock *entry_bb;
+       MonoMemPool     *mempool;
+       GList *basic_blocks;
+       GPtrArray *relocs;
+       gboolean verbose_level;
 } TransformData;
 
 #define MINT_TYPE_I1 0
@@ -150,7 +183,7 @@ grow_code (TransformData *td)
        } while (0)
 
 static void 
-handle_branch(TransformData *td, int short_op, int long_op, int offset) 
+handle_branch (TransformData *td, int short_op, int long_op, int offset)
 {
        int shorten_branch = 0;
        int target = td->ip + offset - td->il_code;
@@ -168,12 +201,20 @@ handle_branch(TransformData *td, int short_op, int long_op, int offset)
                        shorten_branch = 1;
                }
        } else {
-               int prev = td->forward_refs [target];
-               td->forward_refs [td->ip - td->il_code] = prev;
-               td->forward_refs [target] = td->ip - td->il_code;
-               offset = 0;
                if (td->header->code_size <= 25000) /* FIX to be precise somehow? */
                        shorten_branch = 1;
+
+               Reloc *reloc = mono_mempool_alloc0 (td->mempool, sizeof (Reloc));
+               if (shorten_branch) {
+                       offset = 0xffff;
+                       reloc->type = RELOC_SHORT_BRANCH;
+               } else {
+                       offset = 0xdeadbeef;
+                       reloc->type = RELOC_LONG_BRANCH;
+               }
+               reloc->offset = td->new_ip - td->new_code;
+               reloc->target = target;
+               g_ptr_array_add (td->relocs, reloc);
        }
        if (shorten_branch) {
                ADD_CODE(td, short_op);
@@ -554,11 +595,13 @@ load_local(TransformData *td, int n)
                WRITE32(td, &size);
        } else {
                g_assert (mt < MINT_TYPE_VT);
-               if (mt == MINT_TYPE_I4 && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL &&
+               if (!td->gen_sdb_seq_points &&
+                       mt == MINT_TYPE_I4 && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL &&
                        td->last_new_ip [0] == MINT_STLOC_I4 && td->last_new_ip [1] == offset) {
                        td->last_new_ip [0] = MINT_STLOC_NP_I4;
-               } else if (mt == MINT_TYPE_O && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL &&
-                       td->last_new_ip [0] == MINT_STLOC_O && td->last_new_ip [1] == offset) {
+               } else if (!td->gen_sdb_seq_points &&
+                                  mt == MINT_TYPE_O && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL &&
+                                  td->last_new_ip [0] == MINT_STLOC_O && td->last_new_ip [1] == offset) {
                        td->last_new_ip [0] = MINT_STLOC_NP_O;
                } else {
                        ADD_CODE(td, MINT_LDLOC_I1 + (mt - MINT_TYPE_I1));
@@ -696,22 +739,8 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                        else
                                target_method = (MonoMethod *)mono_method_get_wrapper_data (method, token);
                        csignature = mono_method_signature (target_method);
-                       if (target_method->klass == mono_defaults.string_class) {
-                               if (target_method->name [0] == 'g') {
-                                       if (strcmp (target_method->name, "get_Chars") == 0)
-                                               op = MINT_GETCHR;
-                                       else if (strcmp (target_method->name, "get_Length") == 0)
-                                               op = MINT_STRLEN;
-                               }
-                       } else if (mono_class_is_subclass_of (target_method->klass, mono_defaults.array_class, FALSE)) {
-                               if (!strcmp (target_method->name, "get_Rank")) {
-                                       op = MINT_ARRAY_RANK;
-                               } else if (!strcmp (target_method->name, "get_Length")) {
-                                       op = MINT_LDLEN;
-                               } else if (!strcmp (target_method->name, "Address")) {
-                                       op = readonly ? MINT_LDELEMA : MINT_LDELEMA_TC;
-                               }
-                       } else if (target_method && generic_context) {
+
+                       if (generic_context) {
                                csignature = mono_inflate_generic_signature (csignature, generic_context, &error);
                                mono_error_cleanup (&error); /* FIXME: don't swallow the error */
                                target_method = mono_class_inflate_generic_method_checked (target_method, generic_context, &error);
@@ -722,6 +751,33 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                csignature = mono_method_signature (target_method);
        }
 
+       /* Intrinsics */
+       if (target_method) {
+               if (target_method->klass == mono_defaults.string_class) {
+                       if (target_method->name [0] == 'g') {
+                               if (strcmp (target_method->name, "get_Chars") == 0)
+                                       op = MINT_GETCHR;
+                               else if (strcmp (target_method->name, "get_Length") == 0)
+                                       op = MINT_STRLEN;
+                       }
+               } else if (mono_class_is_subclass_of (target_method->klass, mono_defaults.array_class, FALSE)) {
+                       if (!strcmp (target_method->name, "get_Rank")) {
+                               op = MINT_ARRAY_RANK;
+                       } else if (!strcmp (target_method->name, "get_Length")) {
+                               op = MINT_LDLEN;
+                       } else if (!strcmp (target_method->name, "Address")) {
+                               op = readonly ? MINT_LDELEMA : MINT_LDELEMA_TC;
+                       }
+               } else if (target_method->klass->image == mono_defaults.corlib &&
+                                  (strcmp (target_method->klass->name_space, "System.Diagnostics") == 0) &&
+                                  (strcmp (target_method->klass->name, "Debugger") == 0)) {
+                       if (!strcmp (target_method->name, "Break") && csignature->param_count == 0) {
+                               if (mini_should_insert_breakpoint (method))
+                                       op = MINT_BREAK;
+                       }
+               }
+       }
+
        if (constrained_class) {
                if (constrained_class->enumtype && !strcmp (target_method->name, "GetHashCode")) {
                        /* Use the corresponding method from the base type to avoid boxing */
@@ -793,7 +849,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                mono_class_init (target_method->klass);
 
        CHECK_STACK (td, csignature->param_count + csignature->hasthis);
-       if (!calli && (!virtual || (target_method->flags & METHOD_ATTRIBUTE_VIRTUAL) == 0) &&
+       if (!calli && op == -1 && (!virtual || (target_method->flags & METHOD_ATTRIBUTE_VIRTUAL) == 0) &&
                (target_method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) == 0 && 
                (target_method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0 &&
                !(target_method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING)) {
@@ -802,7 +858,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
 
                if (/*mono_metadata_signature_equal (method->signature, target_method->signature) */ method == target_method && *(td->ip + 5) == CEE_RET) {
                        int offset;
-                       if (mono_interp_traceopt)
+                       if (td->verbose_level)
                                g_print ("Optimize tail call of %s.%s\n", target_method->klass->name, target_method->name);
 
                        for (i = csignature->param_count - 1 + !!csignature->hasthis; i >= 0; --i)
@@ -818,7 +874,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
                } else {
                        /* mheader might not exist if this is a delegate invoc, etc */
                        if (mheader && *mheader->code == CEE_RET && called_inited) {
-                               if (mono_interp_traceopt)
+                               if (td->verbose_level)
                                        g_print ("Inline (empty) call of %s.%s\n", target_method->klass->name, target_method->name);
                                for (i = 0; i < csignature->param_count; i++) {
                                        ADD_CODE (td, MINT_POP); /*FIX: vt */
@@ -926,6 +982,109 @@ interp_field_from_token (MonoMethod *method, guint32 token, MonoClass **klass, M
        return field;
 }
 
+static InterpBasicBlock*
+get_bb (TransformData *td, InterpBasicBlock *cbb, unsigned char *ip)
+{
+       int offset = ip - td->il_code;
+       InterpBasicBlock *bb = td->offset_to_bb [offset];
+
+       if (!bb) {
+               bb = mono_mempool_alloc0 (td->mempool, sizeof (InterpBasicBlock));
+               bb->ip = ip;
+               td->offset_to_bb [offset] = bb;
+
+               td->basic_blocks = g_list_append_mempool (td->mempool, td->basic_blocks, bb);
+       }
+
+       if (cbb)
+               bb->preds = g_slist_prepend_mempool (td->mempool, bb->preds, cbb);
+       return bb;
+}
+
+/*
+ * get_basic_blocks:
+ *
+ *   Compute the set of IL level basic blocks.
+ */
+static void
+get_basic_blocks (TransformData *td)
+{
+       guint8 *start = (guint8*)td->il_code;
+       guint8 *end = (guint8*)td->il_code + td->code_size;
+       guint8 *ip = start;
+       unsigned char *target;
+       int i;
+       guint cli_addr;
+       const MonoOpcode *opcode;
+       InterpBasicBlock *cbb;
+
+       td->offset_to_bb = mono_mempool_alloc0 (td->mempool, sizeof (InterpBasicBlock*) * (end - start + 1));
+       td->entry_bb = cbb = get_bb (td, NULL, start);
+
+       while (ip < end) {
+               cli_addr = ip - start;
+               td->offset_to_bb [cli_addr] = cbb;
+               i = mono_opcode_value ((const guint8 **)&ip, end);
+               opcode = &mono_opcodes [i];
+               switch (opcode->argument) {
+               case MonoInlineNone:
+                       ip++;
+                       break;
+               case MonoInlineString:
+               case MonoInlineType:
+               case MonoInlineField:
+               case MonoInlineMethod:
+               case MonoInlineTok:
+               case MonoInlineSig:
+               case MonoShortInlineR:
+               case MonoInlineI:
+                       ip += 5;
+                       break;
+               case MonoInlineVar:
+                       ip += 3;
+                       break;
+               case MonoShortInlineVar:
+               case MonoShortInlineI:
+                       ip += 2;
+                       break;
+               case MonoShortInlineBrTarget:
+                       target = start + cli_addr + 2 + (signed char)ip [1];
+                       get_bb (td, cbb, target);
+                       ip += 2;
+                       cbb = get_bb (td, cbb, ip);
+                       break;
+               case MonoInlineBrTarget:
+                       target = start + cli_addr + 5 + (gint32)read32 (ip + 1);
+                       get_bb (td, cbb, target);
+                       ip += 5;
+                       cbb = get_bb (td, cbb, ip);
+                       break;
+               case MonoInlineSwitch: {
+                       guint32 n = read32 (ip + 1);
+                       guint32 j;
+                       ip += 5;
+                       cli_addr += 5 + 4 * n;
+                       target = start + cli_addr;
+                       get_bb (td, cbb, target);
+
+                       for (j = 0; j < n; ++j) {
+                               target = start + cli_addr + (gint32)read32 (ip);
+                               get_bb (td, cbb, target);
+                               ip += 4;
+                       }
+                       cbb = get_bb (td, cbb, ip);
+                       break;
+               }
+               case MonoInlineR:
+               case MonoInlineI8:
+                       ip += 9;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+       }
+}
+
 static void
 interp_save_debug_info (RuntimeMethod *rtm, MonoMethodHeader *header, TransformData *td, GArray *line_numbers)
 {
@@ -940,14 +1099,26 @@ interp_save_debug_info (RuntimeMethod *rtm, MonoMethodHeader *header, TransformD
         */
 
        dinfo = g_new0 (MonoDebugMethodJitInfo, 1);
+       dinfo->num_params = rtm->param_count;
+       dinfo->params = g_new0 (MonoDebugVarInfo, dinfo->num_params);
        dinfo->num_locals = header->num_locals;
        dinfo->locals = g_new0 (MonoDebugVarInfo, header->num_locals);
        dinfo->code_start = (guint8*)rtm->code;
        dinfo->code_size = td->new_ip - td->new_code;
        dinfo->epilogue_begin = 0;
-       dinfo->has_var_info = FALSE;
+       dinfo->has_var_info = TRUE;
        dinfo->num_line_numbers = line_numbers->len;
        dinfo->line_numbers = g_new0 (MonoDebugLineNumberEntry, dinfo->num_line_numbers);
+
+       for (i = 0; i < dinfo->num_params; i++) {
+               MonoDebugVarInfo *var = &dinfo->params [i];
+               var->type = rtm->param_types [i];
+       }
+       for (i = 0; i < dinfo->num_locals; i++) {
+               MonoDebugVarInfo *var = &dinfo->locals [i];
+               var->type = header->locals [i];
+       }
+
        for (i = 0; i < dinfo->num_line_numbers; i++)
                dinfo->line_numbers [i] = g_array_index (line_numbers, MonoDebugLineNumberEntry, i);
        mono_debug_add_method (rtm->method, dinfo, mono_domain_get ());
@@ -955,6 +1126,201 @@ interp_save_debug_info (RuntimeMethod *rtm, MonoMethodHeader *header, TransformD
        mono_debug_free_method_jit_info (dinfo);
 }
 
+/* Same as the code in seq-points.c */
+static void
+insert_pred_seq_point (SeqPoint *last_sp, SeqPoint *sp, GSList **next)
+{
+       GSList *l;
+       int src_index = last_sp->next_offset;
+       int dst_index = sp->next_offset;
+
+       /* bb->in_bb might contain duplicates */
+       for (l = next [src_index]; l; l = l->next)
+               if (GPOINTER_TO_UINT (l->data) == dst_index)
+                       break;
+       if (!l)
+               next [src_index] = g_slist_append (next [src_index], GUINT_TO_POINTER (dst_index));
+}
+
+static void
+recursively_make_pred_seq_points (TransformData *td, InterpBasicBlock *bb)
+{
+       const gpointer MONO_SEQ_SEEN_LOOP = GINT_TO_POINTER(-1);
+       GSList *l;
+
+       GArray *predecessors = g_array_new (FALSE, TRUE, sizeof (gpointer));
+       GHashTable *seen = g_hash_table_new_full (g_direct_hash, NULL, NULL, NULL);
+
+       // Insert/remove sentinel into the memoize table to detect loops containing bb
+       bb->pred_seq_points = MONO_SEQ_SEEN_LOOP;
+
+       for (l = bb->preds; l; l = l->next) {
+               InterpBasicBlock *in_bb = l->data;
+
+               // This bb has the last seq point, append it and continue
+               if (in_bb->last_seq_point != NULL) {
+                       predecessors = g_array_append_val (predecessors, in_bb->last_seq_point);
+                       continue;
+               }
+
+               // We've looped or handled this before, exit early.
+               // No last sequence points to find.
+               if (in_bb->pred_seq_points == MONO_SEQ_SEEN_LOOP)
+                       continue;
+
+               // Take sequence points from incoming basic blocks
+
+               if (in_bb == td->entry_bb)
+                       continue;
+
+               if (in_bb->pred_seq_points == NULL)
+                       recursively_make_pred_seq_points (td, in_bb);
+
+               // Union sequence points with incoming bb's
+               for (int i=0; i < in_bb->num_pred_seq_points; i++) {
+                       if (!g_hash_table_lookup (seen, in_bb->pred_seq_points [i])) {
+                               g_array_append_val (predecessors, in_bb->pred_seq_points [i]);
+                               g_hash_table_insert (seen, in_bb->pred_seq_points [i], (gpointer)&MONO_SEQ_SEEN_LOOP);
+                       }
+               }
+               // predecessors = g_array_append_vals (predecessors, in_bb->pred_seq_points, in_bb->num_pred_seq_points);
+       }
+
+       g_hash_table_destroy (seen);
+
+       if (predecessors->len != 0) {
+               bb->pred_seq_points = mono_mempool_alloc0 (td->mempool, sizeof (SeqPoint *) * predecessors->len);
+               bb->num_pred_seq_points = predecessors->len;
+
+               for (int newer = 0; newer < bb->num_pred_seq_points; newer++) {
+                       bb->pred_seq_points [newer] = g_array_index (predecessors, gpointer, newer);
+               }
+       }
+
+       g_array_free (predecessors, TRUE);
+}
+
+static void
+collect_pred_seq_points (TransformData *td, InterpBasicBlock *bb, SeqPoint *seqp, GSList **next)
+{
+       // Doesn't have a last sequence point, must find from incoming basic blocks
+       if (bb->pred_seq_points == NULL && bb != td->entry_bb)
+               recursively_make_pred_seq_points (td, bb);
+
+       for (int i = 0; i < bb->num_pred_seq_points; i++)
+               insert_pred_seq_point (bb->pred_seq_points [i], seqp, next);
+
+       return;
+}
+
+static void
+save_seq_points (TransformData *td)
+{
+       RuntimeMethod *rtm = td->rtm;
+       GByteArray *array;
+       int i, seq_info_size;
+       MonoSeqPointInfo *info;
+       MonoDomain *domain = mono_domain_get ();
+       GSList **next = NULL;
+       GList *bblist;
+
+       if (!td->gen_sdb_seq_points)
+               return;
+
+       /*
+        * For each sequence point, compute the list of sequence points immediately
+        * following it, this is needed to implement 'step over' in the debugger agent.
+        * Similar to the code in mono_save_seq_point_info ().
+        */
+       for (i = 0; i < td->seq_points->len; ++i) {
+               SeqPoint *sp = g_ptr_array_index (td->seq_points, i);
+
+               /* Store the seq point index here temporarily */
+               sp->next_offset = i;
+       }
+       next = mono_mempool_alloc0 (td->mempool, sizeof (GList*) * td->seq_points->len);
+       for (bblist = td->basic_blocks; bblist; bblist = bblist->next) {
+               InterpBasicBlock *bb = bblist->data;
+
+               GSList *bb_seq_points = g_slist_reverse (bb->seq_points);
+               SeqPoint *last = NULL;
+               for (GSList *l = bb_seq_points; l; l = l->next) {
+                       SeqPoint *sp = l->data;
+
+                       if (sp->il_offset == METHOD_ENTRY_IL_OFFSET || sp->il_offset == METHOD_EXIT_IL_OFFSET)
+                               /* Used to implement method entry/exit events */
+                               continue;
+
+                       if (last != NULL) {
+                               /* Link with the previous seq point in the same bb */
+                               next [last->next_offset] = g_slist_append_mempool (td->mempool, next [last->next_offset], GINT_TO_POINTER (sp->next_offset));
+                       } else {
+                               /* Link with the last bb in the previous bblocks */
+                               collect_pred_seq_points (td, bb, sp, next);
+                       }
+                       last = sp;
+               }
+       }
+
+       /* Serialize the seq points into a byte array */
+       array = g_byte_array_new ();
+       SeqPoint zero_seq_point = {0};
+       SeqPoint* last_seq_point = &zero_seq_point;
+       for (i = 0; i < td->seq_points->len; ++i) {
+               SeqPoint *sp = (SeqPoint*)g_ptr_array_index (td->seq_points, i);
+
+               sp->next_offset = 0;
+               if (mono_seq_point_info_add_seq_point (array, sp, last_seq_point, next [i], TRUE))
+                       last_seq_point = sp;
+       }
+
+       if (td->verbose_level) {
+               g_print ("\nSEQ POINT MAP FOR %s: \n", td->method->name);
+
+               for (i = 0; i < td->seq_points->len; ++i) {
+                       SeqPoint *sp = (SeqPoint*)g_ptr_array_index (td->seq_points, i);
+                       GSList *l;
+
+                       if (!next [i])
+                               continue;
+
+                       g_print ("\tIL0x%x[0x%0x] ->", sp->il_offset, sp->native_offset);
+                       for (l = next [i]; l; l = l->next) {
+                               int next_index = GPOINTER_TO_UINT (l->data);
+                               g_print (" IL0x%x", ((SeqPoint*)g_ptr_array_index (td->seq_points, next_index))->il_offset);
+                       }
+                       g_print ("\n");
+               }
+       }
+
+       info = mono_seq_point_info_new (array->len, TRUE, array->data, TRUE, &seq_info_size);
+       mono_jit_stats.allocated_seq_points_size += seq_info_size;
+
+       g_byte_array_free (array, TRUE);
+
+       mono_domain_lock (domain);
+       g_hash_table_insert (domain_jit_info (domain)->seq_points, rtm->method, info);
+       mono_domain_unlock (domain);
+}
+
+static void
+emit_seq_point (TransformData *td, int il_offset, InterpBasicBlock *cbb, gboolean nonempty_stack)
+{
+       SeqPoint *seqp;
+
+       seqp = mono_mempool_alloc0 (td->mempool, sizeof (SeqPoint));
+       seqp->il_offset = il_offset;
+       seqp->native_offset = (guint8*)td->new_ip - (guint8*)td->new_code;
+       if (nonempty_stack)
+               seqp->flags |= MONO_SEQ_POINT_FLAG_NONEMPTY_STACK;
+
+       ADD_CODE (td, MINT_SDB_SEQ_POINT);
+       g_ptr_array_add (td->seq_points, seqp);
+
+       cbb->seq_points = g_slist_prepend_mempool (td->mempool, cbb->seq_points, seqp);
+       cbb->last_seq_point = seqp;
+}
+
 static void
 generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context)
 {
@@ -976,8 +1342,20 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        TransformData td;
        int generating_code = 1;
        GArray *line_numbers;
+       MonoDebugMethodInfo *minfo;
+       MonoBitSet *seq_point_locs = NULL;
+       MonoBitSet *seq_point_set_locs = NULL;
+       gboolean sym_seq_points = FALSE;
+       InterpBasicBlock *bb_exit = NULL;
+       static gboolean verbose_method_inited;
+       static char* verbose_method_name;
+
+       if (!verbose_method_inited) {
+               verbose_method_name = getenv ("MONO_VERBOSE_METHOD");
+               verbose_method_inited = TRUE;
+       }
 
-       memset(&td, 0, sizeof(td));
+       memset (&td, 0, sizeof(td));
        td.method = method;
        td.rtm = rtm;
        td.is_bb_start = is_bb_start;
@@ -987,8 +1365,8 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        td.max_code_size = td.code_size;
        td.new_code = (unsigned short *)g_malloc(td.max_code_size * sizeof(gushort));
        td.new_code_end = td.new_code + td.max_code_size;
+       td.mempool = mono_mempool_new ();
        td.in_offsets = g_malloc0(header->code_size * sizeof(int));
-       td.forward_refs = g_malloc(header->code_size * sizeof(int));
        td.stack_state = g_malloc0(header->code_size * sizeof(StackInfo *));
        td.stack_height = g_malloc(header->code_size * sizeof(int));
        td.vt_stack_size = g_malloc(header->code_size * sizeof(int));
@@ -997,12 +1375,61 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        td.data_items = NULL;
        td.data_hash = g_hash_table_new (NULL, NULL);
        td.clause_indexes = g_malloc (header->code_size * sizeof (int));
+       td.gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
+       td.seq_points = g_ptr_array_new ();
+       td.relocs = g_ptr_array_new ();
+       td.verbose_level = mono_interp_traceopt;
        rtm->data_items = td.data_items;
        for (i = 0; i < header->code_size; i++) {
-               td.forward_refs [i] = -1;
                td.stack_height [i] = -1;
                td.clause_indexes [i] = -1;
        }
+
+       if (verbose_method_name) {
+               const char *name = verbose_method_name;
+
+               if ((strchr (name, '.') > name) || strchr (name, ':')) {
+                       MonoMethodDesc *desc;
+
+                       desc = mono_method_desc_new (name, TRUE);
+                       if (mono_method_desc_full_match (desc, method)) {
+                               td.verbose_level = 4;
+                       }
+                       mono_method_desc_free (desc);
+               } else {
+                       if (strcmp (method->name, name) == 0)
+                               td.verbose_level = 4;
+               }
+       }
+
+       if (td.gen_sdb_seq_points) {
+               get_basic_blocks (&td);
+
+               minfo = mono_debug_lookup_method (method);
+
+               if (minfo) {
+                       MonoSymSeqPoint *sps;
+                       int i, n_il_offsets;
+
+                       mono_debug_get_seq_points (minfo, NULL, NULL, NULL, &sps, &n_il_offsets);
+                       // FIXME: Free
+                       seq_point_locs = mono_bitset_mem_new (mono_mempool_alloc0 (td.mempool, mono_bitset_alloc_size (header->code_size, 0)), header->code_size, 0);
+                       seq_point_set_locs = mono_bitset_mem_new (mono_mempool_alloc0 (td.mempool, mono_bitset_alloc_size (header->code_size, 0)), header->code_size, 0);
+                       sym_seq_points = TRUE;
+
+                       for (i = 0; i < n_il_offsets; ++i) {
+                               if (sps [i].il_offset < header->code_size)
+                                       mono_bitset_set_fast (seq_point_locs, sps [i].il_offset);
+                       }
+                       g_free (sps);
+               } else if (!method->wrapper_type && !method->dynamic && mono_debug_image_has_debug_info (method->klass->image)) {
+                       /* Methods without line number info like auto-generated property accessors */
+                       seq_point_locs = mono_bitset_new (header->code_size, 0);
+                       seq_point_set_locs = mono_bitset_new (header->code_size, 0);
+                       sym_seq_points = TRUE;
+               }
+       }
+
        td.new_ip = td.new_code;
        td.last_new_ip = NULL;
 
@@ -1045,7 +1472,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        td.ip = header->code;
        end = td.ip + header->code_size;
 
-       if (mono_interp_traceopt) {
+       if (td.verbose_level) {
                char *tmp = mono_disasm_code (NULL, method, td.ip, end);
                char *name = mono_method_full_name (method, TRUE);
                g_print ("Method %s, original code:\n", name);
@@ -1069,6 +1496,12 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                }
        }
 
+       if (sym_seq_points) {
+               InterpBasicBlock *cbb = td.offset_to_bb [0];
+               g_assert (cbb);
+               emit_seq_point (&td, METHOD_ENTRY_IL_OFFSET, cbb, FALSE);
+       }
+
        while (td.ip < end) {
                int in_offset;
 
@@ -1080,38 +1513,10 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                td.in_start = td.ip;
 
                MonoDebugLineNumberEntry lne;
-               lne.native_offset = td.new_ip - td.new_code;
-               lne.il_offset = td.ip - header->code;
+               lne.native_offset = (guint8*)td.new_ip - (guint8*)td.new_code;
+               lne.il_offset = in_offset;
                g_array_append_val (line_numbers, lne);
 
-               while (td.forward_refs [in_offset] >= 0) {
-                       int j = td.forward_refs [in_offset];
-                       int slot;
-                       td.forward_refs [in_offset] = td.forward_refs [j];
-                       if (td.in_offsets [j] < 0) {                        
-                               int old_switch_offset = -td.in_offsets [j];
-                               int new_switch_offset = td.in_offsets [old_switch_offset];
-                               int switch_case = (j - old_switch_offset - 5) / 4;
-                               int n_cases = read32 (header->code + old_switch_offset + 1);
-                               offset = (td.new_ip - td.new_code) - (new_switch_offset + 2 * n_cases + 3);
-                               slot = new_switch_offset + 3 + 2 * switch_case;
-                               td.new_code [slot] = * (unsigned short *)(&offset);
-                               td.new_code [slot + 1] = * ((unsigned short *)&offset + 1);
-                       } else {
-                               int op = td.new_code [td.in_offsets [j]];
-                               if (mono_interp_opargtype [op] == MintOpShortBranch) {
-                                       offset = (td.new_ip - td.new_code) - td.in_offsets [j];
-                                       g_assert (offset <= 32767);
-                                       slot = td.in_offsets [j] + 1;
-                                       td.new_code [slot] = offset;
-                               } else {
-                                       offset = (td.new_ip - td.new_code) - td.in_offsets [j];
-                                       slot = td.in_offsets [j] + 1;
-                                       td.new_code [slot] = * (unsigned short *)(&offset);
-                                       td.new_code [slot + 1] = * ((unsigned short *)&offset + 1);
-                               }
-                       }
-               }
                if (td.stack_height [in_offset] >= 0) {
                        g_assert (is_bb_start [in_offset]);
                        if (td.stack_height [in_offset] > 0)
@@ -1127,7 +1532,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                ++td.ip;
                        continue;
                }
-               if (mono_interp_traceopt > 1) {
+               if (td.verbose_level > 1) {
                        printf("IL_%04lx %s %-10s -> IL_%04lx, sp %ld, %s %-12s vt_sp %u (max %u)\n", 
                                td.ip - td.il_code,
                                td.is_bb_start [td.ip - td.il_code] == 3 ? "<>" :
@@ -1138,6 +1543,26 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                (td.sp > td.stack && (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_VT)) ? (td.sp [-1].klass == NULL ? "?" : td.sp [-1].klass->name) : "",
                                td.vt_sp, td.max_vt_sp);
                }
+
+               if (sym_seq_points && mono_bitset_test_fast (seq_point_locs, td.ip - header->code)) {
+                       InterpBasicBlock *cbb = td.offset_to_bb [td.ip - header->code];
+                       g_assert (cbb);
+
+                       /*
+                        * Make methods interruptable at the beginning, and at the targets of
+                        * backward branches.
+                        */
+                       if (in_offset == 0 || g_slist_length (cbb->preds) > 1)
+                               ADD_CODE (&td, MINT_SDB_INTR_LOC);
+
+                       emit_seq_point (&td, in_offset, cbb, FALSE);
+
+                       mono_bitset_set_fast (seq_point_set_locs, td.ip - header->code);
+               }
+
+               if (sym_seq_points)
+                       bb_exit = td.offset_to_bb [td.ip - header->code];
+
                switch (*td.ip) {
                case CEE_NOP: 
                        /* lose it */
@@ -1318,7 +1743,20 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                case CEE_CALLVIRT: /* Fall through */
                case CEE_CALLI:    /* Fall through */
                case CEE_CALL: {
+                       gboolean need_seq_point = FALSE;
+
+                       if (sym_seq_points && !mono_bitset_test_fast (seq_point_locs, td.ip + 5 - header->code))
+                               need_seq_point = TRUE;
+
                        interp_transform_call (&td, method, NULL, domain, generic_context, is_bb_start, body_start_offset, constrained_class, readonly);
+
+                       if (need_seq_point) {
+                               InterpBasicBlock *cbb = td.offset_to_bb [td.ip - header->code];
+                               g_assert (cbb);
+
+                               emit_seq_point (&td, td.ip - header->code, cbb, TRUE);
+                       }
+
                        constrained_class = NULL;
                        readonly = FALSE;
                        break;
@@ -1337,6 +1775,13 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                g_warning ("%s.%s: CEE_RET: more values on stack: %d", td.method->klass->name, td.method->name, td.sp - td.stack);
                        if (td.vt_sp != vt_size)
                                g_error ("%s.%s: CEE_RET: value type stack: %d vs. %d", td.method->klass->name, td.method->name, td.vt_sp, vt_size);
+
+                       if (sym_seq_points) {
+                               InterpBasicBlock *cbb = td.offset_to_bb [td.ip - header->code];
+                               g_assert (cbb);
+                               emit_seq_point (&td, METHOD_EXIT_IL_OFFSET, bb_exit, FALSE);
+                       }
+
                        if (vt_size == 0)
                                SIMPLE_OP(td, signature->ret->type == MONO_TYPE_VOID ? MINT_RET_VOID : MINT_RET);
                        else {
@@ -1456,15 +1901,12 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                case CEE_SWITCH: {
                        guint32 n;
                        const unsigned char *next_ip;
-                       const unsigned char *base_ip = td.ip;
-                       unsigned short *next_new_ip;
                        ++td.ip;
                        n = read32 (td.ip);
                        ADD_CODE (&td, MINT_SWITCH);
                        WRITE32 (&td, &n);
                        td.ip += 4;
                        next_ip = td.ip + n * 4;
-                       next_new_ip = td.new_ip + n * 2;
                        --td.sp;
                        int stack_height = td.sp - td.stack;
                        for (i = 0; i < n; i++) {
@@ -1475,16 +1917,19 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                        if (stack_height > 0 && stack_height != td.stack_height [target])
                                                g_warning ("SWITCH with back branch and non-empty stack");
 #endif
-                                       target = td.in_offsets [target] - (next_new_ip - td.new_code);
+                                       target = td.in_offsets [target] - (td.new_ip - td.new_code);
                                } else {
                                        td.stack_height [target] = stack_height;
                                        td.vt_stack_size [target] = td.vt_sp;
                                        if (stack_height > 0)
                                                td.stack_state [target] = g_memdup (td.stack, stack_height * sizeof (td.stack [0]));
-                                       int prev = td.forward_refs [target];
-                                       td.forward_refs [td.ip - td.il_code] = prev;
-                                       td.forward_refs [target] = td.ip - td.il_code;
-                                       td.in_offsets [td.ip - td.il_code] = - (base_ip - td.il_code);
+
+                                       Reloc *reloc = mono_mempool_alloc0 (td.mempool, sizeof (Reloc));
+                                       reloc->type = RELOC_SWITCH;
+                                       reloc->offset = td.new_ip - td.new_code;
+                                       reloc->target = target;
+                                       g_ptr_array_add (td.relocs, reloc);
+                                       target = 0xffff;
                                }
                                WRITE32 (&td, &target);
                                td.ip += 4;
@@ -1942,12 +2387,13 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                        MonoString *s;
                        token = mono_metadata_token_index (read32 (td.ip + 1));
                        td.ip += 5;
-                       if (method->wrapper_type != MONO_WRAPPER_NONE) {
-                               s = mono_string_new_wrapper(
-                                       mono_method_get_wrapper_data (method, token));
-                       }
-                       else
+                       if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) {
+                               s = mono_method_get_wrapper_data (method, token);
+                       } else if (method->wrapper_type != MONO_WRAPPER_NONE) {
+                               s = mono_string_new_wrapper (mono_method_get_wrapper_data (method, token));
+                       } else {
                                s = mono_ldstr (domain, image, token);
+                       }
                        ADD_CODE(&td, MINT_LDSTR);
                        ADD_CODE(&td, get_data_item_index (&td, s));
                        PUSH_TYPE(&td, STACK_TYPE_O, mono_defaults.string_class);
@@ -3237,8 +3683,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                ++td.ip;
                                break;
                        case CEE_UNALIGNED_:
-                               ++td.ip;
-                               /* FIX: should do something? */;
+                               td.ip += 2;
                                break;
                        case CEE_VOLATILE_:
                                ++td.ip;
@@ -3342,9 +3787,40 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                td.last_ip = td.in_start;
        }
 
-       if (mono_interp_traceopt) {
+       /* Handle relocations */
+       for (int i = 0; i < td.relocs->len; ++i) {
+               Reloc *reloc = g_ptr_array_index (td.relocs, i);
+
+               int offset = td.in_offsets [reloc->target] - reloc->offset;
+
+               switch (reloc->type) {
+               case RELOC_SHORT_BRANCH:
+                       g_assert (td.new_code [reloc->offset + 1] == 0xffff);
+                       td.new_code [reloc->offset + 1] = offset;
+                       break;
+               case RELOC_LONG_BRANCH: {
+                       guint16 *v = (guint16 *) &offset;
+                       g_assert (td.new_code [reloc->offset + 1] == 0xbeef);
+                       g_assert (td.new_code [reloc->offset + 2] == 0xdead);
+                       td.new_code [reloc->offset + 1] = *(guint16 *) v;
+                       td.new_code [reloc->offset + 2] = *(guint16 *) (v + 1);
+                       break;
+               }
+               case RELOC_SWITCH: {
+                       guint16 *v = (guint16*)&offset;
+                       td.new_code [reloc->offset] = *(guint16*)v;
+                       td.new_code [reloc->offset + 1] = *(guint16*)(v + 1);
+                       break;
+               }
+               default:
+                       g_assert_not_reached ();
+                       break;
+               }
+       }
+
+       if (td.verbose_level) {
                const guint16 *p = td.new_code;
-               printf("Runtime method: %p, VT stack size: %d\n", rtm, td.max_vt_sp);
+               printf("Runtime method: %s %p, VT stack size: %d\n", mono_method_full_name (method, TRUE), rtm, td.max_vt_sp);
                printf("Calculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack);
                while (p < td.new_ip) {
                        p = mono_interp_dis_mintop(td.new_code, p);
@@ -3384,6 +3860,7 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        /* Create a MonoJitInfo for the interpreted method by creating the interpreter IR as the native code. */
        int jinfo_len = mono_jit_info_size (0, header->num_clauses, 0);
        MonoJitInfo *jinfo = (MonoJitInfo *)mono_domain_alloc0 (domain, jinfo_len);
+       jinfo->is_interp = 1;
        rtm->jinfo = jinfo;
        mono_jit_info_init (jinfo, method, (guint8*)rtm->code, code_len, 0, header->num_clauses, 0);
        for (i = 0; i < jinfo->num_clauses; ++i) {
@@ -3391,17 +3868,18 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                MonoExceptionClause *c = rtm->clauses + i;
 
                ei->flags = c->flags;
-               ei->try_start = rtm->code + c->try_offset;
-               ei->try_end = rtm->code + c->try_offset + c->try_len;
-               ei->handler_start = rtm->code + c->handler_offset;
+               ei->try_start = (guint8*)(rtm->code + c->try_offset);
+               ei->try_end = (guint8*)(rtm->code + c->try_offset + c->try_len);
+               ei->handler_start = (guint8*)(rtm->code + c->handler_offset);
                if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
                } else {
                        ei->data.catch_class = c->data.catch_class;
                }
        }
 
+       save_seq_points (&td);
+
        g_free (td.in_offsets);
-       g_free (td.forward_refs);
        for (i = 0; i < header->code_size; ++i)
                g_free (td.stack_state [i]);
        g_free (td.stack_state);
@@ -3411,7 +3889,10 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
        g_free (td.stack);
        g_hash_table_destroy (td.data_hash);
        g_free (td.clause_indexes);
+       g_ptr_array_free (td.seq_points, TRUE);
        g_array_free (line_numbers, TRUE);
+       g_ptr_array_free (td.relocs, TRUE);
+       mono_mempool_destroy (td.mempool);
 }
 
 static mono_mutex_t calc_section;
@@ -3482,7 +3963,7 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
                mono_os_mutex_lock(&calc_section);
                if (runtime_method->transformed) {
                        mono_os_mutex_unlock(&calc_section);
-                       mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_OK);
+                       mono_profiler_method_end_jit (method, runtime_method->jinfo, MONO_PROFILE_OK);
                        return NULL;
                }
 
@@ -3657,7 +4138,7 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
        if (runtime_method->transformed) {
                mono_os_mutex_unlock(&calc_section);
                g_free (is_bb_start);
-               mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_OK);
+               mono_profiler_method_end_jit (method, runtime_method->jinfo, MONO_PROFILE_OK);
                return NULL;
        }
 
@@ -3708,7 +4189,8 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
 
        g_free (is_bb_start);
 
-       mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_OK);
+       // FIXME: Add a different callback ?
+       mono_profiler_method_end_jit (method, runtime_method->jinfo, MONO_PROFILE_OK);
        runtime_method->transformed = TRUE;
        mono_os_mutex_unlock(&calc_section);
 
index f20d6790eea5bb45770d5d44fab00404aedbbbcb..6a6e11006cc0d395d8cd093cb51f6f667547cc98 100644 (file)
@@ -8,22 +8,25 @@
 
 #ifndef DISABLE_JIT
 
+#include <mono/metadata/gc-internals.h>
 #include <mono/utils/mono-memory-model.h>
 
 #include "mini.h"
 #include "ir-emit.h"
+#include "jit-icalls.h"
 
 #define MAX_INLINE_COPIES 10
+#define MAX_INLINE_COPY_SIZE 10000
 
 void 
 mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align)
 {
        int val_reg;
 
+       /*FIXME arbitrary hack to avoid unbound code expansion.*/
+       g_assert (size < MAX_INLINE_COPY_SIZE);
        g_assert (val == 0);
-
-       if (align == 0)
-               align = 4;
+       g_assert (align > 0);
 
        if ((size <= SIZEOF_REGISTER) && (size <= align)) {
                switch (size) {
@@ -51,39 +54,51 @@ mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val,
        else
                MONO_EMIT_NEW_ICONST (cfg, val_reg, val);
 
-       if (align < 4) {
-               /* This could be optimized further if neccesary */
-               while (size >= 1) {
-                       MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
-                       offset += 1;
-                       size -= 1;
-               }
-               return;
-       }       
-
-       if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
-               if (offset % 8) {
-                       MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
-                       offset += 4;
-                       size -= 4;
-               }
+       if (align < SIZEOF_VOID_P) {
+               if (align % 2 == 1)
+                       goto set_1;
+               if (align % 4 == 2)
+                       goto set_2;
+               if (SIZEOF_VOID_P == 8 && align % 8 == 4)
+                       goto set_4;
+       }
+
+       //Unaligned offsets don't naturaly happen in the runtime, so it's ok to be conservative in how we copy
+       //We assume that input src and dest are be aligned to `align` so offset just worsen it
+       int offsets_mask = offset & 0x7; //we only care about the misalignment part
+       if (offsets_mask) {
+               if (offsets_mask % 2 == 1)
+                       goto set_1;
+               if (offsets_mask % 4 == 2)
+                       goto set_2;
+               if (SIZEOF_VOID_P == 8 && offsets_mask % 8 == 4)
+                       goto set_4;
+       }
+
+       if (SIZEOF_REGISTER == 8) {
                while (size >= 8) {
                        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
                        offset += 8;
                        size -= 8;
                }
-       }       
+       }
 
+set_4:
        while (size >= 4) {
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
                offset += 4;
                size -= 4;
        }
+
+
+set_2:
        while (size >= 2) {
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
                offset += 2;
                size -= 2;
        }
+
+set_1:
        while (size >= 1) {
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
                offset += 1;
@@ -96,25 +111,32 @@ mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int so
 {
        int cur_reg;
 
-       if (align == 0)
-               align = 4;
-
        /*FIXME arbitrary hack to avoid unbound code expansion.*/
-       g_assert (size < 10000);
+       g_assert (size < MAX_INLINE_COPY_SIZE);
+       g_assert (align > 0);
+
+       if (align < SIZEOF_VOID_P) {
+               if (align == 4)
+                       goto copy_4;
+               if (align == 2)
+                       goto copy_2;
+               goto copy_1;
+       }
 
-       if (align < 4) {
-               /* This could be optimized further if neccesary */
-               while (size >= 1) {
-                       cur_reg = alloc_preg (cfg);
-                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
-                       MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
-                       doffset += 1;
-                       soffset += 1;
-                       size -= 1;
-               }
+       //Unaligned offsets don't naturaly happen in the runtime, so it's ok to be conservative in how we copy
+       //We assume that input src and dest are be aligned to `align` so offset just worsen it
+       int offsets_mask = (doffset | soffset) & 0x7; //we only care about the misalignment part
+       if (offsets_mask) {
+               if (offsets_mask % 2 == 1)
+                       goto copy_1;
+               if (offsets_mask % 4 == 2)
+                       goto copy_2;
+               if (SIZEOF_VOID_P == 8 && offsets_mask % 8 == 4)
+                       goto copy_4;
        }
 
-       if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
+
+       if (SIZEOF_REGISTER == 8) {
                while (size >= 8) {
                        cur_reg = alloc_preg (cfg);
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, cur_reg, srcreg, soffset);
@@ -123,8 +145,9 @@ mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int so
                        soffset += 8;
                        size -= 8;
                }
-       }       
+       }
 
+copy_4:
        while (size >= 4) {
                cur_reg = alloc_preg (cfg);
                MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, srcreg, soffset);
@@ -133,6 +156,8 @@ mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int so
                soffset += 4;
                size -= 4;
        }
+
+copy_2:
        while (size >= 2) {
                cur_reg = alloc_preg (cfg);
                MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, srcreg, soffset);
@@ -141,6 +166,8 @@ mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int so
                soffset += 2;
                size -= 2;
        }
+
+copy_1:
        while (size >= 1) {
                cur_reg = alloc_preg (cfg);
                MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
@@ -157,7 +184,7 @@ mini_emit_memcpy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, Mono
        /* FIXME: Optimize the case when src/dest is OP_LDADDR */
 
        /* We can't do copies at a smaller granule than the provided alignment */
-       if (size_ins || ((size / align > MAX_INLINE_COPIES) && !(cfg->opt & MONO_OPT_INTRINS))) {
+       if (size_ins || (size / align > MAX_INLINE_COPIES) || !(cfg->opt & MONO_OPT_INTRINS)) {
                MonoInst *iargs [3];
                iargs [0] = dest;
                iargs [1] = src;
@@ -177,7 +204,7 @@ mini_emit_memset_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *value_ins
        /* FIXME: Optimize the case when dest is OP_LDADDR */
 
        /* We can't do copies at a smaller granule than the provided alignment */
-       if (value_ins || size_ins || value != 0 || ((size / align > MAX_INLINE_COPIES) && !(cfg->opt & MONO_OPT_INTRINS))) {
+       if (value_ins || size_ins || value != 0 || (size / align > MAX_INLINE_COPIES) || !(cfg->opt & MONO_OPT_INTRINS)) {
                MonoInst *iargs [3];
                iargs [0] = dest;
 
@@ -207,12 +234,232 @@ mini_emit_memset_const_size (MonoCompile *cfg, MonoInst *dest, int value, int si
        mini_emit_memset_internal (cfg, dest, NULL, value, NULL, size, align);
 }
 
+
+static void
+create_write_barrier_bitmap (MonoCompile *cfg, MonoClass *klass, unsigned *wb_bitmap, int offset)
+{
+       MonoClassField *field;
+       gpointer iter = NULL;
+
+       while ((field = mono_class_get_fields (klass, &iter))) {
+               int foffset;
+
+               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
+                       continue;
+               foffset = klass->valuetype ? field->offset - sizeof (MonoObject): field->offset;
+               if (mini_type_is_reference (mono_field_get_type (field))) {
+                       g_assert ((foffset % SIZEOF_VOID_P) == 0);
+                       *wb_bitmap |= 1 << ((offset + foffset) / SIZEOF_VOID_P);
+               } else {
+                       MonoClass *field_class = mono_class_from_mono_type (field->type);
+                       if (field_class->has_references)
+                               create_write_barrier_bitmap (cfg, field_class, wb_bitmap, offset + foffset);
+               }
+       }
+}
+
+static gboolean
+mini_emit_wb_aware_memcpy (MonoCompile *cfg, MonoClass *klass, MonoInst *iargs[4], int size, int align)
+{
+       int dest_ptr_reg, tmp_reg, destreg, srcreg, offset;
+       unsigned need_wb = 0;
+
+       if (align == 0)
+               align = 4;
+
+       /*types with references can't have alignment smaller than sizeof(void*) */
+       if (align < SIZEOF_VOID_P)
+               return FALSE;
+
+       if (size > 5 * SIZEOF_VOID_P)
+               return FALSE;
+
+       create_write_barrier_bitmap (cfg, klass, &need_wb, 0);
+
+       destreg = iargs [0]->dreg;
+       srcreg = iargs [1]->dreg;
+       offset = 0;
+
+       dest_ptr_reg = alloc_preg (cfg);
+       tmp_reg = alloc_preg (cfg);
+
+       /*tmp = dreg*/
+       EMIT_NEW_UNALU (cfg, iargs [0], OP_MOVE, dest_ptr_reg, destreg);
+
+       while (size >= SIZEOF_VOID_P) {
+               MonoInst *load_inst;
+               MONO_INST_NEW (cfg, load_inst, OP_LOAD_MEMBASE);
+               load_inst->dreg = tmp_reg;
+               load_inst->inst_basereg = srcreg;
+               load_inst->inst_offset = offset;
+               MONO_ADD_INS (cfg->cbb, load_inst);
+
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, dest_ptr_reg, 0, tmp_reg);
+
+               if (need_wb & 0x1)
+                       mini_emit_write_barrier (cfg, iargs [0], load_inst);
+
+               offset += SIZEOF_VOID_P;
+               size -= SIZEOF_VOID_P;
+               need_wb >>= 1;
+
+               /*tmp += sizeof (void*)*/
+               if (size >= SIZEOF_VOID_P) {
+                       NEW_BIALU_IMM (cfg, iargs [0], OP_PADD_IMM, dest_ptr_reg, dest_ptr_reg, SIZEOF_VOID_P);
+                       MONO_ADD_INS (cfg->cbb, iargs [0]);
+               }
+       }
+
+       /* Those cannot be references since size < sizeof (void*) */
+       while (size >= 4) {
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, tmp_reg, srcreg, offset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, tmp_reg);
+               offset += 4;
+               size -= 4;
+       }
+
+       while (size >= 2) {
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, tmp_reg, srcreg, offset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, tmp_reg);
+               offset += 2;
+               size -= 2;
+       }
+
+       while (size >= 1) {
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, tmp_reg, srcreg, offset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, tmp_reg);
+               offset += 1;
+               size -= 1;
+       }
+
+       return TRUE;
+}
+
+static void
+mini_emit_memory_copy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, int explicit_align, gboolean native)
+{
+       MonoInst *iargs [4];
+       int size;
+       guint32 align = 0;
+       MonoInst *size_ins = NULL;
+       MonoInst *memcpy_ins = NULL;
+
+       g_assert (klass);
+       /*
+       Fun fact about @native. It's false that @klass will have no ref when @native is true.
+       This happens in pinvoke2. What goes is that marshal.c uses CEE_MONO_LDOBJNATIVE and pass klass.
+       The actual stuff being copied will have no refs, but @klass might.
+       This means we can't assert !(klass->has_references && native).
+       */
+
+       if (cfg->gshared)
+               klass = mono_class_from_mono_type (mini_get_underlying_type (&klass->byval_arg));
+
+       /*
+        * This check breaks with spilled vars... need to handle it during verification anyway.
+        * g_assert (klass && klass == src->klass && klass == dest->klass);
+        */
+
+       if (mini_is_gsharedvt_klass (klass)) {
+               g_assert (!native);
+               size_ins = mini_emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_VALUE_SIZE);
+               memcpy_ins = mini_emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_MEMCPY);
+       }
+
+       if (native)
+               size = mono_class_native_size (klass, &align);
+       else
+               size = mono_class_value_size (klass, &align);
+
+       if (!align)
+               align = SIZEOF_VOID_P;
+       if (explicit_align)
+               align = explicit_align;
+
+       if (mini_type_is_reference (&klass->byval_arg)) { // Refs *MUST* be naturally aligned
+               MonoInst *store, *load;
+               int dreg = alloc_ireg_ref (cfg);
+
+               NEW_LOAD_MEMBASE (cfg, load, OP_LOAD_MEMBASE, dreg, src->dreg, 0);
+               MONO_ADD_INS (cfg->cbb, load);
+
+               NEW_STORE_MEMBASE (cfg, store, OP_STORE_MEMBASE_REG, dest->dreg, 0, dreg);
+               MONO_ADD_INS (cfg->cbb, store);
+
+               mini_emit_write_barrier (cfg, dest, src);
+       } else if (cfg->gen_write_barriers && (klass->has_references || size_ins) && !native) {         /* if native is true there should be no references in the struct */
+               /* Avoid barriers when storing to the stack */
+               if (!((dest->opcode == OP_ADD_IMM && dest->sreg1 == cfg->frame_reg) ||
+                         (dest->opcode == OP_LDADDR))) {
+                       int context_used;
+
+                       iargs [0] = dest;
+                       iargs [1] = src;
+
+                       context_used = mini_class_check_context_used (cfg, klass);
+
+                       /* It's ok to intrinsify under gsharing since shared code types are layout stable. */
+                       if (!size_ins && (cfg->opt & MONO_OPT_INTRINS) && mini_emit_wb_aware_memcpy (cfg, klass, iargs, size, align)) {
+                       } else if (size_ins || align < SIZEOF_VOID_P) {
+                               if (context_used) {
+                                       iargs [2] = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
+                               }  else {
+                                       iargs [2] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_CLASS, klass);
+                                       if (!cfg->compile_aot)
+                                               mono_class_compute_gc_descriptor (klass);
+                               }
+                               if (size_ins)
+                                       mono_emit_jit_icall (cfg, mono_gsharedvt_value_copy, iargs);
+                               else
+                                       mono_emit_jit_icall (cfg, mono_value_copy, iargs);
+                       } else {
+                               /* We don't unroll more than 5 stores to avoid code bloat. */
+                               /*This is harmless and simplify mono_gc_get_range_copy_func */
+                               size += (SIZEOF_VOID_P - 1);
+                               size &= ~(SIZEOF_VOID_P - 1);
+
+                               EMIT_NEW_ICONST (cfg, iargs [2], size);
+                               mono_emit_jit_icall (cfg, mono_gc_get_range_copy_func (), iargs);
+                       }
+                       return;
+               }
+       }
+
+       if (size_ins) {
+               iargs [0] = dest;
+               iargs [1] = src;
+               iargs [2] = size_ins;
+               mini_emit_calli (cfg, mono_method_signature (mini_get_memcpy_method ()), iargs, memcpy_ins, NULL, NULL);
+       } else {
+               mini_emit_memcpy_const_size (cfg, dest, src, size, align);
+       }
+}
+
 MonoInst*
 mini_emit_memory_load (MonoCompile *cfg, MonoType *type, MonoInst *src, int offset, int ins_flag)
 {
        MonoInst *ins;
 
-       EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, type, src->dreg, offset);
+       if (ins_flag & MONO_INST_UNALIGNED) {
+               MonoInst *addr, *tmp_var;
+               int align;
+               int size = mono_type_size (type, &align);
+
+               if (offset) {
+                       MonoInst *add_offset;
+                       NEW_BIALU_IMM (cfg, add_offset, OP_PADD_IMM, alloc_preg (cfg), src->dreg, offset);
+                       MONO_ADD_INS (cfg->cbb, add_offset);
+                       src = add_offset;
+               }
+
+               tmp_var = mono_compile_create_var (cfg, type, OP_LOCAL);
+               EMIT_NEW_VARLOADA (cfg, addr, tmp_var, tmp_var->inst_vtype);
+
+               mini_emit_memcpy_const_size (cfg, addr, src, size, 1);
+               EMIT_NEW_TEMPLOAD (cfg, ins, tmp_var->inst_c0);
+       } else {
+               EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, type, src->dreg, offset);
+       }
        ins->flags |= ins_flag;
 
        if (ins_flag & MONO_INST_VOLATILE) {
@@ -233,6 +480,16 @@ mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoIn
                /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
                mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
        }
+
+       if (ins_flag & MONO_INST_UNALIGNED) {
+               MonoInst *addr, *mov, *tmp_var;
+
+               tmp_var = mono_compile_create_var (cfg, type, OP_LOCAL);
+               EMIT_NEW_TEMPSTORE (cfg, mov, tmp_var->inst_c0, value);
+               EMIT_NEW_VARLOADA (cfg, addr, tmp_var, tmp_var->inst_vtype);
+               mini_emit_memory_copy_internal (cfg, dest, addr, mono_class_from_mono_type (type), 1, FALSE);
+       }
+
        /* FIXME: should check item at sp [1] is compatible with the type of the store. */
 
        EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, type, dest->dreg, 0, value->dreg);
@@ -247,7 +504,7 @@ mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoIn
 void
 mini_emit_memory_copy_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoInst *size, int ins_flag)
 {
-       int align = SIZEOF_VOID_P;
+       int align = (ins_flag & MONO_INST_UNALIGNED) ? 1 : SIZEOF_VOID_P;
 
        /*
         * FIXME: It's unclear whether we should be emitting both the acquire
@@ -262,11 +519,9 @@ mini_emit_memory_copy_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *src, Mo
                mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ);
        }
 
-       if ((cfg->opt & MONO_OPT_INTRINS) && (size->opcode == OP_ICONST) && size->inst_c0 < 10000) {
+       if ((cfg->opt & MONO_OPT_INTRINS) && (size->opcode == OP_ICONST)) {
                mini_emit_memcpy_const_size (cfg, dest, src, size->inst_c0, align);
        } else {
-               if (cfg->verbose_level > 3)
-                       printf ("EMITING REGULAR COPY\n");
                mini_emit_memcpy_internal (cfg, dest, src, size, 0, align);
        }
 
@@ -279,7 +534,7 @@ mini_emit_memory_copy_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *src, Mo
 void
 mini_emit_memory_init_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *value, MonoInst *size, int ins_flag)
 {
-       int align = SIZEOF_VOID_P;
+       int align = (ins_flag & MONO_INST_UNALIGNED) ? 1 : SIZEOF_VOID_P;
 
        if (ins_flag & MONO_INST_VOLATILE) {
                /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
@@ -295,4 +550,37 @@ mini_emit_memory_init_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *value,
 
 }
 
+/*
+ * If @klass is a valuetype, emit code to copy a value with source address in @src and destination address in @dest.
+ * If @klass is a ref type, copy a pointer instead.
+ */
+
+void
+mini_emit_memory_copy (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native, int ins_flag)
+{
+       int explicit_align = 0;
+       if (ins_flag & MONO_INST_UNALIGNED)
+               explicit_align = 1;
+
+       /*
+        * FIXME: It's unclear whether we should be emitting both the acquire
+        * and release barriers for cpblk. It is technically both a load and
+        * store operation, so it seems like that's the sensible thing to do.
+        *
+        * FIXME: We emit full barriers on both sides of the operation for
+        * simplicity. We should have a separate atomic memcpy method instead.
+        */
+       if (ins_flag & MONO_INST_VOLATILE) {
+               /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */
+               mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ);
+       }
+
+       mini_emit_memory_copy_internal (cfg, dest, src, klass, explicit_align, native);
+
+       if (ins_flag & MONO_INST_VOLATILE) {
+               /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */
+               mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ);
+       }
+}
+
 #endif
index 0a34f582c637abdd9d565e7ee08a6305f752c2f4..3817d2809f9e0acecb6c2857f0be4a0246017371 100644 (file)
@@ -2827,29 +2827,6 @@ mini_get_memcpy_method (void)
        return memcpy_method;
 }
 
-static void
-create_write_barrier_bitmap (MonoCompile *cfg, MonoClass *klass, unsigned *wb_bitmap, int offset)
-{
-       MonoClassField *field;
-       gpointer iter = NULL;
-
-       while ((field = mono_class_get_fields (klass, &iter))) {
-               int foffset;
-
-               if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
-                       continue;
-               foffset = klass->valuetype ? field->offset - sizeof (MonoObject): field->offset;
-               if (mini_type_is_reference (mono_field_get_type (field))) {
-                       g_assert ((foffset % SIZEOF_VOID_P) == 0);
-                       *wb_bitmap |= 1 << ((offset + foffset) / SIZEOF_VOID_P);
-               } else {
-                       MonoClass *field_class = mono_class_from_mono_type (field->type);
-                       if (field_class->has_references)
-                               create_write_barrier_bitmap (cfg, field_class, wb_bitmap, offset + foffset);
-               }
-       }
-}
-
 void
 mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
 {
@@ -2863,6 +2840,8 @@ mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
        if (!cfg->gen_write_barriers)
                return;
 
+       //method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER && !MONO_INS_IS_PCONST_NULL (sp [1])
+
        card_table = mono_gc_get_card_table (&card_table_shift_bits, &card_table_mask);
 
        mono_gc_get_nursery (&nursery_shift_bits, &nursery_size);
@@ -2906,177 +2885,6 @@ mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
        EMIT_NEW_DUMMY_USE (cfg, dummy_use, value);
 }
 
-gboolean
-mini_emit_wb_aware_memcpy (MonoCompile *cfg, MonoClass *klass, MonoInst *iargs[4], int size, int align)
-{
-       int dest_ptr_reg, tmp_reg, destreg, srcreg, offset;
-       unsigned need_wb = 0;
-
-       if (align == 0)
-               align = 4;
-
-       /*types with references can't have alignment smaller than sizeof(void*) */
-       if (align < SIZEOF_VOID_P)
-               return FALSE;
-
-       if (size > 5 * SIZEOF_VOID_P)
-               return FALSE;
-
-       create_write_barrier_bitmap (cfg, klass, &need_wb, 0);
-
-       destreg = iargs [0]->dreg;
-       srcreg = iargs [1]->dreg;
-       offset = 0;
-
-       dest_ptr_reg = alloc_preg (cfg);
-       tmp_reg = alloc_preg (cfg);
-
-       /*tmp = dreg*/
-       EMIT_NEW_UNALU (cfg, iargs [0], OP_MOVE, dest_ptr_reg, destreg);
-
-       while (size >= SIZEOF_VOID_P) {
-               MonoInst *load_inst;
-               MONO_INST_NEW (cfg, load_inst, OP_LOAD_MEMBASE);
-               load_inst->dreg = tmp_reg;
-               load_inst->inst_basereg = srcreg;
-               load_inst->inst_offset = offset;
-               MONO_ADD_INS (cfg->cbb, load_inst);
-
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, dest_ptr_reg, 0, tmp_reg);
-
-               if (need_wb & 0x1)
-                       mini_emit_write_barrier (cfg, iargs [0], load_inst);
-
-               offset += SIZEOF_VOID_P;
-               size -= SIZEOF_VOID_P;
-               need_wb >>= 1;
-
-               /*tmp += sizeof (void*)*/
-               if (size >= SIZEOF_VOID_P) {
-                       NEW_BIALU_IMM (cfg, iargs [0], OP_PADD_IMM, dest_ptr_reg, dest_ptr_reg, SIZEOF_VOID_P);
-                       MONO_ADD_INS (cfg->cbb, iargs [0]);
-               }
-       }
-
-       /* Those cannot be references since size < sizeof (void*) */
-       while (size >= 4) {
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, tmp_reg, srcreg, offset);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, tmp_reg);
-               offset += 4;
-               size -= 4;
-       }
-
-       while (size >= 2) {
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, tmp_reg, srcreg, offset);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, tmp_reg);
-               offset += 2;
-               size -= 2;
-       }
-
-       while (size >= 1) {
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, tmp_reg, srcreg, offset);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, tmp_reg);
-               offset += 1;
-               size -= 1;
-       }
-
-       return TRUE;
-}
-
-/*
- * Emit code to copy a valuetype of type @klass whose address is stored in
- * @src->dreg to memory whose address is stored at @dest->dreg.
- */
-void
-mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native)
-{
-       MonoInst *iargs [4];
-       int n;
-       guint32 align = 0;
-       MonoMethod *memcpy_method;
-       MonoInst *size_ins = NULL;
-       MonoInst *memcpy_ins = NULL;
-
-       g_assert (klass);
-       if (cfg->gshared)
-               klass = mono_class_from_mono_type (mini_get_underlying_type (&klass->byval_arg));
-
-       /*
-        * This check breaks with spilled vars... need to handle it during verification anyway.
-        * g_assert (klass && klass == src->klass && klass == dest->klass);
-        */
-
-       if (mini_is_gsharedvt_klass (klass)) {
-               g_assert (!native);
-               size_ins = mini_emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_VALUE_SIZE);
-               memcpy_ins = mini_emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_MEMCPY);
-       }
-
-       if (native)
-               n = mono_class_native_size (klass, &align);
-       else
-               n = mono_class_value_size (klass, &align);
-
-       if (!align)
-               align = SIZEOF_VOID_P;
-       /* if native is true there should be no references in the struct */
-       if (cfg->gen_write_barriers && (klass->has_references || size_ins) && !native) {
-               /* Avoid barriers when storing to the stack */
-               if (!((dest->opcode == OP_ADD_IMM && dest->sreg1 == cfg->frame_reg) ||
-                         (dest->opcode == OP_LDADDR))) {
-                       int context_used;
-
-                       iargs [0] = dest;
-                       iargs [1] = src;
-
-                       context_used = mini_class_check_context_used (cfg, klass);
-
-                       /* It's ok to intrinsify under gsharing since shared code types are layout stable. */
-                       if (!size_ins && (cfg->opt & MONO_OPT_INTRINS) && mini_emit_wb_aware_memcpy (cfg, klass, iargs, n, align)) {
-                               return;
-                       } else if (size_ins || align < SIZEOF_VOID_P) {
-                               if (context_used) {
-                                       iargs [2] = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
-                               }  else {
-                                       iargs [2] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_CLASS, klass);
-                                       if (!cfg->compile_aot)
-                                               mono_class_compute_gc_descriptor (klass);
-                               }
-                               if (size_ins)
-                                       mono_emit_jit_icall (cfg, mono_gsharedvt_value_copy, iargs);
-                               else
-                                       mono_emit_jit_icall (cfg, mono_value_copy, iargs);
-                       } else {
-                               /* We don't unroll more than 5 stores to avoid code bloat. */
-                               /*This is harmless and simplify mono_gc_get_range_copy_func */
-                               n += (SIZEOF_VOID_P - 1);
-                               n &= ~(SIZEOF_VOID_P - 1);
-
-                               EMIT_NEW_ICONST (cfg, iargs [2], n);
-                               mono_emit_jit_icall (cfg, mono_gc_get_range_copy_func (), iargs);
-                       }
-               }
-       }
-
-       if (!size_ins && (cfg->opt & MONO_OPT_INTRINS) && n <= sizeof (gpointer) * 8) {
-               /* FIXME: Optimize the case when src/dest is OP_LDADDR */
-               mini_emit_memcpy (cfg, dest->dreg, 0, src->dreg, 0, n, align);
-       } else {
-               iargs [0] = dest;
-               iargs [1] = src;
-               if (size_ins)
-                       iargs [2] = size_ins;
-               else
-                       EMIT_NEW_ICONST (cfg, iargs [2], n);
-               
-               memcpy_method = mini_get_memcpy_method ();
-               if (memcpy_ins)
-                       mini_emit_calli (cfg, mono_method_signature (memcpy_method), iargs, memcpy_ins, NULL, NULL);
-               else
-                       mono_emit_method_call (cfg, memcpy_method, iargs, NULL);
-       }
-}
-
 MonoMethod*
 mini_get_memset_method (void)
 {
@@ -4763,54 +4571,6 @@ mini_emit_ldelema_ins (MonoCompile *cfg, MonoMethod *cmethod, MonoInst **sp, uns
        return addr;
 }
 
-static MonoBreakPolicy
-always_insert_breakpoint (MonoMethod *method)
-{
-       return MONO_BREAK_POLICY_ALWAYS;
-}
-
-static MonoBreakPolicyFunc break_policy_func = always_insert_breakpoint;
-
-/**
- * mono_set_break_policy:
- * \param policy_callback the new callback function
- *
- * Allow embedders to decide wherther to actually obey breakpoint instructions
- * (both break IL instructions and \c Debugger.Break method calls), for example
- * to not allow an app to be aborted by a perfectly valid IL opcode when executing
- * untrusted or semi-trusted code.
- *
- * \p policy_callback will be called every time a break point instruction needs to
- * be inserted with the method argument being the method that calls \c Debugger.Break
- * or has the IL \c break instruction. The callback should return \c MONO_BREAK_POLICY_NEVER
- * if it wants the breakpoint to not be effective in the given method.
- * \c MONO_BREAK_POLICY_ALWAYS is the default.
- */
-void
-mono_set_break_policy (MonoBreakPolicyFunc policy_callback)
-{
-       if (policy_callback)
-               break_policy_func = policy_callback;
-       else
-               break_policy_func = always_insert_breakpoint;
-}
-
-static gboolean
-should_insert_brekpoint (MonoMethod *method) {
-       switch (break_policy_func (method)) {
-       case MONO_BREAK_POLICY_ALWAYS:
-               return TRUE;
-       case MONO_BREAK_POLICY_NEVER:
-               return FALSE;
-       case MONO_BREAK_POLICY_ON_DBG:
-               g_warning ("mdb no longer supported");
-               return FALSE;
-       default:
-               g_warning ("Incorrect value returned from break policy callback");
-               return FALSE;
-       }
-}
-
 /* optimize the simple GetGenericValueImpl/SetGenericValueImpl generic icalls */
 static MonoInst*
 emit_array_generic_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **args, int is_set)
@@ -5114,6 +4874,31 @@ mini_emit_inst_for_sharable_method (MonoCompile *cfg, MonoMethod *cmethod, MonoM
        return NULL;
 }
 
+
+static gboolean
+mono_type_is_native_blittable (MonoType *t)
+{
+       if (MONO_TYPE_IS_REFERENCE (t))
+               return FALSE;
+
+       if (MONO_TYPE_IS_PRIMITIVE_SCALAR (t))
+               return TRUE;
+
+       MonoClass *klass = mono_class_from_mono_type (t);
+
+       //MonoClass::blitable depends on mono_class_setup_fields being done.
+       mono_class_setup_fields (klass);
+       if (!klass->blittable)
+               return FALSE;
+
+       // If the native marshal size is different we can't convert PtrToStructure to a type load
+       if (mono_class_native_size (klass, NULL) != mono_class_value_size (klass, NULL))
+               return FALSE;
+
+       return TRUE;
+}
+
+
 static MonoInst*
 mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
 {
@@ -5930,7 +5715,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                           (strcmp (cmethod->klass->name_space, "System.Diagnostics") == 0) &&
                           (strcmp (cmethod->klass->name, "Debugger") == 0)) {
                if (!strcmp (cmethod->name, "Break") && fsig->param_count == 0) {
-                       if (should_insert_brekpoint (cfg->method)) {
+                       if (mini_should_insert_breakpoint (cfg->method)) {
                                ins = mono_emit_jit_icall (cfg, mono_debugger_agent_user_break, NULL);
                        } else {
                                MONO_INST_NEW (cfg, ins, OP_NOP);
@@ -6029,6 +5814,20 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                        MONO_ADD_INS (cfg->cbb, ins);
                        return ins;
                }
+       } else if (cmethod->klass->image == mono_defaults.corlib &&
+                       (strcmp (cmethod->klass->name_space, "System.Runtime.InteropServices") == 0) &&
+                       (strcmp (cmethod->klass->name, "Marshal") == 0)) {
+               //Convert Marshal.PtrToStructure<T> of blittable T to direct loads
+               if (strcmp (cmethod->name, "PtrToStructure") == 0 &&
+                               cmethod->is_inflated &&
+                               fsig->param_count == 1 &&
+                               !mini_method_check_context_used (cfg, cmethod)) {
+
+                       MonoGenericContext *method_context = mono_method_get_context (cmethod);
+                       MonoType *arg0 = method_context->method_inst->type_argv [0];
+                       if (mono_type_is_native_blittable (arg0))
+                               return mini_emit_memory_load (cfg, arg0, args [0], 0, 0);
+               }
        }
 
 #ifdef MONO_ARCH_SIMD_INTRINSICS
@@ -7958,7 +7757,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        MONO_ADD_INS (cfg->cbb, ins);
                        break;
                case CEE_BREAK:
-                       if (should_insert_brekpoint (cfg->method)) {
+                       if (mini_should_insert_breakpoint (cfg->method)) {
                                ins = mono_emit_jit_icall (cfg, mono_debugger_agent_user_break, NULL);
                        } else {
                                MONO_INST_NEW (cfg, ins, OP_NOP);
@@ -9853,23 +9652,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        klass = mini_get_class (method, token, generic_context);
                        CHECK_TYPELOAD (klass);
                        sp -= 2;
-                       if (generic_class_is_reference_type (cfg, klass)) {
-                               MonoInst *store, *load;
-                               int dreg = alloc_ireg_ref (cfg);
-
-                               NEW_LOAD_MEMBASE (cfg, load, OP_LOAD_MEMBASE, dreg, sp [1]->dreg, 0);
-                               load->flags |= ins_flag;
-                               MONO_ADD_INS (cfg->cbb, load);
-
-                               NEW_STORE_MEMBASE (cfg, store, OP_STORE_MEMBASE_REG, sp [0]->dreg, 0, dreg);
-                               store->flags |= ins_flag;
-                               MONO_ADD_INS (cfg->cbb, store);
-
-                               if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER)
-                                       mini_emit_write_barrier (cfg, sp [0], sp [1]);
-                       } else {
-                               mini_emit_stobj (cfg, sp [0], sp [1], klass, FALSE);
-                       }
+                       mini_emit_memory_copy (cfg, sp [0], sp [1], klass, FALSE, ins_flag);
                        ins_flag = 0;
                        ip += 5;
                        break;
@@ -9918,14 +9701,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        }
 
                        /* Optimize the ldobj+stobj combination */
-                       /* The reference case ends up being a load+store anyway */
-                       /* Skip this if the operation is volatile. */
-                       if (((ip [5] == CEE_STOBJ) && ip_in_bb (cfg, cfg->cbb, ip + 5) && read32 (ip + 6) == token) && !generic_class_is_reference_type (cfg, klass) && !(ins_flag & MONO_INST_VOLATILE)) {
+                       if (((ip [5] == CEE_STOBJ) && ip_in_bb (cfg, cfg->cbb, ip + 5) && read32 (ip + 6) == token)) {
                                CHECK_STACK (1);
 
                                sp --;
 
-                               mini_emit_stobj (cfg, sp [0], sp [1], klass, FALSE);
+                               mini_emit_memory_copy (cfg, sp [0], sp [1], klass, FALSE, ins_flag);
 
                                ip += 5 + 5;
                                ins_flag = 0;
@@ -10596,7 +10377,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                                dreg = alloc_ireg_mp (cfg);
                                                EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, sp [0]->dreg, offset_ins->dreg);
                                                wbarrier_ptr_ins = ins;
-                                               /* The decomposition will call mini_emit_stobj () which will emit a wbarrier if needed */
+                                               /* The decomposition will call mini_emit_memory_copy () which will emit a wbarrier if needed */
                                                EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, field->type, dreg, 0, sp [1]->dreg);
                                        } else {
                                                EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, field->type, sp [0]->dreg, foffset, sp [1]->dreg);
@@ -11857,7 +11638,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        temp = mono_compile_create_var (cfg, &klass->byval_arg, OP_LOCAL);
                                        temp->backend.is_pinvoke = 1;
                                        EMIT_NEW_TEMPLOADA (cfg, dest, temp->inst_c0);
-                                       mini_emit_stobj (cfg, dest, src, klass, TRUE);
+                                       mini_emit_memory_copy (cfg, dest, src, klass, TRUE, 0);
 
                                        EMIT_NEW_TEMPLOAD (cfg, dest, temp->inst_c0);
                                        dest->type = STACK_VTYPE;
@@ -11888,7 +11669,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                } else {
                                        EMIT_NEW_RETLOADA (cfg, ins);
                                }
-                               mini_emit_stobj (cfg, ins, sp [0], klass, TRUE);
+                               mini_emit_memory_copy (cfg, ins, sp [0], klass, TRUE, 0);
                                
                                if (sp != stack_start)
                                        UNVERIFIED;
@@ -14406,11 +14187,4 @@ NOTES
   the values on the stack before emitting the last instruction of the bb.
 */
 
-#else /* !DISABLE_JIT */
-
-void
-mono_set_break_policy (MonoBreakPolicyFunc policy_callback)
-{
-}
-
 #endif /* !DISABLE_JIT */
index b1e795f354fab3e1edba90f85830a0bdd0316e8e..10a9daa20ef24f7fd45f015a82d119d3c3f80a17 100644 (file)
@@ -323,7 +323,7 @@ mono_arm_patchable_bl (guint8 *code, int cond)
        return code;
 }
 
-#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID) && !defined(__native_client__)
+#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID) && !defined(__native_client__) && !defined(MONO_CROSS_COMPILE)
 #define HAVE_AEABI_READ_TP 1
 #endif
 
index b6b1d813399f21e758c9ff90188d8b3f9ddf139e..7878372c10cd57257517b52809e147cb42c654bf 100644 (file)
@@ -1070,6 +1070,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
        mgreg_t *new_reg_locations [MONO_MAX_IREGS];
        gboolean get_reg_locations = unwind_options & MONO_UNWIND_REG_LOCATIONS;
        gboolean async = mono_thread_info_is_async_context ();
+       Unwinder unwinder;
 
        if (mono_llvm_only) {
                GSList *l, *ips;
@@ -1114,9 +1115,11 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain
        memcpy (&ctx, start_ctx, sizeof (MonoContext));
        memset (reg_locations, 0, sizeof (reg_locations));
 
+       unwinder_init (&unwinder);
+
        while (MONO_CONTEXT_GET_SP (&ctx) < jit_tls->end_of_stack) {
                frame.lmf = lmf;
-               res = mono_find_jit_info_ext (domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame);
+               res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame);
                if (!res)
                        return;
 
@@ -1633,7 +1636,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi
 
                gpointer ip;
                if (in_interp)
-                       ip = (guint16*)ji->code_start + frame.native_offset;
+                       ip = (guint8*)ji->code_start + frame.native_offset;
                else
                        ip = MONO_CONTEXT_GET_IP (ctx);
 
@@ -2009,7 +2012,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                }
 
                if (in_interp)
-                       ip = (guint16*)ji->code_start + frame.native_offset;
+                       ip = (guint8*)ji->code_start + frame.native_offset;
                else
                        ip = MONO_CONTEXT_GET_IP (ctx);
 
@@ -2131,7 +2134,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu
                                                 * like the call which transitioned to JITted code has succeeded, but the
                                                 * return value register etc. is not set, so we have to be careful.
                                                 */
-                                               mono_interp_set_resume_state (mono_ex, &frame, ei->handler_start);
+                                               mono_interp_set_resume_state (jit_tls, mono_ex, frame.interp_frame, ei->handler_start);
                                                /* Undo the IP adjustment done by mono_arch_unwind_frame () */
 #if defined(TARGET_AMD64)
                                                ctx->gregs [AMD64_RIP] ++;
@@ -2260,6 +2263,9 @@ mono_debugger_run_finally (MonoContext *start_ctx)
  * mono_handle_exception:
  * \param ctx saved processor state
  * \param obj the exception object
+ *
+ *   Handle the exception OBJ starting from the state CTX. Modify CTX to point to the handler clause if the exception is caught, and
+ * return TRUE.
  */
 gboolean
 mono_handle_exception (MonoContext *ctx, MonoObject *obj)
@@ -3407,31 +3413,3 @@ mono_debug_personality (void)
        g_assert_not_reached ();
 }
 #endif
-
-#ifndef ENABLE_INTERPRETER
-/* Stubs of interpreter functions */
-void
-mono_interp_set_resume_state (MonoException *ex, StackFrameInfo *frame, gpointer handler_ip)
-{
-       g_assert_not_reached ();
-}
-
-void
-mono_interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip)
-{
-       g_assert_not_reached ();
-}
-
-void
-mono_interp_frame_iter_init (MonoInterpStackIter *iter, gpointer interp_exit_data)
-{
-       g_assert_not_reached ();
-}
-
-gboolean
-mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame)
-{
-       g_assert_not_reached ();
-       return FALSE;
-}
-#endif
index 5ef3b350bf065f713a12e9992a124a9d0c0b5b8f..9943d883966e1b74b6be10e1b515c3fbe945e0ba 100644 (file)
@@ -390,7 +390,17 @@ info_has_identity (MonoRgctxInfoType info_type)
 /*
  * LOCKING: loader lock
  */
+#if defined(PLATFORM_ANDROID) && defined(TARGET_ARM)
+/* work around for HW bug on Nexus9 when running on armv7 */
+#ifdef __clang__
+static __attribute__ ((optnone)) void
+#else
+/* gcc */
+static __attribute__ ((optimize("O0"))) void
+#endif
+#else
 static void
+#endif
 rgctx_template_set_slot (MonoImage *image, MonoRuntimeGenericContextTemplate *template_, int type_argc,
        int slot, gpointer data, MonoRgctxInfoType info_type)
 {
index b5d79629a54132d93550187554ac8b08557f4815..7d427a915ee53263ccff6c19689782a15c5c48d7 100644 (file)
@@ -583,23 +583,23 @@ break_count (void)
 G_GNUC_UNUSED gboolean
 mono_debug_count (void)
 {
-       static int count = 0;
+       static int count = 0, int_val = 0;
        static gboolean inited;
-       static char *value;
 
        count ++;
 
        if (!inited) {
-               value = g_getenv ("COUNT");
+               char *value = g_getenv ("COUNT");
+               if (value) {
+                       int_val = atoi (value);
+                       g_free (value);
+               }
                inited = TRUE;
        }
 
-       if (!value)
+       if (!int_val)
                return TRUE;
 
-       int int_val = atoi (value);
-       g_free (value);
-
        if (count == int_val)
                break_count ();
 
@@ -4547,6 +4547,56 @@ mono_personality (void)
        g_assert_not_reached ();
 }
 
+
+static MonoBreakPolicy
+always_insert_breakpoint (MonoMethod *method)
+{
+       return MONO_BREAK_POLICY_ALWAYS;
+}
+
+static MonoBreakPolicyFunc break_policy_func = always_insert_breakpoint;
+
+/**
+ * mono_set_break_policy:
+ * \param policy_callback the new callback function
+ *
+ * Allow embedders to decide whether to actually obey breakpoint instructions
+ * (both break IL instructions and \c Debugger.Break method calls), for example
+ * to not allow an app to be aborted by a perfectly valid IL opcode when executing
+ * untrusted or semi-trusted code.
+ *
+ * \p policy_callback will be called every time a break point instruction needs to
+ * be inserted with the method argument being the method that calls \c Debugger.Break
+ * or has the IL \c break instruction. The callback should return \c MONO_BREAK_POLICY_NEVER
+ * if it wants the breakpoint to not be effective in the given method.
+ * \c MONO_BREAK_POLICY_ALWAYS is the default.
+ */
+void
+mono_set_break_policy (MonoBreakPolicyFunc policy_callback)
+{
+       if (policy_callback)
+               break_policy_func = policy_callback;
+       else
+               break_policy_func = always_insert_breakpoint;
+}
+
+gboolean
+mini_should_insert_breakpoint (MonoMethod *method)
+{
+       switch (break_policy_func (method)) {
+       case MONO_BREAK_POLICY_ALWAYS:
+               return TRUE;
+       case MONO_BREAK_POLICY_NEVER:
+               return FALSE;
+       case MONO_BREAK_POLICY_ON_DBG:
+               g_warning ("mdb no longer supported");
+               return FALSE;
+       default:
+               g_warning ("Incorrect value returned from break policy callback");
+               return FALSE;
+       }
+}
+
 // Custom handlers currently only implemented by Windows.
 #ifndef HOST_WIN32
 gboolean
index 6eb32809205aa44af20d634bfaf7607a344fa0e3..ed10d8f937934da36d172b9a60b1b2847947453d 100644 (file)
@@ -1217,11 +1217,12 @@ typedef struct {
         */
        gpointer abort_exc_stack_threshold;
 
-
        /*
         * List of methods being JIT'd in the current thread.
         */
        int active_jit_methods;
+
+       gpointer interp_context;
 } MonoJitTlsData;
 
 /*
@@ -2481,6 +2482,7 @@ MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, int il_offset, MonoJitI
 MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this_ins);
 void      mono_create_helper_signatures (void);
 MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
+gboolean  mini_should_insert_breakpoint (MonoMethod *method);
 
 gboolean  mini_class_is_system_array (MonoClass *klass);
 MonoMethodSignature *mono_get_element_address_signature (int arity);
@@ -2652,11 +2654,11 @@ MonoInst*         mini_emit_get_gsharedvt_info_klass (MonoCompile *cfg, MonoClas
 MonoInst*         mini_emit_calli (MonoCompile *cfg, MonoMethodSignature *sig, MonoInst **args, MonoInst *addr, MonoInst *imt_arg, MonoInst *rgctx_arg);
 MonoInst*         mini_emit_memory_barrier (MonoCompile *cfg, int kind);
 void              mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value);
-gboolean          mini_emit_wb_aware_memcpy (MonoCompile *cfg, MonoClass *klass, MonoInst *iargs[4], int size, int align);
 MonoInst*         mini_emit_memory_load (MonoCompile *cfg, MonoType *type, MonoInst *src, int offset, int ins_flag);
 void              mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoInst *value, int ins_flag);
 void              mini_emit_memory_copy_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoInst *size, int ins_flag);
 void              mini_emit_memory_init_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *value, MonoInst *size, int ins_flag);
+void              mini_emit_memory_copy (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native, int ins_flag);
 
 MonoMethod*       mini_get_memcpy_method (void);
 MonoMethod*       mini_get_memset_method (void);
index 51c0cac6de625a0579fd85b262059f98a9e3f1f2..723238f4e94b55edada227fd251ffe40344a769b 100644 (file)
@@ -847,26 +847,31 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        guint8 *start = NULL, *code, *label_gexits [gregs_num], *label_fexits [fregs_num], *label_leave_tramp [3], *label_is_float_ret;
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
-       int buf_len, i, framesize = 0, off_methodargs, off_targetaddr;
+       int buf_len, i, framesize, off_methodargs, off_targetaddr;
        const int fp_reg = ARMREG_R7;
 
        buf_len = 512 + 1024;
        start = code = (guint8 *) mono_global_codeman_reserve (buf_len);
 
-       off_methodargs = framesize;
+       framesize = 5 * sizeof (mgreg_t); /* lr, r4, r8, r6 and plus one */
+
+       off_methodargs = -framesize;
        framesize += sizeof (mgreg_t);
 
-       off_targetaddr = framesize;
+       off_targetaddr = -framesize;
        framesize += sizeof (mgreg_t);
 
-       framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
+       framesize = ALIGN_TO (framesize + 4 * sizeof (mgreg_t), MONO_ARCH_FRAME_ALIGNMENT);
 
        /* allocate space on stack for argument passing */
        const int stack_space = ALIGN_TO (((gregs_num - ARMREG_R3) * sizeof (mgreg_t)), MONO_ARCH_FRAME_ALIGNMENT);
 
-       /* use r4, r5 and r6 as scratch registers */
-       ARM_PUSH (code, (1 << fp_reg) | (1 << ARMREG_LR) | (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6));
+       /* iOS ABI */
+       ARM_PUSH (code, (1 << fp_reg) | (1 << ARMREG_LR));
        ARM_MOV_REG_REG (code, fp_reg, ARMREG_SP);
+
+       /* use r4, r8 and r6 as scratch registers */
+       ARM_PUSH (code, (1 << ARMREG_R4) | (1 << ARMREG_R8) | (1 << ARMREG_R6));
        ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, stack_space + framesize);
 
        /* save InterpMethodArguments* onto stack */
@@ -878,32 +883,32 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        /* load pointer to InterpMethodArguments* into r4 */
        ARM_MOV_REG_REG (code, ARMREG_R4, ARMREG_R1);
 
-       /* move flen into r5 */
-       ARM_LDR_IMM (code, ARMREG_R5, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, flen));
+       /* move flen into r8 */
+       ARM_LDR_IMM (code, ARMREG_R8, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, flen));
        /* load pointer to fargs into r6 */
        ARM_LDR_IMM (code, ARMREG_R6, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, fargs));
 
        for (i = 0; i < fregs_num; ++i) {
-               ARM_CMP_REG_IMM (code, ARMREG_R5, 0, 0);
+               ARM_CMP_REG_IMM (code, ARMREG_R8, 0, 0);
                label_fexits [i] = code;
                ARM_B_COND (code, ARMCOND_EQ, 0);
 
                g_assert (i <= ARM_VFP_D7); /* otherwise, need to pass args on stack */
                ARM_FLDD (code, i, ARMREG_R6, i * sizeof (double));
-               ARM_SUB_REG_IMM8 (code, ARMREG_R5, ARMREG_R5, 1);
+               ARM_SUB_REG_IMM8 (code, ARMREG_R8, ARMREG_R8, 1);
        }
 
        for (i = 0; i < fregs_num; i++)
                arm_patch (label_fexits [i], code);
 
-       /* move ilen into r5 */
-       ARM_LDR_IMM (code, ARMREG_R5, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen));
+       /* move ilen into r8 */
+       ARM_LDR_IMM (code, ARMREG_R8, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen));
        /* load pointer to iargs into r6 */
        ARM_LDR_IMM (code, ARMREG_R6, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, iargs));
 
        int stack_offset = 0;
        for (i = 0; i < gregs_num; i++) {
-               ARM_CMP_REG_IMM (code, ARMREG_R5, 0, 0);
+               ARM_CMP_REG_IMM (code, ARMREG_R8, 0, 0);
                label_gexits [i] = code;
                ARM_B_COND (code, ARMCOND_EQ, 0);
 
@@ -914,7 +919,7 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
                        ARM_STR_IMM (code, ARMREG_R4, ARMREG_SP, stack_offset);
                        stack_offset += sizeof (mgreg_t);
                }
-               ARM_SUB_REG_IMM8 (code, ARMREG_R5, ARMREG_R5, 1);
+               ARM_SUB_REG_IMM8 (code, ARMREG_R8, ARMREG_R8, 1);
        }
 
        for (i = 0; i < gregs_num; i++)
@@ -930,24 +935,24 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        ARM_LDR_IMM (code, ARMREG_R4, fp_reg, off_methodargs);
 
        /* load is_float_ret */
-       ARM_LDR_IMM (code, ARMREG_R5, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret));
+       ARM_LDR_IMM (code, ARMREG_R8, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret));
 
        /* check if a float return value is expected */
-       ARM_CMP_REG_IMM (code, ARMREG_R5, 0, 0);
+       ARM_CMP_REG_IMM (code, ARMREG_R8, 0, 0);
        label_is_float_ret = code;
        ARM_B_COND (code, ARMCOND_NE, 0);
 
        /* greg return */
        /* load retval */
-       ARM_LDR_IMM (code, ARMREG_R5, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
+       ARM_LDR_IMM (code, ARMREG_R8, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
 
-       ARM_CMP_REG_IMM (code, ARMREG_R5, 0, 0);
+       ARM_CMP_REG_IMM (code, ARMREG_R8, 0, 0);
        label_leave_tramp [0] = code;
        ARM_B_COND (code, ARMCOND_EQ, 0);
 
        /* store greg result, always write back 64bit */
-       ARM_STR_IMM (code, ARMREG_R0, ARMREG_R5, 0);
-       ARM_STR_IMM (code, ARMREG_R1, ARMREG_R5, 4);
+       ARM_STR_IMM (code, ARMREG_R0, ARMREG_R8, 0);
+       ARM_STR_IMM (code, ARMREG_R1, ARMREG_R8, 4);
 
        label_leave_tramp [1] = code;
        ARM_B_COND (code, ARMCOND_AL, 0);
@@ -955,20 +960,22 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        /* freg return */
        arm_patch (label_is_float_ret, code);
        /* load retval */
-       ARM_LDR_IMM (code, ARMREG_R5, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
+       ARM_LDR_IMM (code, ARMREG_R8, ARMREG_R4, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
 
-       ARM_CMP_REG_IMM (code, ARMREG_R5, 0, 0);
+       ARM_CMP_REG_IMM (code, ARMREG_R8, 0, 0);
        label_leave_tramp [2] = code;
        ARM_B_COND (code, ARMCOND_EQ, 0);
 
        /* store freg result */
-       ARM_FSTD (code, ARM_VFP_F0, ARMREG_R5, 0);
+       ARM_FSTD (code, ARM_VFP_F0, ARMREG_R8, 0);
 
        for (i = 0; i < 3; i++)
                arm_patch (label_leave_tramp [i], code);
 
+       ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, stack_space + framesize);
+       ARM_POP (code, (1 << ARMREG_R4) | (1 << ARMREG_R8) | (1 << ARMREG_R6));
        ARM_MOV_REG_REG (code, ARMREG_SP, fp_reg);
-       ARM_POP (code, (1 << fp_reg) | (1 << ARMREG_PC) | (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6));
+       ARM_POP (code, (1 << fp_reg) | (1 << ARMREG_PC));
 
        g_assert (code - start < buf_len);
 
diff --git a/mono/mini/unaligned.cs b/mono/mini/unaligned.cs
new file mode 100644 (file)
index 0000000..4ff899f
--- /dev/null
@@ -0,0 +1,308 @@
+using System;
+using System.Runtime.CompilerServices;
+using Mono;
+
+/*
+ * Regression tests for the mono JIT.
+ *
+ * Each test needs to be of the form:
+ *
+ * static int test_<result>_<name> ();
+ *
+ * where <result> is an integer (the value that needs to be returned by
+ * the method to make it pass.
+ * <name> is a user-displayed name used to identify the test.
+ *
+ * The tests can be driven in two ways:
+ * *) running the program directly: Main() uses reflection to find and invoke
+ *     the test methods (this is useful mostly to check that the tests are correct)
+ * *) with the --regression switch of the jit (this is the preferred way since
+ *     all the tests will be run with optimizations on and off)
+ *
+ * The reflection logic could be moved to a .dll since we need at least another
+ * regression test file written in IL code to have better control on how
+ * the IL code looks.
+ */
+
+#if __MOBILE__
+namespace UnalignedTests
+{
+#endif
+
+
+class Tests {
+
+#if !__MOBILE__
+       public static int Main (string[] args) {
+               return TestDriver.RunTests (typeof (Tests), args);
+       }
+#endif
+
+
+       public static unsafe int test_0_ldobj_r4 ()
+       {
+               byte *ptr = stackalloc byte [32];
+               float f = (float)123.44f;
+               *(float*)ptr = (float)f;
+
+               int expected = *(int*)ptr;
+
+               Intrinsics.UnalignedStobj<int> (ptr + 1, expected);
+               /* we can loose some precision due to r4<->r8 conversions */
+               if (Math.Abs (Intrinsics.UnalignedLdobj<float> (ptr + 1) - f) > 0.01f)
+                       return 1;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj_r8 ()
+       {
+               byte *ptr = stackalloc byte [32];
+               double f = 34423.44f;
+               *(double*)ptr = (double)f;
+
+               long expected = *(long*)ptr;
+
+               Intrinsics.UnalignedStobj<long> (ptr + 3, expected);
+               if (Intrinsics.UnalignedLdobj<double> (ptr + 3) != f)
+                       return 1;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj ()
+       {
+               byte *ptr = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 0) != 0x0100)
+                       return 1;
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 1) != 0x0201)
+                       return 2;
+
+               if (Intrinsics.UnalignedLdobj<short> (ptr + 2) != 0x0302)
+                       return 3;
+
+               if (Intrinsics.UnalignedLdobj<int> (ptr + 1) != 0x04030201)
+                       return 4;
+
+               if (Intrinsics.UnalignedLdobj<int> (ptr + 2) != 0x05040302)
+                       return 5;
+
+               if (Intrinsics.UnalignedLdobj<long> (ptr + 1) != 0x0807060504030201)
+                       return 6;
+
+               if (Intrinsics.UnalignedLdobj<long> (ptr + 6) != 0xD0C0B0A09080706)
+                       return 7;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldind ()
+       {
+               byte *ptr = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 0) != 0x0100)
+                       return 1;
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 1) != 0x0201)
+                       return 2;
+
+               if (Intrinsics.UnalignedLdInd2 (ptr + 2) != 0x0302)
+                       return 3;
+
+               if (Intrinsics.UnalignedLdInd4 (ptr + 1) != 0x04030201)
+                       return 4;
+
+               if (Intrinsics.UnalignedLdInd4 (ptr + 2) != 0x05040302)
+                       return 5;
+
+               if (Intrinsics.UnalignedLdInd8 (ptr + 1) != 0x0807060504030201)
+                       return 6;
+
+               if (Intrinsics.UnalignedLdInd8 (ptr + 6) != 0xD0C0B0A09080706)
+                       return 7;
+
+               return 0;
+       }
+       public static unsafe int test_0_cpobj ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 0, src + 0);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 1, src + 0);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 0, src + 1);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpobj<short> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpobj<int> (dest + 3, src);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 3] != src [i])
+                               return 4;
+               }
+
+               Intrinsics.UnalignedCpobj<int> (dest + 1, src + 2);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 1] != src [i + 2])
+                               return 5;
+               }
+
+               Intrinsics.UnalignedCpobj<long> (dest + 1, src + 2);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 1] != src [i + 2])
+                               return 6;
+               }
+
+               Intrinsics.UnalignedCpobj<long> (dest + 7, src + 2);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 7] != src [i + 2])
+                               return 7;
+               }
+
+               return 0;
+       }
+
+       public static unsafe int test_0_stobj ()
+       {
+               byte *ptr = stackalloc byte [20];
+
+               Intrinsics.UnalignedStobj <short> (ptr + 0, 0x6688);
+               if (ptr [0] != 0x88 || ptr [1] != 0x66)
+                       return 1;
+
+               Intrinsics.UnalignedStobj <short> (ptr + 1, 0x6589);
+               if (ptr [1] != 0x89 || ptr [2] != 0x65)
+                       return 2;
+
+               Intrinsics.UnalignedStobj <int> (ptr + 1, 0x60708090);
+               if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60)
+                       return 3;
+
+               Intrinsics.UnalignedStobj <long> (ptr + 1, 0x405060708090);
+               if (ptr [1] != 0x90 || ptr [2] != 0x80 || ptr [3] != 0x70 || ptr [4] != 0x60 || ptr [5] != 0x50 || ptr [6] != 0x40)
+                       return 4;
+
+               return 0;
+       }
+
+       public static unsafe int test_0_ldobj_stobj ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 0);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 0);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 0, src + 1);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedLdobjStObjPair<short> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedLdobjStObjPair<int> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 4;
+
+               Intrinsics.UnalignedLdobjStObjPair<long> (dest + 1, src + 1);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 5;
+
+
+               return 0;
+       }
+
+
+       public static unsafe int test_0_cpblk ()
+       {
+               byte *dest = stackalloc byte [20];
+               byte *src = stackalloc byte [20];
+               for (int i = 0; i < 20; ++i)
+                       src [i] = (byte)i;
+
+
+               Intrinsics.UnalignedCpblk (dest + 0, src + 0, 2);
+               if (dest [0] != src [0] || dest [1] != src [1])
+                       return 1;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 0, 2);
+               if (dest [1] != src [0] || dest [2] != src [1])
+                       return 2;
+
+               Intrinsics.UnalignedCpblk (dest + 0, src + 1, 2);
+               if (dest [0] != src [1] || dest [1] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 2);
+               if (dest [1] != src [1] || dest [2] != src [2])
+                       return 3;
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 4);
+               for (int i = 0; i < 4; ++i) {
+                       if (dest [i + 1] != src [i + 1])
+                               return 4;
+               }
+
+               Intrinsics.UnalignedCpblk (dest + 1, src + 1, 8);
+               for (int i = 0; i < 8; ++i) {
+                       if (dest [i + 1] != src [i + 1])
+                               return 5;
+               }
+
+               return 0;
+       }
+
+
+       public static unsafe int test_0_initblk ()
+       {
+               byte *ptr = stackalloc byte [20];
+
+               for (int i = 0; i < 20; ++i)
+                       ptr [i] = (byte)i;
+
+               Intrinsics.UnalignedInit (ptr, 30, 2);
+               if (ptr [0] != 30 || ptr [1] != 30)
+                       return 1;
+
+               Intrinsics.UnalignedInit (ptr + 1, 31, 2);
+               if (ptr[0] != 30 || ptr [1] != 31 || ptr [2] != 31)
+                       return 2;
+
+               return 0;
+       }
+}
+
+#if __MOBILE__
+}
+#endif
+
+
+
index f4182ec0e34202ea1a22c865aedd346985ae00e8..15af95e3e2a6c0ab31d9fc27487e642101626771 100755 (executable)
@@ -867,6 +867,7 @@ PROFILE_DISABLED_TESTS += \
        appdomain1.exe  \
        appdomain2.exe  \
        appdomain-exit.exe      \
+       appdomain-unload-asmload.exe \
        appdomain-unload-callback.exe   \
        appdomain-unload-doesnot-raise-pending-events.exe       \
        unload-appdomain-on-shutdown.exe        \
@@ -1017,6 +1018,7 @@ INTERP_DISABLED_TESTS = \
        appdomain-async-invoke.exe \
        appdomain-exit.exe \
        appdomain-serialize-exception.exe \
+       appdomain-unload-asmload.exe \
        appdomain-unload-callback.exe \
        appdomain-unload-doesnot-raise-pending-events.exe \
        appdomain-unload.exe \
index cc86c7387d0b7728ac01e1d8733786d3b6f4c907..aecae40401d0b921845a313fde973fe7d126c7cc 100644 (file)
@@ -533,6 +533,9 @@ public class Tests
                        if (TestITestDelegate (itest) != 0)
                                return 174;
 
+                       if (TestIfaceNoIcall (itest as ITestPresSig) != 0)
+                               return 201;
+
                        itest = new TestClass ();
 
                        if (TestITest (itest) != 0)
@@ -543,6 +546,7 @@ public class Tests
                        if (TestITest (itest) != 0)
                                return 176;
 
+
 #endif
 
                        #endregion // Runtime Callable Wrapper Tests
@@ -775,6 +779,7 @@ public class Tests
                void ITestIn ([MarshalAs (UnmanagedType.Interface)]ITest val);
                [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
                void ITestOut ([MarshalAs (UnmanagedType.Interface)]out ITest val);
+               int Return22NoICall();
        }
 
        [ComImport ()]
@@ -826,6 +831,8 @@ public class Tests
                [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
                [PreserveSig ()]
                int ITestOut ([MarshalAs (UnmanagedType.Interface)]out ITestPresSig val);
+               [PreserveSig ()]
+               int Return22NoICall();
        }
 
        [System.Runtime.InteropServices.GuidAttribute ("00000000-0000-0000-0000-000000000002")]
@@ -865,6 +872,9 @@ public class Tests
                public virtual extern void ITestIn ([MarshalAs (UnmanagedType.Interface)]ITest val);
                [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
                public virtual extern void ITestOut ([MarshalAs (UnmanagedType.Interface)]out ITest val);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+               public virtual extern int Return22NoICall();
        }
 
        [System.Runtime.InteropServices.GuidAttribute ("00000000-0000-0000-0000-000000000002")]
@@ -1004,6 +1014,11 @@ public class Tests
                        val = new ManagedTestPresSig ();
                        return 0;
                }
+
+               public int Return22NoICall()
+               {
+                       return 88;
+               }
        }
 
        public class ManagedTest : ITest
@@ -1093,6 +1108,11 @@ public class Tests
                                return new ManagedTest ();
                        }
                }
+
+               public int Return22NoICall()
+               {
+                       return 99;
+               }
        }
 
        public static int mono_test_marshal_variant_in_callback (VarEnum vt, object obj)
@@ -1306,6 +1326,10 @@ public class Tests
                }
                return 0;
        }
+
+       public static int TestIfaceNoIcall (ITestPresSig itest) {
+               return itest.Return22NoICall () == 22 ? 0 : 1;
+       }
 }
 
 public class TestVisible
index 4517eda2f74f64ddc41f8e2453372f4b17e5fd12..b94b29d52fd8eae95c11e0877adcc1269a91093d 100644 (file)
@@ -3337,6 +3337,7 @@ typedef struct
        int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
        int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
        int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
+       int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
 } MonoIUnknown;
 
 struct MonoComObject
@@ -3453,6 +3454,13 @@ ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
        return S_OK;
 }
 
+LIBTEST_API int STDCALL
+Return22NoICall(MonoComObject* pUnk)
+{
+       return 22;
+}
+
+
 static void create_com_object (MonoComObject** pOut);
 
 LIBTEST_API int STDCALL 
@@ -3484,6 +3492,7 @@ static void create_com_object (MonoComObject** pOut)
        (*pOut)->vtbl->ITestIn = ITestIn;
        (*pOut)->vtbl->ITestOut = ITestOut;
        (*pOut)->vtbl->get_ITest = get_ITest;
+       (*pOut)->vtbl->Return22NoICall = Return22NoICall;
 }
 
 static MonoComObject* same_object = NULL;
index 8a0d43f3a3660255097fa2cb59e9e21a2f399697..05550ac2277e360581cabe68284d821f3fd55787 100644 (file)
@@ -277,4 +277,20 @@ public class Tests {
                        return 1;
                return 0;
        }
+
+       public static int test_0_generic_ptr_to_struct () {
+               int size = Marshal.SizeOf (typeof (SimpleStruct2));
+               IntPtr p = Marshal.AllocHGlobal (size);
+
+               Marshal.WriteInt32 (p, 0, 1); //a
+               Marshal.WriteInt32 (p, 4, 2); //a
+
+               var s = Marshal.PtrToStructure<SimpleStruct2> (p);
+
+               if (s.a != 1)
+                       return 1;
+               if (s.b != 2)
+                       return 2;
+               return 0;
+       }
 }
index f5449aa086c20d8e6a2b95bcd9a3c28021cba134..70dc4b0554c6eb8d780d1a2c8dcd7feb348ab91a 100644 (file)
     <ClCompile Include="..\mono\mini\mini-native-types.c" />\r
     <ClCompile Include="..\mono\mini\type-checking.c" />\r
     <ClCompile Include="..\mono\mini\lldb.c" />\r
+    <ClCompile Include="..\mono\mini\interp\interp-stubs.c" />\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
     <ProjectGuid>{CB0D9E92-293C-439C-9AC7-C5F59B6E0772}</ProjectGuid>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index 3ff2406521426133728ed01ee90cfdaa43931fda..029b9d162c15144f2740162e2726bb56fb2572ac 100644 (file)
     <ClCompile Include="..\mono\mini\lldb.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\mini\interp\interp-stubs.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\mono\mini\abcremoval.h">\r
       <Filter>Resource Files</Filter>\r
     </None>\r
   </ItemGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index f97a30f3ad3272a71563edd11aa30c0d295676e4..7807fe88fea7e36cd654395ffde0e0679b5eb74f 100644 (file)
@@ -75,6 +75,7 @@
     <ClCompile Include="..\mono\metadata\mono-debug.c" />\r
     <ClCompile Include="..\mono\metadata\mono-endian.c" />\r
     <ClCompile Include="..\mono\metadata\mono-hash.c" />\r
+    <ClCompile Include="..\mono\metadata\mono-conc-hash.c" />\r
     <ClCompile Include="..\mono\metadata\mono-mlist.c" />\r
     <ClCompile Include="..\mono\metadata\mono-perfcounters.c" />\r
     <ClCompile Include="..\mono\metadata\nacl-stub.c" />\r
     <ClInclude Include="..\mono\metadata\mono-debug.h" />\r
     <ClInclude Include="..\mono\metadata\mono-endian.h" />\r
     <ClInclude Include="..\mono\metadata\mono-hash.h" />\r
+    <ClInclude Include="..\mono\metadata\mono-conc-hash.h" />\r
     <ClInclude Include="..\mono\metadata\mono-mlist.h" />\r
     <ClInclude Include="..\mono\metadata\mono-perfcounters-def.h" />\r
     <ClInclude Include="..\mono\metadata\mono-perfcounters.h" />\r
index 6a76b77a4e9ccd2776decdcd439d1b4dd4d65d53..3b1b01037ccb53cf69b148065107f4e33881f25c 100644 (file)
     <ClCompile Include="..\mono\metadata\mono-hash.c">\r
       <Filter>Source Files\gc</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\mono-conc-hash.c">\r
+      <Filter>Source Files\gc</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="..\mono\metadata\object.c">\r
       <Filter>Source Files\gc</Filter>\r
     </ClCompile>\r
     <ClInclude Include="..\mono\metadata\mono-hash.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\mono-conc-hash.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\mono\metadata\mono-mlist.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
diff --git a/packaging/.gitignore b/packaging/.gitignore
new file mode 100644 (file)
index 0000000..be1aeeb
--- /dev/null
@@ -0,0 +1,2 @@
+*.pyo
+
index ed9de8174840f455d66a849a89cb377b9086b268..34f7afe3107adc49b5e64a6826bf9dbba2b59bdd 100644 (file)
@@ -85,16 +85,16 @@ class MonoMasterPackage(Package):
             "LocalMachine")
         ensure_dir(registry_dir)
 
-        # Add ImportBefore/ImportAfter files from xbuild to the msbuild
-        # directories
+        # Add ImportBefore files from xbuild 14.0 toolsVersion directory to msbuild's
+        # 15.0 directory
         xbuild_dir = os.path.join(self.staged_prefix, 'lib/mono/xbuild')
-        new_xbuild_tv_dir = os.path.join(xbuild_dir, self.version)
+        new_xbuild_tv_dir = os.path.join(xbuild_dir, '15.0')
         os.makedirs(new_xbuild_tv_dir)
 
         self.sh('cp -R %s/14.0/Imports %s' % (xbuild_dir, new_xbuild_tv_dir))
-        self.sh(
-            'cp -R %s/14.0/Microsoft.Common.targets %s' %
-            (xbuild_dir, new_xbuild_tv_dir))
+
+        for dep in glob.glob("%s/Microsoft/NuGet/*" % xbuild_dir):
+            self.sh('ln -s %s %s' % (dep, xbuild_dir))
 
     def deploy(self):
         if bockbuild.cmd_options.arch == 'darwin-universal':
index 34d3ae0c650bb0297bb8560c22e2e8ee8f3b0b72..6df28bc78390d0f3d7ce5f7456e9319c3fa13ab9 100644 (file)
@@ -4,7 +4,7 @@ class XamarinGtkThemePackage (Package):
         Package.__init__(self, 'xamarin-gtk-theme',
                          sources=[
                              'git://github.com/mono/xamarin-gtk-theme.git'],
-                         revision='cc3fb66e56d494e968be3a529a0737a60e31c1f3')
+                         revision='b7fe407d869dfeac4eacbcb82771f600e0bbaa83')
 
     def build(self):
         try: