static Handle make_handle_entry(TaskData *taskData) { unsigned handle_no; Handle str_token; bool have_collected = false; do { for(handle_no = 0; handle_no < maxHandleTab && handleTable[handle_no].token != 0; handle_no++); /* Check we have enough space. */ if (handle_no >= maxHandleTab) { /* No space. */ /* See if we have unreferenced streams. */ if (! have_collected) { FullGC(taskData); have_collected = true; } else /* No space - expand vector. */ { POLYUNSIGNED oldMax = maxHandleTab; maxHandleTab += maxHandleTab/2; void *p = realloc(handleTable, maxHandleTab*sizeof(HANDLETAB)); // If there's insufficient memory leave the old table. if (p == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM); handleTable = (PHANDLETAB)p; /* Clear the new space. */ memset(handleTable+oldMax, 0, (maxHandleTab-oldMax)*sizeof(HANDLETAB)); } } } while (handle_no >= maxHandleTab); str_token = alloc_and_save(taskData, 1, F_BYTE_OBJ); STREAMID(str_token) = handle_no; /* Clear the entry then set the token. */ memset(&handleTable[handle_no], 0, sizeof(HANDLETAB)); handleTable[handle_no].token = DEREFWORDHANDLE(str_token); return str_token; }
Handle SaveState(TaskData *taskData, Handle args) { TCHAR fileNameBuff[MAXPATHLEN]; POLYUNSIGNED length = Poly_string_to_C(DEREFHANDLE(args)->Get(0), fileNameBuff, MAXPATHLEN); if (length > MAXPATHLEN) raise_syscall(taskData, "File name too long", ENAMETOOLONG); // The value of depth is zero for top-level save so we need to add one for hierarchy. unsigned newHierarchy = get_C_unsigned(taskData, DEREFHANDLE(args)->Get(1)) + 1; if (newHierarchy > hierarchyDepth+1) raise_fail(taskData, "Depth must be no more than the current hierarchy plus one"); // Request a full GC first. The main reason is to avoid running out of memory as a // result of repeated saves. Old export spaces are turned into local spaces and // the GC will delete them if they are completely empty FullGC(taskData); SaveRequest request(fileNameBuff, newHierarchy); processes->MakeRootRequest(taskData, &request); if (request.errorMessage) raise_syscall(taskData, request.errorMessage, request.errCode); return SAVE(TAGGED(0)); }