Esempio n. 1
0
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
  lua_State *L = (lua_State *)ud;
  int mode = L == NULL ? 0 : G(L)->egcmode;
  void *nptr;

  if (nsize == 0) {
    c_free(ptr);
    return NULL;
  }
  if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */
    luaC_fullgc(L);
  if(nsize > osize && L != NULL) {
#if defined(LUA_STRESS_EMERGENCY_GC)
    luaC_fullgc(L);
#endif
    if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize))
      return NULL;
  }
  nptr = (void *)c_realloc(ptr, nsize);
  if (nptr == NULL && L != NULL && (mode & EGC_ON_ALLOC_FAILURE)) {
    luaC_fullgc(L); /* emergency full collection. */
    nptr = (void *)c_realloc(ptr, nsize); /* try allocation again */
  }
  return nptr;
}
Esempio n. 2
0
File: lmem.c Progetto: guodawei/lua
/*
** In case of allocation fail, this function will call the GC to try
** to free some memory and then try the allocation again.
** (It should not be called when shrinking a block, because then the
** interpreter may be in the middle of a collection step.)
*/
static void *tryagain (lua_State *L, void *block,
                       size_t osize, size_t nsize) {
  global_State *g = G(L);
  if (ttisnil(&g->nilvalue)) {  /* is state fully build? */
    luaC_fullgc(L, 1);  /* try to free some memory... */
    return (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
  }
  else return NULL;  /* cannot free any memory without a full state */
}
Esempio n. 3
0
/*
** generic allocation routine.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
  void *newblock;
  global_State *g = G(L);
  size_t realosize = (block) ? osize : 0;
  lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS)
  if (nsize > realosize && g->gcrunning)
    luaC_fullgc(L, 1);  /* force a GC whenever possible */
#endif
  newblock = (*g->frealloc)(g->ud, block, osize, nsize);
  if (newblock == NULL && nsize > 0) {
    api_check(L, nsize > realosize,
                 "realloc cannot fail when shrinking a block");
    if (g->gcrunning) {
      luaC_fullgc(L, 1);  /* try to free some memory... */
      newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
    }
    if (newblock == NULL)
      luaD_throw(L, LUA_ERRMEM);
  }
  lua_assert((nsize == 0) == (newblock == NULL));
  g->GCdebt = (g->GCdebt + nsize) - realosize;
#if defined(TRACEMEM)
  { /* auxiliary patch to monitor garbage collection.
    ** To plot, gnuplot with following command:
    ** plot TRACEMEM using 1:2 with lines, TRACEMEM using 1:3 with lines
    */
    static unsigned long total = 0;  /* our "time" */
    static FILE *f = NULL;  /* output file */
    total++;  /* "time" always grows */
    if ((total % 200) == 0) {
      if (f == NULL) f = fopen(TRACEMEM, "w");
      fprintf(f, "%lu %u %d %d\n", total,
              gettotalbytes(g), g->GCdebt, g->gcstate * 10000);
    }
  }
#endif

  return newblock;
}
Esempio n. 4
0
/**
 * 调用此函数前,参数都经过检查, 保证了分配的内存块不会过大;
 * 
 * 创建对象的函数 luaM_newobject 也调用此函数(lmem.h):
 *  #define luaM_newobject(L,tag,s)	luaM_realloc_(L, NULL, tag, (s))
 *  
 *  nsize 为 0 表示释放内存
 *  #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
 *  
 *  内部调用 g->frealloc 来重新分配内存
 */
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
  void *newblock;
  global_State *g = G(L);
  size_t realosize = (block) ? osize : 0;
  lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS)
  if (nsize > realosize && g->gcrunning)
    luaC_fullgc(L, 1);  /* force a GC whenever possible */
#endif
  newblock = (*g->frealloc)(g->ud, block, osize, nsize);
  if (newblock == NULL && nsize > 0) {
    api_check( nsize > realosize,
                 "realloc cannot fail when shrinking a block");
    luaC_fullgc(L, 1);  /* try to free some memory... */
    newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
    if (newblock == NULL)
      luaD_throw(L, LUA_ERRMEM);
  }
  lua_assert((nsize == 0) == (newblock == NULL));
  g->GCdebt = (g->GCdebt + nsize) - realosize;
  return newblock;
}
Esempio n. 5
0
static void generationalcollection (lua_State *L) {
  global_State *g = G(L);
  if (g->lastmajormem == 0) {  /* signal for another major collection? */
    luaC_fullgc(L, 0);  /* perform a full regular collection */
    g->lastmajormem = gettotalbytes(g);  /* update control */
  }
  else {
    luaC_runtilstate(L, ~bitmask(GCSpause));  /* run complete cycle */
    luaC_runtilstate(L, bitmask(GCSpause));
    if (gettotalbytes(g) > g->lastmajormem/100 * g->gcmajorinc)
      g->lastmajormem = 0;  /* signal for a major collection */
  }
  luaE_setdebt(g, stddebt(g));
}
Esempio n. 6
0
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
  lua_State *L = (lua_State *)ud;
  void *nptr;
  if (nsize == 0) {
    free(ptr);
    return NULL;
  }
  if(nsize > osize && L != NULL) {
    if(G(L)->memlimit > 0 && l_check_memlimit(L, nsize - osize))
      return NULL;
  }
  nptr = realloc(ptr, nsize);
  if (nptr == NULL && L != NULL) {
    luaC_fullgc(L); /* emergency full collection. */
    nptr = realloc(ptr, nsize); /* try allocation again */
  }
  return nptr;
}
Esempio n. 7
0
static void generationalcollection (lua_State *L) {
	global_State *g = G(L);
	lua_assert(g->gcstate == GCSpropagate);
	if (g->GCestimate == 0) {  /* signal for another major collection? */
	luaC_fullgc(L, 0);  /* perform a full regular collection */
	g->GCestimate = gettotalbytes(g);  /* update control */
	}
	else {
	lu_mem estimate = g->GCestimate;
	luaC_runtilstate(L, bitmask(GCSpause));  /* run complete (minor) cycle */
	g->gcstate = GCSpropagate;  /* skip restart */
	if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
		g->GCestimate = 0;  /* signal for a major collection */
	else
		g->GCestimate = estimate;  /* keep estimate from last major coll. */

	}
	setpause(g, gettotalbytes(g));
	lua_assert(g->gcstate == GCSpropagate);
}