core/NativeOwner.cpp
author David Anderson <dvander@alliedmods.net>
Fri Aug 15 05:22:26 2008 +0000 (2008-08-15)
changeset 2226 d10b38524be3
parent 2088 c84cd855ca10
permissions -rw-r--r--
Landed sourcepawn-1.2. The big changes:

1) JIT compilation/optimization now occurs per-function, and only when functions are first used. We're now officially a whole-method JIT rather than an AOT compiler (albiet, still a simple JIT). This has two implications: Functions are now much better abstracted internally, and loading a plugin is now much less expensive. If a function contains calls to other functions, THOSE functions are only compiled when they're invoked as well.

2) I've removed debug mode. We always show full backtraces now, as there was a very cheap way to implement this which really cleaned up everything. This is great for a number of reasons -- there's less code, the JIT is better designed, we don't need to relocate debug tables, and best of all we no longer have to tell users to enable debug mode at their own expense.
dvander@2088
     1
#include "NativeOwner.h"
dvander@2088
     2
#include "ShareSys.h"
dvander@2088
     3
#include "PluginSys.h"
dvander@2088
     4
dvander@2226
     5
CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
dvander@2226
     6
{
dvander@2226
     7
}
dvander@2226
     8
dvander@2088
     9
void CNativeOwner::SetMarkSerial(unsigned int serial)
dvander@2088
    10
{
dvander@2088
    11
	m_nMarkSerial = serial;
dvander@2088
    12
}
dvander@2088
    13
dvander@2088
    14
unsigned int CNativeOwner::GetMarkSerial()
dvander@2088
    15
{
dvander@2088
    16
	return m_nMarkSerial;
dvander@2088
    17
}
dvander@2088
    18
dvander@2088
    19
void CNativeOwner::AddDependent(CPlugin *pPlugin)
dvander@2088
    20
{
dvander@2088
    21
	m_Dependents.push_back(pPlugin);
dvander@2088
    22
}
dvander@2088
    23
dvander@2088
    24
void CNativeOwner::AddWeakRef(const WeakNative & ref)
dvander@2088
    25
{
dvander@2088
    26
	m_WeakRefs.push_back(ref);
dvander@2088
    27
}
dvander@2088
    28
dvander@2088
    29
void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
dvander@2088
    30
{
dvander@2088
    31
	NativeEntry *pEntry;
dvander@2088
    32
dvander@2088
    33
	for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
dvander@2088
    34
	{
dvander@2088
    35
		if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
dvander@2088
    36
		{
dvander@2088
    37
			continue;
dvander@2088
    38
		}
dvander@2088
    39
dvander@2088
    40
		m_Natives.push_back(pEntry);
dvander@2088
    41
	}
dvander@2088
    42
}
dvander@2088
    43
dvander@2088
    44
void CNativeOwner::PropogateMarkSerial(unsigned int serial)
dvander@2088
    45
{
dvander@2088
    46
	CNativeOwner *pOwner;
dvander@2088
    47
	List<CPlugin *>::iterator iter;
dvander@2088
    48
dvander@2088
    49
	for (iter = m_Dependents.begin();
dvander@2088
    50
		 iter != m_Dependents.end();
dvander@2088
    51
		 iter++)
dvander@2088
    52
	{
dvander@2088
    53
		pOwner = (*iter);
dvander@2088
    54
		pOwner->SetMarkSerial(serial);
dvander@2088
    55
	}
dvander@2088
    56
}
dvander@2088
    57
dvander@2088
    58
void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
dvander@2088
    59
{
dvander@2088
    60
	sp_native_t *native;
dvander@2088
    61
	IPluginContext *pContext;
dvander@2088
    62
dvander@2088
    63
	pContext = ref.pl->GetBaseContext();
dvander@2088
    64
	if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
dvander@2088
    65
	{
dvander@2088
    66
		/* If there is no reference, the native must be unbound */
dvander@2088
    67
		if (ref.entry == NULL)
dvander@2088
    68
		{
dvander@2088
    69
			native->status = SP_NATIVE_UNBOUND;
dvander@2088
    70
			native->pfn = NULL;
dvander@2088
    71
		}
dvander@2088
    72
		/* If we've cached a reference, it's a core native we can 
dvander@2088
    73
		 * rebind back to its original (this was a replacement).
dvander@2088
    74
		 */
dvander@2088
    75
		else
dvander@2088
    76
		{
dvander@2088
    77
			native->pfn = ref.entry->func;
dvander@2088
    78
		}
dvander@2088
    79
	}
dvander@2088
    80
}
dvander@2088
    81
dvander@2088
    82
void CNativeOwner::DropEverything()
dvander@2088
    83
{
dvander@2088
    84
	NativeEntry *pEntry;
dvander@2088
    85
	List<WeakNative>::iterator iter;
dvander@2088
    86
	List<NativeEntry *>::iterator ntv_iter;
dvander@2088
    87
dvander@2088
    88
	/* Unbind and remove all weak references to us */
dvander@2088
    89
	iter = m_WeakRefs.begin();
dvander@2088
    90
	while (iter != m_WeakRefs.end())
dvander@2088
    91
	{
dvander@2088
    92
		UnbindWeakRef((*iter));
dvander@2088
    93
		iter = m_WeakRefs.erase(iter);
dvander@2088
    94
	}
dvander@2088
    95
dvander@2088
    96
	/* Unmark our replacement natives */
dvander@2088
    97
	ntv_iter = m_ReplacedNatives.begin();
dvander@2088
    98
	while (ntv_iter != m_ReplacedNatives.end())
dvander@2088
    99
	{
dvander@2088
   100
		pEntry = (*ntv_iter);
dvander@2088
   101
		pEntry->replacement.func = NULL;
dvander@2088
   102
		pEntry->replacement.owner = NULL;
dvander@2088
   103
		ntv_iter = m_ReplacedNatives.erase(ntv_iter);
dvander@2088
   104
	}
dvander@2088
   105
dvander@2088
   106
	/* Strip all of our natives from the cache */
dvander@2088
   107
	ntv_iter = m_Natives.begin();
dvander@2088
   108
	while (ntv_iter != m_Natives.end())
dvander@2088
   109
	{
dvander@2088
   110
		g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
dvander@2088
   111
		ntv_iter = m_Natives.erase(ntv_iter);
dvander@2088
   112
	}
dvander@2088
   113
}
dvander@2088
   114
dvander@2088
   115
void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
dvander@2088
   116
{
dvander@2088
   117
	List<WeakNative>::iterator iter;
dvander@2088
   118
dvander@2088
   119
	iter = m_WeakRefs.begin();
dvander@2088
   120
	while (iter != m_WeakRefs.end())
dvander@2088
   121
	{
dvander@2088
   122
		WeakNative & ref = (*iter);
dvander@2088
   123
dvander@2088
   124
		if (ref.pl == pPlugin)
dvander@2088
   125
		{
dvander@2088
   126
			iter = m_WeakRefs.erase(iter);
dvander@2088
   127
		}
dvander@2088
   128
		else
dvander@2088
   129
		{
dvander@2088
   130
			iter++;
dvander@2088
   131
		}
dvander@2088
   132
	}
dvander@2088
   133
}
dvander@2088
   134
dvander@2088
   135
void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
dvander@2088
   136
{
dvander@2088
   137
	m_Dependents.remove(pPlugin);
dvander@2088
   138
	DropWeakRefsTo(pPlugin);
dvander@2088
   139
}
dvander@2088
   140
dvander@2088
   141
void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
dvander@2088
   142
{
dvander@2088
   143
	m_ReplacedNatives.push_back(pEntry);
dvander@2088
   144
}