Imported Upstream version 3.10.0

Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
Jo Shields 2014-10-04 11:27:48 +01:00
parent fe777c5c82
commit 8b9b85e7f5
970 changed files with 20242 additions and 31308 deletions

View File

@ -85,7 +85,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/config.h.in mkinstalldirs \ $(srcdir)/config.h.in mkinstalldirs \
$(srcdir)/mono-core.spec.in $(srcdir)/mono-uninstalled.pc.in \ $(srcdir)/mono-core.spec.in $(srcdir)/mono-uninstalled.pc.in \
AUTHORS COPYING.LIB ChangeLog NEWS compile config.guess \ AUTHORS COPYING.LIB ChangeLog NEWS compile config.guess \
config.rpath config.sub depcomp install-sh missing ltmain.sh config.rpath config.sub install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \

View File

@ -1,7 +1,7 @@
Mono is a software platform designed to allow developers to easily create cross platform applications. Mono is a software platform designed to allow developers to easily create cross platform applications.
Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime. Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime.
[![Build Status](http://monojenkins.cloudapp.net/job/Mono/badge/icon)](http://monojenkins.cloudapp.net/job/Mono/) [![Build Status](http://jenkins.mono-project.com/job/test-mono-mainline/badge/icon/)](http://jenkins.mono-project.com/job/test-mono-mainline/)
1. [Installation](#compilation-and-installation) 1. [Installation](#compilation-and-installation)
2. [Using Mono](#using-mono) 2. [Using Mono](#using-mono)

View File

@ -123,7 +123,6 @@ if test x$has_ext_mod = xtrue; then
popd popd
else else
cat mono/mini/Makefile.am.in > mono/mini/Makefile.am cat mono/mini/Makefile.am.in > mono/mini/Makefile.am
cat mono/metadata/Makefile.am.in > mono/metadata/Makefile.am
fi fi

View File

@ -1 +1 @@
e2d46ae5f394ada396886d241225ad895d4fa194 f98bd1e8bf7b203688329a408624ecaaf8192c9a

View File

@ -1 +1 @@
9ad91a3e3e9b4a437dedfc1a32a3c9092d967f5e 6792b0c1cb1e40049a4610645db04eb603741561

View File

@ -377,7 +377,7 @@ mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_c
</div> </div>
<p /> <p />
<b>Parameters</b> <b>Parameters</b>
<blockquote><dt><i>klass:</i></dt><dd> where to look for the method</dd><dt><i>name_space:</i></dt><dd> name of the method</dd><dt><i>param_count:</i></dt><dd> number of parameters. -1 for any number.</dd></blockquote> <blockquote><dt><i>klass:</i></dt><dd> where to look for the method</dd><dt><i>name:</i></dt><dd> name of the method</dd><dt><i>param_count:</i></dt><dd> number of parameters. -1 for any number.</dd></blockquote>
<b>Remarks</b> <b>Remarks</b>
<p /> <p />
Obtains a MonoMethod with a given name and number of parameters. Obtains a MonoMethod with a given name and number of parameters.

View File

@ -283,15 +283,8 @@
<div class="api"> <div class="api">
<div class="api-entry">DeleteCriticalSection</div> <div class="api-entry">DeleteCriticalSection</div>
<div class="prototype">void DeleteCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: DeleteCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to delete.</dd></blockquote>
<b>Remarks</b>
<p />
Releases all resources owned by critical section <i>section</i>.
</div> <a name="api:DeleteFile"></a> </div> <a name="api:DeleteFile"></a>
<div class="api"> <div class="api">
@ -764,35 +757,15 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
<div class="api"> <div class="api">
<div class="api-entry">InitializeCriticalSectionAndSpinCount</div> <div class="api-entry">InitializeCriticalSectionAndSpinCount</div>
<div class="prototype">gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section, <div class="prototype">Prototype: InitializeCriticalSectionAndSpinCount</div>
guint32 spincount G_GNUC_UNUSED)
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to initialise.</dd><dt><i>spincount:</i></dt><dd> The spin count for this critical section. Not</dd></blockquote>
<b>Remarks</b>
<p /> currently used.
Initialises a critical section and sets the spin count. This
implementation just calls InitializeCriticalSection().
Return value: %TRUE on success, %FALSE otherwise. (%FALSE never
happens).
</div> <a name="api:InitializeCriticalSection"></a> </div> <a name="api:InitializeCriticalSection"></a>
<div class="api"> <div class="api">
<div class="api-entry">InitializeCriticalSection</div> <div class="api-entry">InitializeCriticalSection</div>
<div class="prototype">void InitializeCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: InitializeCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to initialise</dd></blockquote>
<b>Remarks</b>
<p />
Initialises a critical section.
</div> <a name="api:ioctlsocket"></a> </div> <a name="api:ioctlsocket"></a>
<div class="api"> <div class="api">
@ -1046,19 +1019,8 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
<div class="api"> <div class="api">
<div class="api-entry">SetCriticalSectionSpinCount</div> <div class="api-entry">SetCriticalSectionSpinCount</div>
<div class="prototype">guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED) <div class="prototype">Prototype: SetCriticalSectionSpinCount</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to set</dd><dt><i>spincount:</i></dt><dd> The new spin count for this critical section. Not</dd></blockquote>
<b>Remarks</b>
<p /> currently used.
Sets the spin count for the critical section <i>section</i>. The spin
count is currently ignored, and set to zero.
Return value: The previous spin count. (Currently always zero).
</div> <a name="api:SetCurrentDirectory"></a> </div> <a name="api:SetCurrentDirectory"></a>
<div class="api"> <div class="api">
@ -1356,24 +1318,8 @@ SleepEx (guint32 ms, gboolean alertable)
<div class="api"> <div class="api">
<div class="api-entry">TryEnterCriticalSection</div> <div class="api-entry">TryEnterCriticalSection</div>
<div class="prototype">gboolean TryEnterCriticalSection(WapiCriticalSection *section) <div class="prototype">Prototype: TryEnterCriticalSection</div>
</div>
<p /> <p />
<b>Parameters</b>
<blockquote><dt><i>section:</i></dt><dd> The critical section to try and enter</dd></blockquote>
<b>Remarks</b>
<p />
Attempts to enter a critical section without blocking. If
successful the calling thread takes ownership of the critical
section.
A thread can recursively call EnterCriticalSection() and
TryEnterCriticalSection(), but must call LeaveCriticalSection() an
equal number of times.
Return value: %TRUE if the thread successfully locked the critical
section, %FALSE otherwise.
</div> <a name="api:UnlockFile"></a> </div> <a name="api:UnlockFile"></a>
<div class="api"> <div class="api">

View File

@ -273,3 +273,9 @@
#define g_utf8_get_char_validated monoeg_utf8_get_char_validated #define g_utf8_get_char_validated monoeg_utf8_get_char_validated
#define g_utf8_prev_char monoeg_utf8_prev_char #define g_utf8_prev_char monoeg_utf8_prev_char
#define g_utf8_to_ucs4 monoeg_utf8_to_ucs4 #define g_utf8_to_ucs4 monoeg_utf8_to_ucs4
#define g_log_default_handler monoeg_log_default_handler
#define g_log_set_default_handler monoeg_log_set_default_handler
#define g_set_print_handler monoeg_set_print_handler
#define g_set_printerr_handler monoeg_set_printerr_handler

View File

@ -603,10 +603,14 @@ void g_assertion_message (const gchar *format, ...) G_GNUC_NORETURN
#define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__) #define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
#define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif /* ndef HAVE_C99_SUPPORT */ #endif /* ndef HAVE_C99_SUPPORT */
#define g_log_set_handler(a,b,c,d)
#define G_GNUC_INTERNAL typedef void (*GLogFunc) (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data);
typedef void (*GPrintFunc) (const gchar *string);
void g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data);
GLogFunc g_log_set_default_handler (GLogFunc log_func, gpointer user_data);
GPrintFunc g_set_print_handler (GPrintFunc func);
GPrintFunc g_set_printerr_handler (GPrintFunc func);
/* /*
* Conversions * Conversions
*/ */

View File

@ -35,85 +35,47 @@
/* The current fatal levels, error is always fatal */ /* The current fatal levels, error is always fatal */
static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR;
static GLogFunc default_log_func;
static gpointer default_log_func_user_data;
static GPrintFunc stdout_handler, stderr_handler;
#if PLATFORM_ANDROID static void default_stdout_handler (const gchar *string);
#include <android/log.h> static void default_stderr_handler (const gchar *string);
static android_LogPriority
to_android_priority (GLogLevelFlags log_level)
{
switch (log_level & G_LOG_LEVEL_MASK)
{
case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL;
case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR;
case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN;
case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO;
case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG;
case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE;
}
return ANDROID_LOG_UNKNOWN;
}
static void
out_vfprintf (FILE *ignore, const gchar *format, va_list args)
{
/* TODO: provide a proper app name */
__android_log_vprint (ANDROID_LOG_ERROR, "mono", format, args);
}
#elif MONOTOUCH && defined(__arm__)
#include <asl.h>
static int
to_asl_priority (GLogLevelFlags log_level)
{
switch (log_level & G_LOG_LEVEL_MASK)
{
case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT;
case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR;
case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING;
case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE;
case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO;
case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG;
}
return ASL_LEVEL_ERR;
}
static void
out_vfprintf (FILE *ignore, const gchar *format, va_list args)
{
asl_vlog (NULL, NULL, ASL_LEVEL_WARNING, format, args);
}
#else
static void
out_vfprintf (FILE *file, const gchar *format, va_list args)
{
vfprintf (file, format, args);
}
#endif
void void
g_print (const gchar *format, ...) g_print (const gchar *format, ...)
{ {
char *msg;
va_list args; va_list args;
va_start (args, format); va_start (args, format);
if (vasprintf (&msg, format, args) < 0)
out_vfprintf (stdout, format, args); return;
va_end (args); va_end (args);
if (!stdout_handler)
stdout_handler = default_stdout_handler;
stdout_handler (msg);
free (msg);
} }
void void
g_printerr (const gchar *format, ...) g_printerr (const gchar *format, ...)
{ {
char *msg;
va_list args; va_list args;
va_start (args, format); va_start (args, format);
if (vasprintf (&msg, format, args) < 0)
out_vfprintf (stderr, format, args); return;
va_end (args); va_end (args);
if (!stderr_handler)
stderr_handler = default_stderr_handler;
stderr_handler (msg);
free (msg);
} }
GLogLevelFlags GLogLevelFlags
@ -140,42 +102,16 @@ g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask)
void void
g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args) g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args)
{ {
#if PLATFORM_ANDROID
__android_log_vprint (to_android_priority (log_level), log_domain, format, args);
#elif MONOTOUCH && defined(__arm__)
asl_vlog (NULL, NULL, to_asl_priority (log_level), format, args);
#else
char *msg; char *msg;
if (!default_log_func)
default_log_func = g_log_default_handler;
if (vasprintf (&msg, format, args) < 0) if (vasprintf (&msg, format, args) < 0)
return; return;
#ifdef G_OS_WIN32 default_log_func (log_domain, log_level, msg, default_log_func_user_data);
printf ("%s%s%s\n",
log_domain != NULL ? log_domain : "",
log_domain != NULL ? ": " : "",
msg);
#else
#if MONOTOUCH
FILE *target = stderr;
#else
FILE *target = stdout;
#endif
fprintf (target, "%s%s%s\n",
log_domain != NULL ? log_domain : "",
log_domain != NULL ? ": " : "",
msg);
#endif
free (msg); free (msg);
if (log_level & fatal){
fflush (stdout);
fflush (stderr);
}
#endif
if (log_level & fatal){
abort ();
}
} }
void void
@ -196,6 +132,143 @@ g_assertion_message (const gchar *format, ...)
va_start (args, format); va_start (args, format);
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
va_end (args); va_end (args);
abort (); }
#if PLATFORM_ANDROID
#include <android/log.h>
static android_LogPriority
to_android_priority (GLogLevelFlags log_level)
{
switch (log_level & G_LOG_LEVEL_MASK)
{
case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL;
case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR;
case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN;
case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO;
case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG;
case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE;
}
return ANDROID_LOG_UNKNOWN;
}
void
g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
{
__android_log_write (to_android_priority (log_level), log_domain, message);
if (log_level & fatal)
abort ();
}
static void
default_stdout_handler (const gchar *message)
{
/* TODO: provide a proper app name */
__android_log_write (ANDROID_LOG_ERROR, "mono", message);
}
static void
default_stderr_handler (const gchar *message)
{
/* TODO: provide a proper app name */
__android_log_write (ANDROID_LOG_ERROR, "mono", message);
}
#elif MONOTOUCH
#include <asl.h>
static int
to_asl_priority (GLogLevelFlags log_level)
{
switch (log_level & G_LOG_LEVEL_MASK)
{
case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT;
case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR;
case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING;
case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE;
case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO;
case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG;
}
return ASL_LEVEL_ERR;
}
void
g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
{
asl_log (NULL, NULL, to_asl_priority (log_level), "%s", message);
if (log_level & fatal)
abort ();
}
static void
default_stdout_handler (const gchar *message)
{
asl_log (NULL, NULL, ASL_LEVEL_WARNING, "%s", message);
}
static void
default_stderr_handler (const gchar *message)
{
asl_log (NULL, NULL, ASL_LEVEL_WARNING, "%s", message);
}
#else
void
g_log_default_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
{
FILE *target = stdout;
fprintf (target, "%s%s%s\n",
log_domain != NULL ? log_domain : "",
log_domain != NULL ? ": " : "",
message);
if (log_level & fatal) {
fflush (stdout);
fflush (stderr);
abort ();
}
}
static void
default_stdout_handler (const gchar *string)
{
fprintf (stdout, "%s", string);
}
static void
default_stderr_handler (const gchar *string)
{
fprintf (stderr, "%s", string);
}
#endif
GLogFunc
g_log_set_default_handler (GLogFunc log_func, gpointer user_data)
{
GLogFunc old = default_log_func;
default_log_func = log_func;
default_log_func_user_data = user_data;
return old;
}
GPrintFunc
g_set_print_handler (GPrintFunc func)
{
GPrintFunc old = stdout_handler;
stdout_handler = func;
return old;
}
GPrintFunc
g_set_printerr_handler (GPrintFunc func)
{
GPrintFunc old = stderr_handler;
stderr_handler = func;
return old;
} }

View File

@ -150,6 +150,11 @@ namespace Mono.Cecil.PE {
PointerToRawData = buffer.ReadInt32 (), PointerToRawData = buffer.ReadInt32 (),
}; };
if (directory.SizeOfData == 0 || directory.PointerToRawData == 0) {
header = Empty<byte>.Array;
return directory;
}
buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData); buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData);
header = new byte [directory.SizeOfData]; header = new byte [directory.SizeOfData];

View File

@ -3099,9 +3099,29 @@ namespace Mono.Cecil {
} }
} }
string UnescapeTypeName (string name)
{
StringBuilder sb = new StringBuilder (name.Length);
for (int i = 0; i < name.Length; i++) {
char c = name [i];
if (name [i] == '\\') {
if ((i < name.Length - 1) && (name [i + 1] == '\\')) {
sb.Append (c);
i++;
}
} else {
sb.Append (c);
}
}
return sb.ToString ();
}
public TypeReference ReadTypeReference () public TypeReference ReadTypeReference ()
{ {
return TypeParser.ParseType (reader.module, ReadUTF8String ()); string s = ReadUTF8String ();
if (s != null && s.IndexOf ('\\') != -1)
s = UnescapeTypeName (s);
return TypeParser.ParseType (reader.module, s);
} }
object ReadCustomAttributeEnum (TypeReference enum_type) object ReadCustomAttributeEnum (TypeReference enum_type)

View File

@ -1164,9 +1164,14 @@ namespace Mono.Cecil {
MetadataToken GetTypeRefToken (TypeReference type) MetadataToken GetTypeRefToken (TypeReference type)
{ {
MetadataToken token;
if (module.CustomMetadataWriter != null) {
if (module.CustomMetadataWriter.CreateTypeRefToken (ref type, out token))
return token;
}
var row = CreateTypeRefRow (type); var row = CreateTypeRefRow (type);
MetadataToken token;
if (type_ref_map.TryGetValue (row, out token)) if (type_ref_map.TryGetValue (row, out token))
return token; return token;

View File

@ -437,7 +437,7 @@ namespace Mono.Cecil {
} }
#endif #endif
public TypeReference ImportType (TypeReference type, ImportGenericContext context) public virtual TypeReference ImportType (TypeReference type, ImportGenericContext context)
{ {
if (type.IsTypeSpecification ()) if (type.IsTypeSpecification ())
return ImportTypeSpecification (type, context); return ImportTypeSpecification (type, context);
@ -466,6 +466,7 @@ namespace Mono.Cecil {
case MetadataScopeType.AssemblyNameReference: case MetadataScopeType.AssemblyNameReference:
return ImportAssemblyName ((AssemblyNameReference) scope); return ImportAssemblyName ((AssemblyNameReference) scope);
case MetadataScopeType.ModuleDefinition: case MetadataScopeType.ModuleDefinition:
if (scope == module) return scope;
return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name); return ImportAssemblyName (((ModuleDefinition) scope).Assembly.Name);
case MetadataScopeType.ModuleReference: case MetadataScopeType.ModuleReference:
throw new NotImplementedException (); throw new NotImplementedException ();
@ -474,7 +475,7 @@ namespace Mono.Cecil {
throw new NotSupportedException (); throw new NotSupportedException ();
} }
AssemblyNameReference ImportAssemblyName (AssemblyNameReference name) protected virtual AssemblyNameReference ImportAssemblyName (AssemblyNameReference name)
{ {
AssemblyNameReference reference; AssemblyNameReference reference;
if (TryGetAssemblyNameReference (name, out reference)) if (TryGetAssemblyNameReference (name, out reference))

View File

@ -157,6 +157,22 @@ namespace Mono.Cecil {
} }
} }
interface ICustomMetadataWriter
{
/*
* Remap TypeReference or create custom TypeRef token.
*
* Return true to use the returned custom 'token'.
*
* Return false to create a TypeRef token for 'type'
* (which may have been replaced with a different TypeReference).
*
* This is necessary when types are moved from one assembly to another
* to either adjust the scope or replace a TypeRef with a TypeDef token.
*/
bool CreateTypeRefToken (ref TypeReference type, out MetadataToken token);
}
public sealed class WriterParameters { public sealed class WriterParameters {
Stream symbol_stream; Stream symbol_stream;
@ -216,6 +232,7 @@ namespace Mono.Cecil {
#if !READ_ONLY #if !READ_ONLY
MetadataImporter importer; MetadataImporter importer;
ICustomMetadataWriter custom_writer;
#endif #endif
Collection<CustomAttribute> custom_attributes; Collection<CustomAttribute> custom_attributes;
Collection<AssemblyNameReference> references; Collection<AssemblyNameReference> references;
@ -286,6 +303,18 @@ namespace Mono.Cecil {
internal MetadataImporter MetadataImporter { internal MetadataImporter MetadataImporter {
get { return importer ?? (importer = new MetadataImporter (this)); } get { return importer ?? (importer = new MetadataImporter (this)); }
} }
internal void SetMetadataImporter (MetadataImporter importer)
{
if (this.importer != null)
throw new InvalidOperationException ();
this.importer = importer;
}
internal ICustomMetadataWriter CustomMetadataWriter {
get { return custom_writer; }
set { custom_writer = value; }
}
#endif #endif
public IAssemblyResolver AssemblyResolver { public IAssemblyResolver AssemblyResolver {

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters
Copyright (C) 2006 Active Endpoints, Inc. Copyright (C) 2006 Active Endpoints, Inc.
Copyright (C) 2006 - 2013 Volker Berlin (i-net software) Copyright (C) 2006 - 2014 Volker Berlin (i-net software)
Copyright (C) 2011 Karsten Heinrich (i-net software) Copyright (C) 2011 Karsten Heinrich (i-net software)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
@ -40,17 +40,29 @@ namespace ikvm.awt
internal class BitmapGraphics : NetGraphics internal class BitmapGraphics : NetGraphics
{ {
private readonly Bitmap bitmap; private readonly Bitmap bitmap;
private readonly BufferedImage image;
internal BitmapGraphics(Bitmap bitmap, java.awt.Font font, Color fgcolor, Color bgcolor) internal BitmapGraphics(Bitmap bitmap, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor)
: base(createGraphics(bitmap), font, fgcolor, bgcolor) : base(createGraphics(bitmap), destination, font, fgcolor, bgcolor)
{ {
this.bitmap = bitmap; this.bitmap = bitmap;
image = destination as BufferedImage;
} }
internal BitmapGraphics(Bitmap bitmap) internal BitmapGraphics(Bitmap bitmap, Object destination)
: base(createGraphics(bitmap), null, Color.White, Color.Black) : this(bitmap, destination, null, Color.White, Color.Black)
{ {
this.bitmap = bitmap; }
internal override Graphics g
{
get {
if (image != null)
{
image.toBitmap();
}
return base.g;
}
} }
protected override SizeF GetSize() { protected override SizeF GetSize() {
@ -89,8 +101,8 @@ namespace ikvm.awt
{ {
private readonly Control control; private readonly Control control;
internal ComponentGraphics(Control control, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font) internal ComponentGraphics(Control control, java.awt.Component target, java.awt.Color fgColor, java.awt.Color bgColor, java.awt.Font font)
: base(control.CreateGraphics(), font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor)) : base(control.CreateGraphics(), target, font, J2C.ConvertColor(fgColor), J2C.ConvertColor(bgColor))
{ {
this.control = control; this.control = control;
} }
@ -116,12 +128,17 @@ namespace ikvm.awt
return (Point)this.control.Invoke(new Converter<Point,Point>(getPointToScreenImpl),point); return (Point)this.control.Invoke(new Converter<Point,Point>(getPointToScreenImpl),point);
} }
public override void copyArea(int x, int y, int width, int height, int dx, int dy) public override void copyArea(int x, int y, int width, int height, int dx, int dy)
{ {
Point src = getPointToScreen(new Point(x + (int)this.g.Transform.OffsetX, y + (int)this.g.Transform.OffsetY)); Matrix t = g.Transform;
Point dest = new Point(x + (int)this.g.Transform.OffsetX + dx, y + (int)this.g.Transform.OffsetY + dy); Point src = getPointToScreen(new Point(x + (int)t.OffsetX, y + (int)t.OffsetY));
this.g.CopyFromScreen(src, dest, new Size(width, height)); Bitmap copy = new Bitmap(width, height);
} using (Graphics gCopy = Graphics.FromImage(copy))
{
gCopy.CopyFromScreen(src, new Point(0, 0), new Size(width, height));
}
g.DrawImageUnscaled(copy, x + dx, y + dy);
}
public override void clip(java.awt.Shape shape) public override void clip(java.awt.Shape shape)
{ {
@ -150,7 +167,7 @@ namespace ikvm.awt
private bool isBase = true; private bool isBase = true;
internal PrintGraphics(Graphics g) internal PrintGraphics(Graphics g)
: base(g, null, Color.White, Color.Black) : base(g, null, null, Color.White, Color.Black)
{ {
baseContext = new PrintGraphicsContext(); baseContext = new PrintGraphicsContext();
baseContext.Current = this; baseContext.Current = this;
@ -744,7 +761,7 @@ namespace ikvm.awt
netG.g.Clip = Clip; netG.g.Clip = Clip;
netG.g.SmoothingMode = SmoothingMode; netG.g.SmoothingMode = SmoothingMode;
netG.g.PixelOffsetMode = PixelOffsetMode; netG.g.PixelOffsetMode = PixelOffsetMode;
netG.g.TextRenderingHint = TextRenderingHint; netG.setTextRenderingHint(TextRenderingHint);
netG.g.InterpolationMode = InterpolationMode; netG.g.InterpolationMode = InterpolationMode;
netG.g.CompositingMode = CompositingMode; netG.g.CompositingMode = CompositingMode;
} }
@ -768,10 +785,9 @@ namespace ikvm.awt
} }
} }
internal abstract class NetGraphics : java.awt.Graphics2D internal abstract class NetGraphics : java.awt.Graphics2D//sun.java2d.SunGraphics2D
{ {
internal Graphics g; private Graphics graphics;
internal Graphics JGraphics { get { return g; } }
private java.awt.Color javaColor; private java.awt.Color javaColor;
private java.awt.Paint javaPaint; private java.awt.Paint javaPaint;
internal Color color; internal Color color;
@ -780,6 +796,7 @@ namespace ikvm.awt
private java.awt.Stroke stroke; private java.awt.Stroke stroke;
private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke(); private static java.awt.BasicStroke defaultStroke = new java.awt.BasicStroke();
private Font netfont; private Font netfont;
private int baseline;
internal Brush brush; internal Brush brush;
internal Pen pen; internal Pen pen;
private CompositeHelper composite; private CompositeHelper composite;
@ -787,7 +804,16 @@ namespace ikvm.awt
private Object textAntialiasHint; private Object textAntialiasHint;
private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT; private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT;
protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor) private static System.Collections.Generic.Dictionary<String, Int32> baselines = new System.Collections.Generic.Dictionary<String, Int32>();
internal static readonly StringFormat FORMAT = new StringFormat(StringFormat.GenericTypographic);
static NetGraphics()
{
FORMAT.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
FORMAT.Trimming = StringTrimming.None;
}
protected NetGraphics(Graphics g, Object destination, java.awt.Font font, Color fgcolor, Color bgcolor) //: base( new sun.java2d.SurfaceData(destination) )
{ {
if (font == null) if (font == null)
{ {
@ -801,12 +827,21 @@ namespace ikvm.awt
init(g); init(g);
} }
/// <summary>
/// The current C# Graphics
/// </summary>
internal virtual Graphics g
{
get { return graphics; }
set { graphics = value; }
}
protected void init(Graphics graphics) protected void init(Graphics graphics)
{ {
NetGraphicsState state = new NetGraphicsState(); NetGraphicsState state = new NetGraphicsState();
state.saveGraphics(this); state.saveGraphics(this);
g = graphics; g = graphics;
state.restoreGraphics(this); state.restoreGraphics(this);
} }
/// <summary> /// <summary>
@ -850,7 +885,7 @@ namespace ikvm.awt
{ {
if (pen!=null) pen.Dispose(); if (pen!=null) pen.Dispose();
if (brush!=null) brush.Dispose(); if (brush!=null) brush.Dispose();
g.Dispose(); graphics.Dispose(); //for dispose we does not need to synchronize the buffer of a bitmap
} }
public override void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) public override void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
@ -1190,6 +1225,7 @@ namespace ikvm.awt
{ {
netfont = f.getNetFont(); netfont = f.getNetFont();
font = f; font = f;
baseline = getBaseline( netfont, g.TextRenderingHint );
} }
} }
@ -1278,30 +1314,33 @@ namespace ikvm.awt
drawString(str, (float)x, (float)y); drawString(str, (float)x, (float)y);
} }
public override void drawString(String text, float x, float y) public override void drawString(String text, float x, float y) {
{ if (text.Length == 0) {
if (text.Length == 0)
{
return; return;
} }
bool fractional = isFractionalMetrics(); CompositingMode origCM = g.CompositingMode;
StringFormat format = new StringFormat(StringFormat.GenericTypographic); try {
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; if (origCM != CompositingMode.SourceOver) {
format.Trimming = StringTrimming.None; // Java has a different behaviar for AlphaComposite and Text Antialiasing
if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) g.CompositingMode = CompositingMode.SourceOver;
{ }
g.DrawString(text, netfont, brush, x, y - font.getSize(), format);
} bool fractional = isFractionalMetrics();
else if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) {
{ g.DrawString(text, netfont, brush, x, y - baseline, FORMAT);
// fixed metric for simple text, we position every character to simulate the Java behaviour } else {
java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional); // fixed metric for simple text, we position every character to simulate the Java behaviour
sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc); java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional);
y -= font.getSize(); sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc);
for (int i = 0; i < text.Length; i++) y -= baseline;
{ for (int i = 0; i < text.Length; i++) {
g.DrawString(text.Substring(i, 1), netfont, brush, x, y, format); g.DrawString(text.Substring(i, 1), netfont, brush, x, y, FORMAT);
x += metrics.charWidth(text[i]); x += metrics.charWidth(text[i]);
}
}
} finally {
if (origCM != CompositingMode.SourceOver) {
g.CompositingMode = origCM;
} }
} }
} }
@ -1345,6 +1384,9 @@ namespace ikvm.awt
public override void setComposite(java.awt.Composite comp) public override void setComposite(java.awt.Composite comp)
{ {
if (javaComposite == comp) {
return;
}
if (comp == null) if (comp == null)
{ {
throw new java.lang.IllegalArgumentException("null Composite"); throw new java.lang.IllegalArgumentException("null Composite");
@ -1750,13 +1792,13 @@ namespace ikvm.awt
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT || if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT ||
hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
{ {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; setTextRenderingHint(TextRenderingHint.SingleBitPerPixelGridFit);
textAntialiasHint = hintValue; textAntialiasHint = hintValue;
return; return;
} }
if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
{ {
g.TextRenderingHint = TextRenderingHint.AntiAlias; setTextRenderingHint(TextRenderingHint.AntiAlias);
textAntialiasHint = hintValue; textAntialiasHint = hintValue;
return; return;
} }
@ -1933,6 +1975,71 @@ namespace ikvm.awt
return stroke; return stroke;
} }
internal void setTextRenderingHint(TextRenderingHint hint)
{
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
}
/// <summary>
/// Caclulate the baseline from a font and a TextRenderingHint
/// </summary>
/// <param name="font">the font</param>
/// <param name="hint">the used TextRenderingHint</param>
/// <returns></returns>
private static int getBaseline(Font font, TextRenderingHint hint)
{
lock (baselines)
{
String key = font.ToString() + hint.ToString();
int baseline;
if (!baselines.TryGetValue(key, out baseline))
{
FontFamily family = font.FontFamily;
FontStyle style = font.Style;
float ascent = family.GetCellAscent(style);
float lineSpace = family.GetLineSpacing(style);
baseline = (int)Math.Round(font.GetHeight() * ascent / lineSpace);
// Until this point the calulation use only the Font. But with different TextRenderingHint there are smal differences.
// There is no API that calulate the offset from TextRenderingHint that we messure it.
const int w = 3;
const int h = 3;
Bitmap bitmap = new Bitmap(w, h);
Graphics g = Graphics.FromImage(bitmap);
g.TextRenderingHint = hint;
g.FillRectangle(new SolidBrush(Color.White), 0, 0, w, h);
g.DrawString("A", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT);
g.DrawString("X", font, new SolidBrush(Color.Black), 0, -baseline, FORMAT);
g.Dispose();
int y = 0;
LINE:
while (y < h)
{
for (int x = 0; x < w; x++)
{
Color color = bitmap.GetPixel(x, y);
if (color.GetBrightness() < 0.5)
{
//there is a black pixel, we continue in the next line.
baseline++;
y++;
goto LINE;
}
}
break; // there was a line without black pixel
}
baselines[key] = baseline;
}
return baseline;
}
}
private bool isAntiAlias() private bool isAntiAlias()
{ {
switch (g.TextRenderingHint) switch (g.TextRenderingHint)
@ -1962,6 +2069,7 @@ namespace ikvm.awt
Matrix currentMatrix = null; Matrix currentMatrix = null;
Font currentFont = netfont; Font currentFont = netfont;
TextRenderingHint currentHint = g.TextRenderingHint; TextRenderingHint currentHint = g.TextRenderingHint;
int currentBaseline = baseline;
try try
{ {
java.awt.Font javaFont = gv.getFont(); java.awt.Font javaFont = gv.getFont();
@ -1969,19 +2077,22 @@ namespace ikvm.awt
{ {
netfont = javaFont.getNetFont(); netfont = javaFont.getNetFont();
} }
TextRenderingHint hint;
if (frc.isAntiAliased()) { if (frc.isAntiAliased()) {
if( frc.usesFractionalMetrics() ){ if( frc.usesFractionalMetrics() ){
g.TextRenderingHint = TextRenderingHint.AntiAlias; hint = TextRenderingHint.AntiAlias;
} else { } else {
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; hint = TextRenderingHint.AntiAliasGridFit;
} }
} else { } else {
if (frc.usesFractionalMetrics()) { if (frc.usesFractionalMetrics()) {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; hint = TextRenderingHint.SingleBitPerPixel;
} else { } else {
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; hint = TextRenderingHint.SingleBitPerPixelGridFit;
} }
} }
g.TextRenderingHint = hint;
baseline = getBaseline(netfont, hint);
if (!frc.getTransform().equals(getTransform())) if (!frc.getTransform().equals(getTransform()))
{ {
// save the old context and use the transformation from the renderContext // save the old context and use the transformation from the renderContext
@ -1994,6 +2105,7 @@ namespace ikvm.awt
{ {
// Restore the old context if needed // Restore the old context if needed
g.TextRenderingHint = currentHint; g.TextRenderingHint = currentHint;
baseline = currentBaseline;
netfont = currentFont; netfont = currentFont;
if (currentMatrix != null) if (currentMatrix != null)
{ {
@ -2144,14 +2256,20 @@ namespace ikvm.awt
} }
} }
public class NetGraphicsEnvironment : java.awt.GraphicsEnvironment public class NetGraphicsEnvironment : sun.java2d.SunGraphicsEnvironment
{ {
public override bool isDisplayLocal()
{
return true;
}
// Create a bitmap with the dimensions of the argument image. Then // Create a bitmap with the dimensions of the argument image. Then
// create a graphics objects from the bitmap. All paint operations will // create a graphics objects from the bitmap. All paint operations will
// then paint the bitmap. // then paint the bitmap.
public override java.awt.Graphics2D createGraphics(BufferedImage bi) public override java.awt.Graphics2D createGraphics(BufferedImage bi)
{ {
return new BitmapGraphics(bi.getBitmap()); return new BitmapGraphics(bi.getBitmap(), bi );
} }
public override java.awt.Font[] getAllFonts() public override java.awt.Font[] getAllFonts()

View File

@ -1 +1 @@
4341b9c30b528a9c448533ed715fc437369b3561 474cfafc92a8fad74e36e71fb612ebd44209bce8

15
external/ikvm/bin/ikvm.exe.manifest vendored Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>

View File

@ -0,0 +1,380 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
import java.util.function.LongBinaryOperator;
import java.util.function.DoubleBinaryOperator;
import java.util.concurrent.ThreadLocalRandom;
/**
* A package-local class holding common representation and mechanics
* for classes supporting dynamic striping on 64bit values. The class
* extends Number so that concrete subclasses must publicly do so.
*/
@SuppressWarnings("serial")
abstract class Striped64 extends Number {
/*
* This class maintains a lazily-initialized table of atomically
* updated variables, plus an extra "base" field. The table size
* is a power of two. Indexing uses masked per-thread hash codes.
* Nearly all declarations in this class are package-private,
* accessed directly by subclasses.
*
* Table entries are of class Cell; a variant of AtomicLong padded
* (via @sun.misc.Contended) to reduce cache contention. Padding
* is overkill for most Atomics because they are usually
* irregularly scattered in memory and thus don't interfere much
* with each other. But Atomic objects residing in arrays will
* tend to be placed adjacent to each other, and so will most
* often share cache lines (with a huge negative performance
* impact) without this precaution.
*
* In part because Cells are relatively large, we avoid creating
* them until they are needed. When there is no contention, all
* updates are made to the base field. Upon first contention (a
* failed CAS on base update), the table is initialized to size 2.
* The table size is doubled upon further contention until
* reaching the nearest power of two greater than or equal to the
* number of CPUS. Table slots remain empty (null) until they are
* needed.
*
* A single spinlock ("cellsBusy") is used for initializing and
* resizing the table, as well as populating slots with new Cells.
* There is no need for a blocking lock; when the lock is not
* available, threads try other slots (or the base). During these
* retries, there is increased contention and reduced locality,
* which is still better than alternatives.
*
* The Thread probe fields maintained via ThreadLocalRandom serve
* as per-thread hash codes. We let them remain uninitialized as
* zero (if they come in this way) until they contend at slot
* 0. They are then initialized to values that typically do not
* often conflict with others. Contention and/or table collisions
* are indicated by failed CASes when performing an update
* operation. Upon a collision, if the table size is less than
* the capacity, it is doubled in size unless some other thread
* holds the lock. If a hashed slot is empty, and lock is
* available, a new Cell is created. Otherwise, if the slot
* exists, a CAS is tried. Retries proceed by "double hashing",
* using a secondary hash (Marsaglia XorShift) to try to find a
* free slot.
*
* The table size is capped because, when there are more threads
* than CPUs, supposing that each thread were bound to a CPU,
* there would exist a perfect hash function mapping threads to
* slots that eliminates collisions. When we reach capacity, we
* search for this mapping by randomly varying the hash codes of
* colliding threads. Because search is random, and collisions
* only become known via CAS failures, convergence can be slow,
* and because threads are typically not bound to CPUS forever,
* may not occur at all. However, despite these limitations,
* observed contention rates are typically low in these cases.
*
* It is possible for a Cell to become unused when threads that
* once hashed to it terminate, as well as in the case where
* doubling the table causes no thread to hash to it under
* expanded mask. We do not try to detect or remove such cells,
* under the assumption that for long-running instances, observed
* contention levels will recur, so the cells will eventually be
* needed again; and for short-lived ones, it does not matter.
*/
/**
* Padded variant of AtomicLong supporting only raw accesses plus CAS.
*
* JVM intrinsics note: It would be possible to use a release-only
* form of CAS here, if it were provided.
*/
@sun.misc.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
@ikvm.internal.InterlockedCompareAndSet("value")
final native boolean cas(long cmp, long val);
}
/** Number of CPUS, to place bound on table size */
static final int NCPU = Runtime.getRuntime().availableProcessors();
/**
* Table of cells. When non-null, size is a power of 2.
*/
transient volatile Cell[] cells;
/**
* Base value, used mainly when there is no contention, but also as
* a fallback during table initialization races. Updated via CAS.
*/
transient volatile long base;
/**
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
*/
transient volatile int cellsBusy;
/**
* Package-private default constructor
*/
Striped64() {
}
/**
* CASes the base field.
*/
@ikvm.internal.InterlockedCompareAndSet("base")
final native boolean casBase(long cmp, long val);
/**
* CASes the cellsBusy field from 0 to 1 to acquire lock.
*/
final boolean casCellsBusy() {
return casCellsBusy(0, 1);
}
@ikvm.internal.InterlockedCompareAndSet("cellsBusy")
private native boolean casCellsBusy(int cmp, int newVal);
/**
* Returns the probe value for the current thread.
* Duplicated from ThreadLocalRandom because of packaging restrictions.
*/
static final int getProbe() {
return Thread.currentThread().threadLocalRandomProbe;
}
/**
* Pseudo-randomly advances and records the given probe value for the
* given thread.
* Duplicated from ThreadLocalRandom because of packaging restrictions.
*/
static final int advanceProbe(int probe) {
probe ^= probe << 13; // xorshift
probe ^= probe >>> 17;
probe ^= probe << 5;
Thread.currentThread().threadLocalRandomProbe = probe;
return probe;
}
/**
* Handles cases of updates involving initialization, resizing,
* creating new Cells, and/or contention. See above for
* explanation. This method suffers the usual non-modularity
* problems of optimistic retry code, relying on rechecked sets of
* reads.
*
* @param x the value
* @param fn the update function, or null for add (this convention
* avoids the need for an extra field or function in LongAdder).
* @param wasUncontended false if CAS failed before call
*/
final void longAccumulate(long x, LongBinaryOperator fn,
boolean wasUncontended) {
int h;
if ((h = getProbe()) == 0) {
ThreadLocalRandom.current(); // force initialization
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
if ((as = cells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(x); // Optimistically create
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
rs[j = (m - 1) & h] == null) {
rs[j] = r;
created = true;
}
} finally {
cellsBusy = 0;
}
if (created)
break;
continue; // Slot is now non-empty
}
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (a.cas(v = a.value, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break;
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
if (cells == as) { // Expand table unless stale
Cell[] rs = new Cell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
cells = rs;
}
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(x);
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
else if (casBase(v = base, ((fn == null) ? v + x :
fn.applyAsLong(v, x))))
break; // Fall back on using base
}
}
/**
* Same as longAccumulate, but injecting long/double conversions
* in too many places to sensibly merge with long version, given
* the low-overhead requirements of this class. So must instead be
* maintained by copy/paste/adapt.
*/
final void doubleAccumulate(double x, DoubleBinaryOperator fn,
boolean wasUncontended) {
int h;
if ((h = getProbe()) == 0) {
ThreadLocalRandom.current(); // force initialization
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
if ((as = cells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
if (cellsBusy == 0) { // Try to attach new Cell
Cell r = new Cell(Double.doubleToRawLongBits(x));
if (cellsBusy == 0 && casCellsBusy()) {
boolean created = false;
try { // Recheck under lock
Cell[] rs; int m, j;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
rs[j = (m - 1) & h] == null) {
rs[j] = r;
created = true;
}
} finally {
cellsBusy = 0;
}
if (created)
break;
continue; // Slot is now non-empty
}
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
else if (a.cas(v = a.value,
((fn == null) ?
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
(fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break;
else if (n >= NCPU || cells != as)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
if (cells == as) { // Expand table unless stale
Cell[] rs = new Cell[n << 1];
for (int i = 0; i < n; ++i)
rs[i] = as[i];
cells = rs;
}
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
boolean init = false;
try { // Initialize table
if (cells == as) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
cells = rs;
init = true;
}
} finally {
cellsBusy = 0;
}
if (init)
break;
}
else if (casBase(v = base,
((fn == null) ?
Double.doubleToRawLongBits
(Double.longBitsToDouble(v) + x) :
Double.doubleToRawLongBits
(fn.applyAsDouble
(Double.longBitsToDouble(v), x)))))
break; // Fall back on using base
}
}
}

View File

@ -35,7 +35,7 @@
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile> <ConfigurationOverrideFile>
</ConfigurationOverrideFile> </ConfigurationOverrideFile>
<DefineConstants>TRACE;DEBUG;STATIC_COMPILER;IKVM_REF_EMIT</DefineConstants> <DefineConstants>TRACE;DEBUG;STATIC_COMPILER;EMITTERS</DefineConstants>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -91,6 +91,7 @@
<Compile Include="runtime\BigEndianBinaryReader.cs"> <Compile Include="runtime\BigEndianBinaryReader.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\Boxer.cs" />
<Compile Include="runtime\ByteCode.cs"> <Compile Include="runtime\ByteCode.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@ -119,10 +120,12 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\JsrInliner.cs" /> <Compile Include="runtime\JsrInliner.cs" />
<Compile Include="runtime\LambdaMetafactory.cs" />
<Compile Include="runtime\LocalVars.cs" /> <Compile Include="runtime\LocalVars.cs" />
<Compile Include="runtime\MemberWrapper.cs"> <Compile Include="runtime\MemberWrapper.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="runtime\MethodHandleUtil.cs" />
<Compile Include="runtime\profiler.cs"> <Compile Include="runtime\profiler.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

Some files were not shown because too many files have changed in this diff Show More