Hi all,

Since cleaning up the accessors to my native Sprite and Vector
classes, I've noticed that code as simple as the following triggers
the memory scavenging quite frequently (about every 2s, taking around
5ms on a debug build):

var my_sprite = new Sprite(); // native class
while (1) {
    var pos = my_sprite.pos; // pos is actually a native vector type
}

It doesn't really affect performance greatly at the moment or leak
handles (from what I can tell at least), but it's something that
doesn't happen if I simply used Sprite/Vector classes that are
completely defined in Javascript instead of wrapped around native
types. Should it be expected that accessors which return proxies to
native types will always add additional memory? From what I can tell,
I really have no choice since I need to new up an External handle as
well as the proxy object. A tight loop like my previous example is a
little unrealistic, but I'm planning on using this in a 30hz game
loop. It makes me wonder if I need to really limit these type of
accesses.

I've added some of my code as a reference.

Thanks
-Dave

// Sprite accessor function for the vector position ("pos")
Handle<Value> GetPos( Local<String>, const AccessorInfo& info )
{
    CSprite* pSprite = static_cast<CSprite*>( info.This()-
>GetPointerFromInternalField(0) );
    assert(pSprite);

    Handle<Function> vector_ctor =
CV8FunctionTemplates::VectorTemplate->GetFunction();

    Handle<External> external = External::New(pSprite->GetPos());
    Handle<Value> args[] = {external};

    Handle<Object> pos_obj = vector_ctor->NewInstance(1, args);

    pos_obj->SetInternalField(1, info.This());

    return pos_obj;
}

// Ctor function for a native vector type
Handle<Value> CreateVector(const Arguments& args)
{
    if ( !args.IsConstructCall() )
    {
        ThrowException( String::New("Invalid use of Vector
constructor!") );
    }

    Handle<External> external;

    // If there's already a vector, just wrap around it
    // (eg: an accessor call wraps around a pre-existing vector)
    if (args[0]->IsExternal())
    {
        external = Handle<External>::Cast(args[0]);
    }
    // Otherwise, create a brand new vector
    else
    {
        CVector* v = new CVector();
        Persistent<External> pexternal =
Persistent<External>::New( External::New(v) );
        pexternal.MakeWeak(v, DestroyVector);
        external = pexternal;

        V8::AdjustAmountOfExternalAllocatedMemory(sizeof(CVector));
    }

    args.This()->SetInternalField(0, external);

    return args.This();
}

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to