Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

12
samples/size/Makefile Normal file
View File

@@ -0,0 +1,12 @@
all: objectinspector.dll libmono-profiler-size.so sample.exe
LD_LIBRARY_PATH=. mono --profile=size sample.exe
sample.exe: objectinspector.dll sample.cs
mcs -r:objectinspector.dll sample.cs
objectinspector.dll: objectinspector.cs
mcs -target:library objectinspector.cs
libmono-profiler-size.so: size.c
gcc -Wall -g -shared -o libmono-profiler-size.so size.c `pkg-config --cflags --libs mono`

28
samples/size/README Normal file
View File

@@ -0,0 +1,28 @@
* Size sample
This sample provides a new internal call that can be used to
obtain the size of an object and all of the referenced objects
that this object holds.
This is exposed in the method:
int Mono.ObjectServices.ObjectInspector.GetMemoryUsage (object x)
Available in the objectinspector.dll file; To use this, you
must run Mono with the --profile=size argument (and have the
libmono-profile-size.so module in your path).
* Inner Details.
This implementation used a profiler hook at jit-end to install
a new internal call, and exposes a small DLL
(objectinspector.dll).
There is no need to use the profiler, the method body that
does the object size computation can be copy/pasted elsewhere,
particularly on embedded uses of Mono.

View File

@@ -0,0 +1,37 @@
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.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.
//
using System.Runtime.CompilerServices;
using System;
using System.Security;
using System.Reflection;
using System.Threading;
namespace Mono.ObjectServices {
public class ObjectInspector {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static int GetMemoryUsage (object x);
}
}

44
samples/size/sample.cs Normal file
View File

@@ -0,0 +1,44 @@
using System;
using Mono.ObjectServices;
class Demo {
int a;
static void Main ()
{
Demo d = new Demo ();
prints ("d", d);
prints ("dd", new DD ());
prints ("short str", "short");
prints ("long str", "this is a longer string which we want to measure the size of");
object[] obj_array = new object [100];
prints ("obj array", obj_array);
for (int i = 0; i < 100; i++)
obj_array [i] = new Demo ();
prints ("obj array w/ demos", obj_array);
}
static void prints (string s, object x)
{
Console.WriteLine ("size of " + s + ":" + ObjectInspector.GetMemoryUsage (x));
}
}
class DD {
Demo d = new Demo ();
object [] o = new object [10];
char [] ch = new char [10];
int junk;
public DD ()
{
o [0] = new Demo ();
o [5] = new Demo ();
}
}

138
samples/size/size.c Normal file
View File

@@ -0,0 +1,138 @@
#include <glib.h>
#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/tokentype.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/assembly.h>
#include <string.h>
#define FIELD_ATTRIBUTE_STATIC 0x10
#define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x100
static int memory_usage (MonoObject *obj, GHashTable *visited);
static int
memory_usage_array (MonoArray *array, GHashTable *visited)
{
int total = 0;
MonoClass *array_class = mono_object_get_class ((MonoObject *) array);
MonoClass *element_class = mono_class_get_element_class (array_class);
MonoType *element_type = mono_class_get_type (element_class);
if (MONO_TYPE_IS_REFERENCE (element_type)) {
int i;
for (i = 0; i < mono_array_length (array); i++) {
MonoObject *element = mono_array_get (array, gpointer, i);
if (element != NULL)
total += memory_usage (element, visited);
}
}
return total;
}
static int
memory_usage (MonoObject *obj, GHashTable *visited)
{
int total = 0;
MonoClass *klass;
MonoType *type;
gpointer iter = NULL;
MonoClassField *field;
if (g_hash_table_lookup (visited, obj))
return 0;
g_hash_table_insert (visited, obj, obj);
klass = mono_object_get_class (obj);
type = mono_class_get_type (klass);
/* This is an array, so drill down into it */
if (type->type == MONO_TYPE_SZARRAY)
total += memory_usage_array ((MonoArray *) obj, visited);
while ((field = mono_class_get_fields (klass, &iter)) != NULL) {
MonoType *ftype = mono_field_get_type (field);
gpointer value;
if ((ftype->attrs & (FIELD_ATTRIBUTE_STATIC | FIELD_ATTRIBUTE_HAS_FIELD_RVA)) != 0)
continue;
/* FIXME: There are probably other types we need to drill down into */
switch (ftype->type) {
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
mono_field_get_value (obj, field, &value);
if (value != NULL)
total += memory_usage ((MonoObject *) value, visited);
break;
case MONO_TYPE_STRING:
mono_field_get_value (obj, field, &value);
if (value != NULL)
total += mono_object_get_size ((MonoObject *) value);
break;
case MONO_TYPE_SZARRAY:
mono_field_get_value (obj, field, &value);
if (value != NULL) {
total += memory_usage_array ((MonoArray *) value, visited);
total += mono_object_get_size ((MonoObject *) value);
}
break;
default:
/* printf ("Got type 0x%x\n", ftype->type); */
/* ignore, this will be included in mono_object_get_size () */
break;
}
}
total += mono_object_get_size (obj);
return total;
}
/*
* Only returns data for instances, not for static fields, those might
* be larger, or hold larger structures
*/
static int
GetMemoryUsage (MonoObject *this)
{
GHashTable *visited = g_hash_table_new (NULL, NULL);
int n;
n = memory_usage (this, visited);
g_hash_table_destroy (visited);
return n;
}
static int installed = 0;
void install_icall (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result)
{
if (installed)
return;
mono_add_internal_call ("Mono.ObjectServices.ObjectInspector::GetMemoryUsage", GetMemoryUsage);
installed = 1;
}
void
mono_profiler_startup (const char *desc)
{
mono_profiler_install_jit_end (install_icall);
mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION);
}