Skip to content
Permalink
Browse files
* Add LUA_C41FASTREF.
  • Loading branch information
jjensen committed Jan 14, 2011
1 parent b0e54d7 commit f8bef58
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 0 deletions.
@@ -51,6 +51,18 @@ static TValue *index2addr (lua_State *L, int idx) {
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
#if LUA_C41FASTREF_SUPPORT
else if (idx <= LUA_C42FASTREFNIL) {
struct c42_lua_Ref* refobj;
if (idx == LUA_C42FASTREFNIL)
return &G(L)->c42RefNilValue;
idx = -idx + LUA_C42FASTREFNIL - 1;
refobj = &G(L)->c42refArray[idx];
if (0 <= idx && idx < G(L)->c42refSize && refobj->st == LUA_C42FASTREF_LOCK)
return &refobj->o;
return &G(L)->c42RefNilValue;
}
#endif /* LUA_C41FASTREF_SUPPORT */
else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry;
else { /* upvalues */
@@ -1214,3 +1226,84 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
luaC_objbarrier(L, f1, *up2);
}



#if LUA_C41FASTREF_SUPPORT

static void growfastref (lua_State *L) {
global_State *g = G(L);
int origsize = g->c42refSize;
int c42refFree;
struct c42_lua_Ref* c42refArray;
int i;
luaM_growvector(L, g->c42refArray, g->c42refSize, g->c42refSize, struct c42_lua_Ref,
MAX_INT, "reference table overflow");

c42refFree = g->c42refFree;
i = g->c42refSize - 1;
c42refArray = &g->c42refArray[i];
for (; i >= origsize; --i, --c42refArray) {
c42refArray->st = c42refFree;
c42refFree = i;
}
g->c42refFree = c42refFree;
}

LUA_API int lua_c41getfastref (lua_State *L, int ref) {
struct c42_lua_Ref* refobj;
if (ref == LUA_C42FASTREFNIL) {
ttype(L->top) = LUA_TNIL;
api_incr_top(L);
return 1;
}
ref = -ref + LUA_C42FASTREFNIL - 1;
refobj = &G(L)->c42refArray[ref];
if (0 <= ref && ref < G(L)->c42refSize && refobj->st == LUA_C42FASTREF_LOCK)
*L->top = refobj->o;
else
return 0;
api_incr_top(L);
return 1;
}


LUA_API int lua_c41fastrefindex (lua_State *L, int idx) {
int ref;
TValue* value = index2addr(L, idx);
if (ttype(value) == LUA_TNIL)
return LUA_C42FASTREFNIL;
else {
global_State *g = G(L);
struct c42_lua_Ref* refobj;
if (g->c42refFree == LUA_C42FASTREF_NONEXT) { /* is there a free place? */
growfastref(L);
value = index2addr(L, idx);
}
ref = g->c42refFree;
refobj = &g->c42refArray[ref];
g->c42refFree = refobj->st;
refobj->o = *value;
refobj->st = LUA_C42FASTREF_LOCK;
}
return LUA_C42FASTREFNIL - 1 - ref;
}


LUA_API int lua_c41fastref (lua_State *L) {
int ref = lua_c41fastrefindex(L, -1);
lua_pop(L, 1);
return ref;
}


LUA_API void lua_c41fastunref (lua_State *L, int ref) {
ref = -ref + LUA_C42FASTREFNIL - 1;
if (ref >= 0) {
global_State* g = G(L);
luai_apicheck(L, ref < g->c42refSize && g->c42refArray[ref].st < 0); //, "invalid ref");
g->c42refArray[ref].st = g->c42refFree;
g->c42refFree = ref;
}
}

#endif /* LUA_C41FASTREF_SUPPORT */
@@ -847,13 +847,28 @@ void luaC_freeallobjects (lua_State *L) {
}


#if LUA_C41FASTREF_SUPPORT
static void marklock (global_State *g)
{
int i;
for (i=0; i<g->c42refSize; i++) {
if (g->c42refArray[i].st == LUA_C42FASTREF_LOCK)
markvalue(g, &g->c42refArray[i].o);
}
}
#endif /* LUA_C41FASTREF_SUPPORT */


static void atomic (lua_State *L) {
global_State *g = G(L);
lua_assert(!iswhite(obj2gco(g->mainthread)));
markobject(g, L); /* mark running thread */
/* registry and global metatables may be changed by API */
markvalue(g, &g->l_registry);
markmt(g); /* mark basic metatables */
#if LUA_C41FASTREF_SUPPORT
marklock(g); /* mark locked objects */
#endif /* LUA_C41FASTREF_SUPPORT */
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
/* traverse objects caught by write barrier and by 'remarkupvals' */
@@ -260,6 +260,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->gcpause = LUAI_GCPAUSE;
g->gcmajorinc = LUAI_GCMAJOR;
g->gcstepmul = LUAI_GCMUL;
#if LUA_C41FASTREF_SUPPORT
g->c42refArray = NULL;
g->c42refSize = 0;
g->c42refFree = LUA_C42FASTREF_NONEXT;
setnilvalue(&g->c42RefNilValue);
#endif /* LUA_C41FASTREF_SUPPORT */
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
@@ -39,6 +39,23 @@
*/


#if LUA_C41FASTREF_SUPPORT

/*
** marks for Reference array
*/
#define LUA_C42FASTREF_NONEXT -1 /* to end the free list */
#define LUA_C42FASTREF_LOCK -4


struct c42_lua_Ref {
TValue o;
int st; /* can be LUA_C42FASTREF_LOCK, LUA_C42FASTREF_NONEXT, or next (for free list) */
};

#endif /* LUA_C41FASTREF_SUPPORT */


struct lua_longjmp; /* defined in ldo.c */


@@ -144,6 +161,12 @@ typedef struct global_State {
TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
#if LUA_C41FASTREF_SUPPORT
struct c42_lua_Ref *c42refArray; /* locked objects */
int c42refSize; /* size of c42refArray */
int c42refFree; /* list of free positions in c42refArray */
TValue c42RefNilValue;
#endif /* LUA_C41FASTREF_SUPPORT */
} global_State;


@@ -414,6 +414,18 @@ struct lua_Debug {
/* }====================================================================== */


#if LUA_C41FASTREF_SUPPORT
/* pre-defined references */
#define LUA_C42FASTREFNIL (-199999999)

LUA_API int lua_c41getfastref (lua_State *L, int ref);
LUA_API int lua_c41fastrefindex (lua_State *L, int idx);
LUA_API int lua_c41fastref (lua_State *L);
LUA_API void lua_c41fastunref (lua_State *L, int ref);

#endif /* LUA_C41FASTREF_SUPPORT */


/******************************************************************************
* Copyright (C) 1994-2010 Lua.org, PUC-Rio. All rights reserved.
*
@@ -12,6 +12,11 @@
#include <stddef.h>


#if !defined(LUA_C41FASTREF_SUPPORT)
#define LUA_C41FASTREF_SUPPORT 1
#endif /* LUA_C41FASTREF_SUPPORT */


/*
** ==================================================================
** Search for "@@" to find all configurable definitions.

0 comments on commit f8bef58

Please sign in to comment.