#include <lowlevel/barriers.h>
#include <lowlevel/bitops.h>
+#include <util/array.h>
+
namespace System {
struct _i_Object;
}
namespace RunTime {
+ using namespace ::Util::Arrays;
+
class ORBMM {
- void *priv;
+ static void *priv;
public:
- class AllocGroup {
- friend class ORBMM;
- };
-
typedef ::System::Mem::Region Region;
- ORBMM();
-
- void *alloc(size_t size, int refs = 1);
- void retain(void *ptr, int refs = 1);
- void release(void *ptr, int refs = 1);
- void add_region(Region region, bool unmap_orig, int refs = 1);
- };
-
- extern ORBMM *orbmm;
-
- // FIXME: should be an IDL exception
- struct ArrayException
- {
- };
-
- class NullArray {
- };
-
- static const NullArray nullarray = {};
-
- template<typename T> struct MutableArray {
- T *ptr;
- size_t count;
-
- bool valid_index(size_t index)
- {
- return index >= 0 && index < count;
- }
-
- T &operator[](size_t index)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(index))
- throw ArrayException();
-#endif
-
- return ptr[index];
- }
-
- MutableArray()
- {
- ptr = NULL;
- count = 0;
- }
-
- MutableArray(NullArray na)
- {
- ptr = NULL;
- count = 0;
- }
-
- MutableArray(T *PTR, size_t COUNT)
- {
- ptr = PTR;
- count = COUNT;
- }
-
- MutableArray &slice_nocheck(size_t first, size_t newcount)
- {
- MutableArray ret;
- ret.ptr = ptr + first;
- ret.count = newcount;
- return ret;
- }
-
- MutableArray &slice_nocheck(size_t first)
- {
- MutableArray ret;
- ret.ptr = ptr + first;
- ret.count = count - first;
- return ret;
- }
-
- MutableArray &slice(size_t first, size_t count)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(first) || !valid_index(first + count - 1))
- throw ArrayException();
-#endif
-
- return slice_nocheck(first, count);
- }
-
- MutableArray &slice(size_t first)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(first))
- throw ArrayException();
-#endif
-
- return slice_nocheck(first);
- }
-
- MutableArray copy()
- {
- MutableArray new_arr;
- new_arr.ptr = new(orbmm) T[count];
- new_arr.count = count;
- memcpy(new_arr.ptr, ptr, count);
- return new_arr;
- }
+ static void *alloc(size_t size, int refs = 1);
+ static void retain(void *ptr, int refs = 1);
+ static void release(void *ptr, int refs = 1);
+ static void add_region(Region region, bool unmap_orig, int refs = 1);
};
- template<typename T>
- struct GrowableArray : public MutableArray<T> {
- using MutableArray<T>::ptr;
- using MutableArray<T>::count;
- size_t bufsize;
-
- GrowableArray()
- {
- bufsize = 0;
- }
-
- GrowableArray(NullArray na) : MutableArray<T>(na)
- {
- bufsize = 0;
- }
-
- GrowableArray(T *PTR, size_t COUNT) : MutableArray<T>(PTR, COUNT)
- {
- bufsize = COUNT;
- }
-
- GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) :
- MutableArray<T>(PTR, COUNT)
- {
- bufsize = BUFSIZE;
- }
-
- GrowableArray(MutableArray<T> &ma) : MutableArray<T>(ma)
- {
- bufsize = count;
- }
-
- void grow(size_t newsize)
- {
- if (newsize <= bufsize)
- return;
-
- T *oldptr = ptr;
- T *newptr = new(orbmm) T[newsize];
- memcpy(newptr, ptr, count * sizeof(T));
- ptr = newptr;
- ll_smp_membar_store_after_store();
- bufsize = newsize;
- // FIXME: Should release imply membar?
- ll_smp_membar_any_after_store();
- orbmm->release(oldptr);
- }
-
- // Caller must sync against all writers.
- void append(T *newptr, size_t len, size_t max = ULONG_MAX)
- {
- if (count + len < count)
- throw ArrayException();
-
- if (count + len > max)
- throw ArrayException();
-
- if (count + len > bufsize)
- grow(ll_get_order_round_up(count + len));
-
- memcpy(ptr + count, newptr, len * sizeof(T));
- count += len;
- }
- };
-
- template<typename T> struct Array {
- const T *ptr;
- size_t count;
-
- bool valid_index(size_t index)
- {
- return index >= 0 && index < count;
- }
-
- const T &operator[](size_t index)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(index))
- throw ArrayException();
-#endif
-
- return ptr[index];
- }
-
- Array()
- {
- ptr = NULL;
- count = 0;
- }
-
- Array(NullArray na)
- {
- ptr = NULL;
- count = 0;
- }
-
- Array(const T *PTR, size_t COUNT)
- {
- ptr = PTR;
- count = COUNT;
- }
-
- Array(MutableArray<T> ma)
- {
- ptr = ma.ptr;
- count = ma.count;
- }
-
- MutableArray<T> constcast()
- {
- MutableArray<T> ma;
- ma.ptr = const_cast<T>(ptr);
- ma.count = count;
- return ma;
- }
-
- Array &slice_nocheck(size_t first, size_t newcount)
- {
- Array ret;
- ret.ptr = ptr + first;
- ret.count = newcount;
- return ret;
- }
-
- Array &slice_nocheck(size_t first)
- {
- Array ret;
- ret.ptr = ptr + first;
- ret.count = count - first;
- return ret;
- }
-
- Array &slice(size_t first, size_t count)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(first) || !valid_index(first + count - 1))
- throw ArrayException();
-#endif
-
- return slice_nocheck(first, count);
- }
-
- Array &slice(size_t first)
- {
-#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
- if (!valid_index(first))
- throw ArrayException();
-#endif
-
- return slice_nocheck(first);
- }
-
- MutableArray<T> copy()
- {
- MutableArray<T> new_arr;
- new_arr.ptr = new(orbmm) T[count];
- new_arr.count = count;
- memcpy(new_arr.ptr, ptr, count);
- return new_arr;
- }
- };
-
- static inline Array<uint8_t> countarray(const char *ptr)
- {
- Array<uint8_t> ret;
- ret.ptr = reinterpret_cast<const uint8_t *>(ptr);
- ret.count = strlen(ptr);
- return ret;
- }
-
- static inline MutableArray<uint8_t> countarray(char *ptr)
- {
- MutableArray<uint8_t> ret;
- ret.ptr = reinterpret_cast<uint8_t *>(ptr);
- ret.count = strlen(ptr);
- return ret;
- }
-
struct IFaceInfo;
typedef uint32_t ID;
union GUID {
unsigned char c[16];
- unsigned long l[];
+ unsigned long l[16 / sizeof(unsigned long)];
};
uintptr_t downcast(::System::_i_Object *obj, const GUID *new_guid);
struct IFaceInfo {
const GUID *guid;
- void (*invoke)(Array<ID> objlist,
+ void (*invoke)(Array<ID, ORBMM> objlist,
ParamInfoBlock::Segment *segs,
int nsegs);
::System::_i_Object *(*wrapper)(ID id);
uint32_t reserved[3]; // must be zero
};
+ struct MarshCtx {
+ GrowableArray<uint8_t, ORBMM> &buf;
+ GrowableArray<ID, ORBMM> &objlist;
+ GrowableArray<NewObject, ORBMM> &newobjlist;
+ ParamInfoBlock::Segment *segs;
+ int nsegs;
+ };
+
struct VStructInfo {
// List of GUIDs of the struct and its superstructs,
// starting with System.VStruct and ending with
const int chainlen;
- int (*marshall)(GrowableArray<uint8_t> &buf,
- GrowableArray<ID> &objlist,
- GrowableArray<NewObject> &newobjlist,
- ParamInfoBlock::Segment *segs,
- int nsegs);
- void (*unmarshall)(Array<uint8_t> buf,
- Array< ::System::_i_Object *> objlist,
- ParamInfoBlock::Segment *segs,
- int nsegs);
+ int (*marshall)(MarshCtx &ctx);
+ void (*unmarshall)(MarshCtx &ctx);
};
-
+
namespace Priv {
// Return the caller's PC. It'd be nice if GCC had a builtin for
// the current PC, so that a simple relocation could be used rather
return false;
#endif
}
+
}
};
}
-inline void *operator new(size_t len, ::System::RunTime::ORBMM *orbmm,
+inline void *operator new(size_t len, ::System::RunTime::ORBMM orbmm,
int refs = 1)
{
- return orbmm->alloc(len, refs);
-}
-
-inline void *operator new[](size_t len, ::System::RunTime::ORBMM *orbmm,
- int refs = 1)
-{
- return orbmm->alloc(len, refs);
+ return ::System::RunTime::ORBMM::alloc(len, refs);
}
-// FIXME: This isn't safe on anything with a descructor.
-inline void operator delete(void *ptr, ::System::RunTime::ORBMM *orbmm,
+inline void *operator new[](size_t len, ::System::RunTime::ORBMM orbmm,
int refs = 1)
{
- orbmm->release(ptr, refs);
-}
-
-inline void operator delete[](void *ptr, ::System::RunTime::ORBMM *orbmm,
- int refs = 1)
-{
- orbmm->release(ptr, refs);
+ return ::System::RunTime::ORBMM::alloc(len, refs);
}
// This is a macro rather than an inline template function so that the
#ifndef POLINTOS_NO_THROW_IDL
#define throw_idl(T, args...) do { \
throw T(NULL, NULL, \
- new(::System::RunTime::orbmm) \
+ new(::System::RunTime::ORBMM()) \
::System::Exceptions::NativeCodeExceptionOriginInfo \
(::System::RunTime::Priv::get_pc()), \
::System::RunTime::Priv::in_kernel(), ##args); \
} while (0)
#define rethrow_idl(oldex, T, args...) do { \
- throw T(new(::System::RunTime::orbmm) typeof(oldex)(oldex), NULL, \
- new(::System::RunTime::orbmm) \
+ throw T(new(::System::RunTime::ORBMM()) typeof(oldex)(oldex), NULL, \
+ new(::System::RunTime::ORBMM()) \
::System::Exceptions::NativeCodeExceptionOriginInfo \
(::System::RunTime::Priv::get_pc()), \
::System::RunTime::Priv::in_kernel(), ##args); \