Table Of Contents

Programming Reference

Predefined Macros

Frequently used macros

__OBJC_GC__
This macro is defined if the source is being compiled with garbage collection enabled, including MRRGC, ARCGC and ARCGC_C, provided by GCC-4.2, LLVM-GCC-4.2 and Clang compilers.
__has_feature(objc_arc)
This __has_feature expression returns true in ARC, ARCGC and ARCGC_C, provided by Clang compiler.

Examples

#if !defined(__OBJC_GC__) && !__has_feature(objc_arc)
// Code that is only for MRR (GC disabled)
#endif

#if !defined(__OBJC_GC__) && __has_feature(objc_arc)
// Code that is only for ARC (GC disabled)
#endif

#if defined(__OBJC_GC__) && !__has_feature(objc_arc)
// Code that is only for MRRGC
#endif

#if defined(__OBJC_GC__) && __has_feature(objc_arc)
// Code that is for ARCGC or ARCGC_C
#endif

iGC Clang specific macros

The followings macros are provided only by iGC Clang compiler. They return false under other compilers, including GCC-4.2 and LLVM-GCC-4.2 compilers.

__has_feature(objc_arc_gc)
return true in ARCGC or ARCGC_C.
__has_feature(objc_arc_gc_compatible)
return true in ARCGC_C.
__has_feature(objc_hnxgc)
return true in MRRGC, ARCGC, or ARCGC_C.
__has_feature(objc_hnx)
return true always no matter garbage collection is enabled or not.

Examples

#if __has_feature(objc_arc_gc) && !__has_feature(objc_arc_gc_compatible)
// Code that only for ARCGC
#endif

#if __has_feature(objc_arc_gc_compatible)
// Code that only for ARCGC_C
#endif

General C functions

All the functions described in this Programming Reference are declared in the header file “hnxgc.h”, include it before using any of the following functions.

#include "hnxgc.h"

Perform garbage collection

void _hnxgc_collect()

The same as HXSystem_gc.

void HXSystem_gc()

Explicitly call this function to invoke garbage collection.

Remarks

Usually you do not need to call this function. The system will invoke garbage collection when necessary. A complicate policy has been implemented to determine when and how frequently should garbage collection be performed.

This function may block and take noticeable time to finish, and the garbage collection may not be conducted in the caller thread, but in a background collector.

void HXSystem_gcNoWait()

Explicitly call this function to invoke garbage collection and return immediately.

Remarks

This function does not block and returns immediately. It notifies the background collector to perform garbage collection. The run of garbage collection may be delayed or not performed if the system thought it was not necessary.

For single thread environment, this function is the same as HXSystem_gc.

void _hnxgc_enter_multithreading()

Optionally call this function to notify the system of entering multi-threading.

Remarks

If a new thread is running, the system can detect that and automatically enter multi-threading mode, e.g. launching a dedicated collector thread. You can explicitly call this function to enter multi-threading mode even there is only a single application thread running.

This function should be called from the main thread before any other threads begin to run.

void _hnxgc_add_memory_pressure(size_t size, bool bRemove)

Call this function to notify the sytem an extra amount of memory should be taken into account for garbage collection.

Parameters:
  • size (size_t) – Specify the amount of memory that should be taken into account for GC.
  • bRemove (bool) – True: the amount is removed from the system instead add.

Example

Foo::Foo() {
    _hnxgc_add_memory_pressure(size, false);
}
Foo::~Foo() {
    _hnxgc_add_memory_pressure(size, true);
}

// dynamic add/remove pressure at some other places
_hnxgc_add_memory_pressure(size, false);
...
_hnxgc_add_memory_pressure(size, true);
...
int _hnxgc_destruct_object(void *pObj)

Instruct the system to destruct the specified object safely. The system guarantees an object is destructed only once in its lifetime. It is safe to call this function multiple times on an object.

Parameters:
  • pObj (void*) – Specify a managed object
Returns:

always 0

Example

gcptr<Foo> p = gcnew Foo;

_hnxgc_destruct_object(p);
void _hnxgc_set_cycle_breaker(void * pObj)

Set an object where iGC start to reclaim dependence cycles. If the collector found some unreachable objects (involving reference cycles), and in OnReclaim calls they declared one or more cycles of dependences, then the system will first reclaimed those marked “cycle_breaker” by this function.

Parameters:
  • pObj (void*) – Specify a managed object
Returns:

(none)

void _hnxgc_set_nonrc(void * pObj)

Set an object to non-RC.

Parameters:
  • pObj (void*) – Specify a managed object
Returns:

(none)

Remarks

Once an object set to non-RC, reference counting operations would no longer perform on it. Thus this will improve the performance. The object will be collected only by GC, so don’t expect it be reclaimed immediately.

System configuration

void HXSystem_setTraceType(bool bEnable, HXLogType_t nType)

Call this function to enable (or disable) tracing log on a specified type events.

Parameters:
  • bEnable (bool) – Enable tracing log on the specified event(s)
  • nType (HXLogType_t) –

    Specify one or a combination of the following event types

    enum {
        kHXLogObjCClass,   // class level trace
        kHXLogMovingObj,   // move objects around
        kHXLogGCGeneral,   // general GC info
        kHXLogGCSpecial,   // special events of GC
        kHXLogObjLifeTime, // create, destruct and free
        kHXLogObjCRR,      // Objective-C retain/release
        kHXLogGarbageObjs, // GC collected objects
        kHXLogAll,         // all types
    };
    
Returns:

(none)

Example

HXSystem_setTraceType(true, kHXLogObjLifeTime | kHXLogObjCRR);

2013-05-19 02:42:26.559 iTestARCGC[8463:11303] HnxGC garbage collector v3.5-790 (release)
    for ObjC started, Copyright 2006-2012 (c) Harnix Technologies Inc., All Rights Reserved.
... 01:42:26.573 [11303] Create object 0x7bf9910(Foo)
... 01:42:26.575 [11303] Create object 0x9bb7f80(NSNotificationCenter)
... 01:42:26.576 [11303] Create object 0x7bddfa8(NSFileManager)
        ...   ...
... 01:42:26.581 [12d03] Destructing 0x9bbd2c0(__NSObserver)
... 01:42:26.581 [12d03] Destructing 0x9bbd290(__Block_layout)
... 01:42:26.581 [12d03] Free object 0x7bf9910(Foo)
bool HXSystem_configure(HXFeatureID_t nFeatureID, bool bEnable)

Call this function to enable (or disable) a specific feature

Parameters:
  • nFeatureID (HXFeatureID_t) –

    Specify a feature for enable or disable action

    enum {
        kHXFeature_DestructInLinearPool,    // default: false
        kHXFeature_ARCOptimizationLT5,      // default: false
        kHXFeature_WeakReferenceLT5,        // default: true
        kHXFeature_ManageCocoaArray,        // default: true
        kHXFeature_ManageCocoaCollection,   // default: true
        kHXFeature_ManageObjCBlock,         // default: true
        kHXFeature_SkipGCReclamation,       // default: false   change: safe
        kHXFeature_GraceTerminate,          // default: false
        kHXFeature_CocoaEnumUnsafe,         // default: false
        kHXFeature_AutoBlockCopy,           // default: true
        kHXFeature_DisableAutoGC,           // default: false   change: safe
    };
    
  • bEnable (bool) – Set true to enable the specified feature
Returns:

The previous status (true for enabled)

Remarks

Unless explicitly indicated features, you should only call HXSystem_configure in a user-defined function HXApplication_initialize, which is invoked by the system before iGC/HnxGC is fully initialized. This is because some features are only allowed to be setup once, and system has a default settings, you should notify the system what you want before the system chooses a default value.

Example

int HXApplication_initialize(void) {
    // Disable the feature of collecting Block Retain Cycles
    HXSystem_configure(kHXFeature_ManageObjCBlock, false);
    return 0;
}

Objective-C keywords & methods

Here are some keyword usage for MRRGC and ARCGC code. For ARCGC_C code, please reference Apple’s ARC documents as they are the same.

__weak

In MRRGC and ARCGC, it means unretained reference similar to ARC __unsafe_unretained. It can be used in declaration of instance variables and properties. For ARCGC, it can also be used in other non-ivar declarations to differentiate them from auto-retained variables.

__weak Foo * ivar;
@property __weak Foo * prop;
@property (nonatomic) __weak Foo * prop;
__weak Foo * foo;  // in ARCGC code
__autoweak

A auto-zeroing weak reference qualifier in ARCGC, like __weak in ARC. It can be used in ivar and non-ivar declarations.

// ARCGC code
__autoweak Foo * ivar;
@property __autoweak Foo * prop;
@property (nonatomic) __autoweak Foo * prop;
__autoweak Foo * foo;

For MRRGC, which does not support __autoweak keyword, you can use gcptr<T>::autoweak to do the same job.

__strong

A special qualifier only for properties declaration in Clang compiler.

@property (nonatomic) __strong Foo * prop;
@property (retain) Foo * prop;

A strong property will retain the object until the end of [dealloc] method even in the process of garbage collecting a cycle. This feature is provided by HnxGC reclamation ordering mechanism.

For those compilers cannot provide the __strong keyword, use @property (nonatomic, retain) to achieve the same effects as @property (nonatomic) __strong.

- (void)destruct

Send this message to an object to safely invoke [dealloc] method on the object once. The system guarantees [dealloc] of an object is invoked only once in its lifetime. It is safe to send this message multiple times to an object.

Foo * foo = [[Foo alloc] init];
...
[foo destruct]; // the system will invoke [dealloc] once
[foo release];

C++ helper functions

gcnew operator

gcnew

Use this macro to replace C++ new operator to create a managed object in heap. You can use gcnew to create an object or an array of objects in the similar way of C++ new operator.

see gcnew

The type can be any C++ types, including GC and non-GC class and struct and primitive types, like int, double, etc.

Example

gcptr<Foo> p = gcnew Foo;       // create an instance
gcptr<Foo> p = gcnew Foo(<constructor parameters>);     // with initial values
gcptr<Foo> p = gcnew Foo[100];  // create 100 instances of class Foo
gcptr<int> p = gcnew int[5];    // create an array of integer
gcptr<CGPoint> p = gcnew CGPoint;     // create an CGPoint

gcnew returns gcptr<T>::ret type, which can be assigned to other types of gcptr<>. If you do not assign the return value to a gcptr<>, the object will be reclaimed immediately after the statement.

If the constructor throw an exception, the newly created object will be reclaimed.

You can use gcnew in static initialization routine, i.e. in code executed before main().

You can use gcnew in contructor of an object. That is, gcnew can be nested into another execution of gcnew.

gcdelete

Usually you don’t need to use this as the system will automatically reclaim objects.

Use this operator to immediately destruct a “live” object which is referencec by other code or live objects. The system guarantees an object is destructed only once in its lifetime. It is safe to call this function multiple times on an object.

Example

gcptr<Foo> p = gcnew Foo;

gcdelete p;

Type casting

gcptr<T>::weak native_cast(T * p)

This casting function convert a native C/C++ pointer to its counter part GC smart pointer.

Parameters:
  • p (T*) – A native C/C++ pointer that the return value points to. The param p must points to a valid managed object, otherwise the program may crash.
Returns:

An GC smart pointer to p.

Example

Foo * pFoo = ...;
gcptr<Foo> foo = native_cast<Foo>(pFoo);
gcptr<T> interior_cast(gcptr<> obj, T * p)

This casting function converts a native C/C++ pointer p to effective reference gcptr<T>, with a control object obj provided represent the lifetime of p.

Parameters:
  • p (T*) – A native C/C++ pointer that the return value points to. The lifetime of p is controlled by a managed object obj. That is, p becomes inaccessible after obj is reclaimed.
  • obj (gcptr<>) – A managed object reference.
Returns:

An effective reference to p. It holds the obj and in turn prevent p from reclamation.

Remarks

The managed object obj is NOT required to be at the same allocated memory block with p, nor of the same type of p, i.e. obj could be any type, even an unknown type.

Example

class Foo {
    ...
    int num;
    ...
};
...
gcptr<Foo> foo = gcnew Foo;
gcptr<int> pNum = interior_cast<int>(foo, &foo.num);
foo = nullptr;
*pNum += 3;
gcptr<T> gc_static_cast(gcptr<U> p)

This casting function first uses C++ static_cast to convert p to T\ *, then use interior_cast to return a GC smart pointer.

Parameters:
  • p (gcptr<U>) – A GC smart pointer to managed object of type ‘U’
Returns:

A GC smart pointer casted to a different type ‘T’

Example

gcptr<Bar> bar = ...;
gcptr<Foo> foo = gc_static_cast<Foo>(pBar);
gcptr<T> gc_dynamic_cast(gcptr<U> p)

This casting function first uses C++ dynamic_cast to convert p to T\ *, then use interior_cast to return a GC smart pointer.

Parameters:
  • p (gcptr<U>) – A GC smart pointer to managed object of type ‘U’
Returns:

A GC smart pointer casted to a different type ‘T’

gcptr<T> gc_reinterpret_cast(gcptr<U> p)

This casting function first uses C++ reinterpret_cast to convert p to T\ *, then use interior_cast to return a GC smart pointer.

Parameters:
  • p (gcptr<U>) – A GC smart pointer to managed object of type ‘U’
Returns:

A GC smart pointer casted to a different type ‘T’

Class information

HNXGC_CLASSINFO

This GC class helper macro begins a CLASSINFO routine, which is called at the first-time use of this class to report locations of member pointers to the system.

Example

class Foo {
    ...
    HNXGC_CLASSINFO() {
        < report member pointers >
    }
};
HNXGC_CLASSINFO_MP(...)

This GC class helper macro should be used in CLASSINFO routine with variadic parameters of GC smart member pointers.

The maximum number of parameters is 16. You can call this function multiple times in CLASSINFO routine.

Example

HNXGC_CLASSINFO_MP(m_pFieldA, m_pFieldB, m_pFieldC);
HNXGC_CLASSINFO_MP_BEGIN
HNXGC_CLASSINFO_MP_END

This pair of GC class helper macros should be used in CLASSINFO routine to report unlimited number of GC smart member pointers

Example

HNXGC_CLASSINFO_MP_BEGIN
{m_pFieldA, m_pFieldB, m_pFieldC}
HNXGC_CLASSINFO_MP_END
HNXGC_CLASSINFO_CHAIN(obj)

This function should be used in CLASSINFO routine to report GC smart member pointers of an embedded object or a base object.

Example

HNXGC_CLASSINFO_CHAIN(&this->m_vBar);
HNXGC_CLASSINFO_CHAIN(static_cast<CBase*>(this));

C++ smart pointers

HnxGC defines a C++ template gcptr<T> smart pointer to be used as a substitution of C/C++ pointers to hold objects from reclamation.

You can omit the T type, e.g. gcptr<>, to define a smart pointer that matches any types, similar to C/C++ void *.

gcptr<> p;  // can hold any type of managed object

if (doFoo) {
    p = gcnew Foo;
} else {
    p = gcnew Bar;
}

You can provide a role specifier to gcptr<>, such as gcptr<>::in, gcptr<>::m, to define the behaviors of the smart pointer.

A generic pointer

type gcptr<T>

Use this type to define a GC smart pointer for C++ or Objective-C++ variable, including:

  • in-stack auto variable of function
  • global variable, static variable, C++ class variable
  • member variable of C++ class (cannot be used as Objective-C instance variable)
  • function parameters and return value (not recommended)

You can omit the type T to make a smart pointer accept any type of managed object.

Example

class Foo {
public:
    HNXGC_ENABLE(Foo)
    gcptr<Foo>  m_pFoo;     // member variable
    static gcptr<> c_pFoo;   // declare a class variable
};

gcptr<> g_pFoo = gcnew Foo;  // global variable

gcptr<Foo> Foo::c_pFoo = ...;   // define a class variable

int main() {
    static gcptr<Foo> s_pFoo = ...;     // static variable
    gcptr<Foo> p = ...;         // function in-stack auto variable
    gcptr<> p2 = ...;
    ...
}

Note

  1. The system allows gcptr<T> smart pointers implicitly convert to T* type pointer. But on the contrary, converting a T * pointer to a gcptr<T> smart pointer needs explicit casting. see: native_cast, etc.

  2. For a variadic paramters function, such as printf, you need explicitly specify (void*) or (T*) to convert gcptr<T> smart pointer first.

    gcptr<Foo> p = gcnew Foo;
    printf("obj: %p", (void*)p);
    

Basic pointers

type gcptr<T>::weak

Use this type to define a GC smart pointer that DOES NOT hold object. HnxGC does not perform any special action for assigment on this kind of smart pointers. Be careful using this kind of pointer as it may points to an invalid address. See below

gcptr<Foo>::weak w = gcnew Foo;

// Now, `w' points to an invalid address as object `Foo' is already reclaimed.

gcptr<T>::weak can be implicitly casted to gcptr<T>, or vice versa, while C/C++ type T * requires native_cast helper. Only assign managed object or nullptr to this kind of pointer.

type gcptr<T>::autoweak

An auto-zeroing weak reference. It DOES NOT hold object. When the target object is collected, the contents of the pointer is nullified. To avoid multi-threading racing condition, should only use specially methods of this smart pointer to access its contents.

Example

int main() {
    gcptr<Foo> p = gcnew Foo;

    gcptr<Foo>::autoweak w;

    w = p;

    printf("w:%p\n", (void*)w.Lock());      // output a valid address

    p = nullptr;

    printf("w:%p\n", (void*)w.Lock());      // output "zero"
}
type gcptr<T>::ref

Use this type to define a reference to GC smart pointer, so that changes to the reference will change the value of smart pointer it references. Similar to the concept of C++ reference type T&.

Example

int main() {
    gcptr<Foo> p;

    gcptr<Foo>::ref r = p;

    r = gcnew Foo;      // the value of `p' is changed.

    printf("p:%p\n", (void*)p);
}

Function parameters and return type

We recommend explicitly provide a role specifier for function paramters and return value.

type gcptr<T>::in

Passing a pointer as input parameter of a function. The caller of the function should keep the object alive until return from the function. This type internally equals to const gcptr<T>::weak. HnxGC deliberately disallow assign a new value to this kind of smart pointer to avoid error, because gcptr<T>::in cannot hold object. This is different from C/C++.

type gcptr<T>::out

The same as gcptr<T>::inout

type gcptr<T>::inout

These two types are the same. Should be used as output paramter of a function. The caller should pass a smart pointer variable as parameter to the function. If callee assigns a new value to the paramter, the value of caller’s variable is changed. This type internaly equals gcptr<T>::ref;

type gcptr<T>::ret

Use this type to declare return value of a function. This type is superior than generic gcptr<T>, because it moves ownship from callee to caller instead copy.

Example

gcptr<Foo>::ret CreateFooWithValues(
        gcptr<Bar>::in pBar, gcptr<Foo>::inout pFoo)
{
    gcptr<Foo> p = gcnew Foo;

    // pBar = ...   <--- this is disallowed deliberately

    p->m_pBar = pBar;

    pFoo = p;       // changes the caller's variable

    return p;
}

int main() {
    gcptr<Foo> p1;
    gcptr<Foo> p2;

    p1 = CreateFooWithValues(gcnew Bar, p2);
    // both `p1' and `p2' are changed.
}

Class member pointer

type gcptr<T>::m

Use this type to define a GC smart pointer for member variable of C++ class.

It automatically reports its location at first use of a GC class. You don’t need to define a CLASSINFO routine to report this kind of member pointers.

Example

class Foo {
public:
    HNXGC_ENABLE(Foo)

    gcptr<Foo>::m      foo;
    gcptr<>::m         obj;
};
type gcptr<T>::mm

Use this type to define a GC smart pointer for member variable of C++ class.

You need to define a CLASSINFO routine to report this kind of member pointers.

Example

class Foo {
public:
    HNXGC_ENABLE(Foo)

    gcptr<Foo>::mm      foo;
    gcptr<>::mm         obj;

    HNXGC_CLASSINFO() {     // required CLASSINFO routine
        HNXGC_CLASSINFO_MP(foo, obj);
    }
};

Pointers with explicit location

There are several gcptr<> types with explicit location specifiers, which indicate the location the pointer resides.

These smart pointers are a little bit faster than generic gcptr<T> (without location specifier).

type gcptr<T>::s

A GC smart pointer resides in stack

type gcptr<T>::g

A GC smart pointer resides at common region, like global variable, etc.

type gcptr<T>::sg

The pointer is either gcptr<T>::s or gcptr<T>::g

type gcptr<T>::gs

Synonym of gcptr<T>::sg

type gcptr<T>::r

Synonym of gcptr<T>::sg, also known as root-set pointer

Objective-C++ smart pointers and helpers

You can use C++ smart pointers and helpers in Manual Retain Release programming, and then your code no longer depends on a particular compiler, i.e. you can use iGC under almost any Objective-C++ compilers without applying any patches.

Root-set pointer

type gcptr<T>::oc

A Objective-C smart pointer that points to a cocoa object or nullptr (nil).

Remarks

For many cases, you can use generic gcptr<T> and its variants to hold Cocoa objects. But if you may assign a non-managed Cocoa object to a GC smart pointer, and RTTI is disabled or using a non-typed pointer gcptr<>, you need to use this type of pointer instead.

If you are not sure, always use this type for Cocoa objects.

Example

gcptr<NSDate> aObj = gcnew_i [[NSDate alloc] init];

gcptr<> aObj = gcnew_i [[NSDate alloc] init];

gcptr<NSDate>::oc aObj = gcnew_i [[NSDate alloc] init];

gcptr<>::oc aObj = gcnew_i [[NSDate alloc] init];

Instance variable pointer

type gcptr<T>::i

Use this type to define a GC smart pointer for Objective-C++ instance variable.

Example

@interface Foo : NSObject {
    gcptr<Foo>::i      foo;
    gcptr<>::i         obj;
}
@end

Helper macros and functions

gcnew_i

This helper function accepts a retained cocoa object, then passes the ownership as return value.

Example

// This MRR code will automatically send -[release] message after use
gcptr<NSDate>::oc aDate = gcnew_i [[NSDate alloc] init];
gcptr<>::oc_import(T * aObj)

Transfer the ownership of aObj, a retained cocoa object, into this GC smart pointer.

Parameters:
  • aObj (T*) – Specify a retained cocoa object.
Returns:

(none)

Example

gcptr<NSDate>::oc aObj;

aObj.oc_import([[NSDate alloc] init]);
T * gcptr<>::oc_export()

Transfer the ownership out of this GC smart pointer.

Returns:A retained C/C++ T* pointer.

Example

gcptr<NSDate>::oc aObj = gcnew_i [[NSDate alloc] init];

[aObj.oc_export() release];
T* oc_returnRetained(gcptr<T>::oc aObj)

This transfer the ownership from a gcptr to a retained “C” pointer.

Parameters:
  • aObj (gcptr<T>) – Specify a GC smart pointer for cocoa object
Returns:

A retained “C” pointer.

Example

// This is MRR code
- (Foo*)initWithNumber:(int)n
{
    gcptr<Foo>::oc foo = gcnew_i [[Foo alloc] init];
    foo->num = n;
    return oc_returnRetained(foo);
}
T* oc_returnAutoreleased(gcptr<T>::oc aObj)

This return an autoreleased object from a gcptr, through a oc_autoreleaseMethod macro. That is, -[autorelease] message is NOT sent to aObj immediately, instead it is sent by oc_autoreleaseMethod at function scrope.

Parameters:
  • aObj (gcptr<T>) – Specify a GC smart pointer for cocoa object
Returns:

An autoreleased “C” pointer.

Example

// this is MRR code
+ (Foo*)fooWithNumber:(int)n
{
    oc_autoreleaseMethod();
    gcptr<Foo>::oc foo = gcnew_i [[Foo alloc] init];
    foo->num = n;
    @autoreleasepool {
        // it is safe as `foo' is not autoreleased here,
        // but at ``oc_autoreleaseMethod()``.
        return oc_returnAutoreleased(foo);
    }
}

Linear Pool and Linear Pool Stack

Linear Pool functions

HXLinearPoolRef HXLinearPool_createInstance();

Synonym of HXLinearPool_createInstanceEx(kHXFeature_DestructInLinearPool), e.g. it equals HXLinearPool_createInstanceEx(false) by default, kHXFeature_DestructInLinearPool is false.

HXLinearPoolRef HXLinearPool_createInstanceEx(bool bHasDtor);

Create a Linear Pool

Parameters:
  • bHasDtor (bool) – true: The system will call destructors of objects in this pool.
Returns:

a reference to the newly created linear pool, which is a retained managed Objective-C object.

Remarks

After use of linear pool, you can: * send -[release] message to it, or * let gcptr<> to automatically drop RC of it.

void HXLinearPool_drain(HXLinearPoolRef pool, int action)

Drain a pool so that empty pool blocks (neither retained nor referenced by others) are eligible for collection.

Parameters:
  • pool (HXLinearPoolRef) – Specify the linear pool
  • action (enum) – see below values:
enum {
    LPD_Default = 0,    // let system balance performance and memory usage
    LPD_FullDrain,      // all empty pool blocks are eligible for collection
    LPD_Evacute         // live objects are evacuated, all pool blocks are reclaimed.
};

Linear Pool Stack functions

void HXLinearPoolStack_push()

Synonym of HXLinearPoolStack_pushWithPool(0), i.e. create a new linear pool and push it as the top of the current thread’s linear pool stack.

void HXLinearPoolStack_pushWithPool(HXLinearPoolRef pool)

Push a specific linear pool into current thread’s linear pool stack.

Parameters:
  • pool (HXLinearPoolRef) – Specify the linear pool. If pool is NULL, then a new linear pool is created and used.
Returns:

(none)

HXLinearPoolRef HXLinearPoolStack_top()

Return the top of the current thread’s linear pool stack.

Returns:the top linear pool of the linear pool stack. Usually this is the working pool, although you can create objects directly from any linear pool in linear pool stack.
void HXLinearPoolStack_pop()

Remove the top linear pool from the current thread’s linear pool stack.

Returns:(none)
void HXLinearPoolStack_drainTop(int action = LPD_Default)

Synonym of HXLinearPool_drain(HXLinearPoolStack_top(), action), i.e. drain the top of the current thread’s linear pool stack.

Create Objective-C objects

id HXLinearPool_createInstanceOfClass(Class cls)

Synonym of HXLinearPool_createInstanceOfClassEx(0, cls, 0), i.e. create an object from top of stacked linear pool with no extra bytes.

id HXLinearPool_createInstanceOfClassEx(HXLinearPoolRef pool, Class cls, size_t nExtraBytes)

Call this function to create an Objective-C object from specified linear pool.

Parameters:
  • pool (HXLinearPoolRef) – A weak reference to linear pool. If pool is NULL, then pool is set to HXLinearPoolStack_top().
  • cls (Class) – An Objective-C class
  • nExtraBytes (size_t) – Specify the extra bytes of object to be created.
Returns:

a reference to unretained new Objective-C object.

Example

@implementation Foo
+ (id)fooFromLinearPool {
    Foo * foo = HXLinearPool_createInstanceOfClass(self);

    // The contents of object `foo' is already zero-filled except
    // extra bytes, do additional instance initialization here
    // if necessary.
    ...

    return foo;
}
@end

The following NSObject category methods return unretained objects. The method names are comformed to Objective-C naming conventions.

+ (id)poolAlloc

Allocate an object from the top linear pool of the thread’s linear pool stack.

+ (id)poolAllocWithPool:(id)pool

Allocate an object from a specified linear pool.

+ (id)poolNew

Implemented as return [[self poolAlloc] poolInit];

- (id)poolInit

The default implementation is call -[init] method as return [self init];.

A user-defined class should override this method to do instance initialization if -[init] method is not compatible with -[poolInit]. For example, if the -[init] method releases the original self, and returns another retained object.

Example

@implementation Foo
- (id)poolInit {
    ... // do something similar in -[init]
}
@end

int main() {
    __unsafe_unretained Foo * foo = [[Foo poolAlloc] poolInit];

    // it is safe to use unretained `foo' before the linear pool is drained.
    ...

}

Create C++ objects

All these macros can optionally have constructor parameters followed, similar to C++ new operator.

pool_gcnew <cls>

This helper creates an object of specified GC class in the default linear pool.

Parameters:
  • cls – A GC enabled class.
Returns:

A unretained object created in linear pool.

Example

class Foo {
public:
    HNXGC_ENABLE(Foo)
    HNXGC_ENABLE_POOL           // enable allocation from linear pool
    ...
};

// create an instance of GC class from default pool
gcptr<Foo>::weak p = pool_gcnew Foo;
pool_gcnew_(type)

This helper creates an object of non-GC class or primitive type in the default linear pool.

Parameters:
  • type – Specify a type. Can be non-GC class or primitive type
Returns:

A unretained object created in linear pool.

Example

gcptr<sockaddr_in>::weak pAddr = pool_gcnew_(sockaddr_in);

gcptr<double>::weak pValue = pool_gcnew_(double) (123.45);
pool_gcnew_ex(pool, type, extraBytes)

This helper creates an object on specified linear pool with extra bytes.

Parameters:
  • pool (HXLinearPoolRef) – Specify a linear pool. Should not be NULL.
  • type

    Specify a type. Can be:

    • GC class
    • Non-GC class
    • primitive
  • extraBytes (size_t) – Specify the size of extra bytes.
Returns:

A unretained object created in linear pool.

Example

gcptr<CDataHead>::weak pData = pool_gcnew_ex
            (HXLinearPoolStack_top(), CDataHead, 512);

Special functions and helpers

Traverse routine

HNXGC_TRAVERSE

This GC class helper macro begins a TRAVERSE routine, which is called at garbage collection to report objects being referenced by this object.

Example

class Foo {
    ...
    HNXGC_TRAVERSE() {
        < report referenced objects >
    }
};
HNXGC_TRAVERSE_PTR(...)

This GC class helper macro should be used in TRAVERSE routine with variadic parameters of managed objects.

Example

HNXGC_TRAVERSE_PTR(m_pFieldA, m_pFieldB, m_pFieldC);
HNXGC_TRAVERSE_MULTIPLE_BEGIN
HNXGC_TRAVERSE_MULTIPLE_END

This pair of GC class helper macros should be used in TRAVERSE routine to report unlimited number of managed objects being referenced by this object.

Example

HNXGC_TRAVERSE_MULTIPLE_BEGIN
{m_pFieldA, m_pFieldB, m_pFieldC}
HNXGC_TRAVERSE_MULTIPLE_END
HNXGC_TRAVERSE_CHAIN(obj)

This function should be used in TRAVERSE routine to report managed objects being referenced by an embedded object or a base object.

Example

HNXGC_TRAVERSE_CHAIN(&this->m_vBar);
HNXGC_TRAVERSE_CHAIN(static_cast<CBase*>(this));
void _hnxgc_traverse_report_objc(void * caller, size_t n, void **ppObj)

This function is mainly used by Traverse routine to report objects referenced by the object.

Parameters:
  • caller (void*) – A oqaque value provided by Traverse routine.
  • n (size_t) – The size of ppObj array
  • ppObj (void**) – An array containing raw references to objects
Returns:

(none)

- (void)HNXGCTraverse: (void*)caller

This user-defined Objective-C instance method is called by system at GC traversal. This function should call _hnxgc_traverse_report_objc() to report objects being referenced by this object.

Parameters:
  • caller (void*) – The system passes in this opaque value to be used in _hnxgc_traverse_report_objc().
Returns:

(none)

Example

@interface Foo : NSObject {
    void * pObjs[15];
}
@end

@implementation Foo
- (void)HNXGCTraverse: (void *)caller {
    _hnxgc_traverse_report_objc(caller, 15, pObjs);
}
@end

OnReclaim routine

void * _hnxgc_onreclaim_change_depender(void *caller, void *pDepender)

This function is mainly used by OnReclaim routine to change depender, which is default to this.

Parameters:
  • caller (void*) – A oqaque value provided by OnReclaim routine.
  • pDepender (void*) – A managed object which requires specified others keep alive. default:this.
Returns:

(none)

void _hnxgc_onreclaim_declare(void * caller, size_t n, void **ppObj)

This function is mainly used by OnReclaim routine to declare objects depended by this object.

Parameters:
  • caller (void*) – A oqaque value provided by OnReclaim routine.
  • n (size_t) – The size of ppObj array
  • ppObj (void**) – An array containing raw references to objects
Returns:

(none)

HNXGC_ONRECLAIM

This GC class helper macro begins a OnReclaim routine, which is called just before collector takes action to reclaim objects.

Example

class Foo {
    ...
    HNXGC_ONRECLAIM() {
        < declare dependence to control reclamation ordering>
        < resurrection >
        ...
    }
};
HNXGC_DEPEND_DECLARE(...)

This GC class helper macro should be used in OnReclaim routine with variadic parameters of managed objects, which will not be destructed before this object.

Example

HNXGC_DEPEND_DECLARE(m_pFieldA, m_pFieldB, m_pFieldC);
HNXGC_DEPEND_MULTIPLE_BEGIN
HNXGC_DEPEND_MULTIPLE_END

This pair of GC class helper macros should be used in OnReclaim routine declare a set of managed objects, which will not be destructed before this object.

Example

HNXGC_DEPEND_MULTIPLE_BEGIN
{m_pFieldA, m_pFieldB, m_pFieldC}
HNXGC_DEPEND_MULTIPLE_END
- (void)HNXGCOnReclaim: (void*)caller

This GC class helper macro begins an OnReclaim routine, which is called just before collector takes action to reclaim objects.

Parameters:
  • caller (void*) – The system passes in this opaque value to be used in _hnxgc_traverse_report_objc().
Returns:

(none)

Example

@interface Foo : NSObject {
    id _obj;
}
@end

@implementation Foo
- (void)HNXGCOnReclaim: (void *)caller {
    _hnxgc_onreclaim_declare(caller, 1, &_obj);
}
@end