Exemplo n.º 1
0
void GfxPorts::processEngineHunkList(WorklistManager &wm) {
	for (PortList::const_iterator it = _windowList.begin(); it != _windowList.end(); ++it) {
		if ((*it)->isWindow()) {
			Window *wnd = ((Window *)*it);
			wm.push(wnd->hSaved1);
			wm.push(wnd->hSaved2);
		}
	}
}
Exemplo n.º 2
0
Arquivo: gc.cpp Projeto: 86400/scummvm
static void processWorkList(SegManager *segMan, WorklistManager &wm, const Common::Array<SegmentObj *> &heap) {
	SegmentId stackSegment = segMan->findSegmentByType(SEG_TYPE_STACK);
	while (!wm._worklist.empty()) {
		reg_t reg = wm._worklist.back();
		wm._worklist.pop_back();
		if (reg.getSegment() != stackSegment) { // No need to repeat this one
			debugC(kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg));
			if (reg.getSegment() < heap.size() && heap[reg.getSegment()]) {
				// Valid heap object? Find its outgoing references!
				wm.pushArray(heap[reg.getSegment()]->listAllOutgoingReferences(reg));
			}
		}
	}
}
Exemplo n.º 3
0
reg_t_hash_map *find_all_used_references(EngineState *s) {
	SegManager *sm = s->seg_manager;
	reg_t_hash_map *normal_map = NULL;
	WorklistManager wm;
	uint i;

	// Initialise
	// Init: Registers
	wm.push(s->r_acc);
	wm.push(s->r_prev);
	// Init: Value Stack
	// We do this one by hand since the stack doesn't know the current execution stack
	{
		ExecStack &xs = s->_executionStack.back();
		reg_t *pos;

		for (pos = s->stack_base; pos < xs.sp; pos++)
			wm.push(*pos);
	}

	debugC(2, kDebugLevelGC, "[GC] -- Finished adding value stack");

	// Init: Execution Stack
	Common::List<ExecStack>::iterator iter;
	for (iter = s->_executionStack.begin();
	     iter != s->_executionStack.end(); ++iter) {
		ExecStack &es = *iter;

		if (es.type != EXEC_STACK_TYPE_KERNEL) {
			wm.push(es.objp);
			wm.push(es.sendp);
			if (es.type == EXEC_STACK_TYPE_VARSELECTOR)
				wm.push(*(es.getVarPointer(s)));
		}
	}

	debugC(2, kDebugLevelGC, "[GC] -- Finished adding execution stack");

	// Init: Explicitly loaded scripts
	for (i = 1; i < sm->_heap.size(); i++)
		if (sm->_heap[i]
		        && sm->_heap[i]->getType() == MEM_OBJ_SCRIPT) {
			Script *script = (Script *)sm->_heap[i];

			if (script->lockers) { // Explicitly loaded?
				// Locals, if present
				wm.push(make_reg(script->locals_segment, 0));

				// All objects (may be classes, may be indirectly reachable)
				for (uint obj_nr = 0; obj_nr < script->_objects.size(); obj_nr++) {
					wm.push(script->_objects[obj_nr].pos);
				}
			}
		}

	debugC(2, kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set\n");

	// Run Worklist Algorithm
	while (!wm._worklist.empty()) {
		reg_t reg = wm._worklist.back();
		wm._worklist.pop_back();
		if (reg.segment != s->stack_segment) { // No need to repeat this one
			debugC(2, kDebugLevelGC, "[GC] Checking %04x:%04x\n", PRINT_REG(reg));
			if (reg.segment < sm->_heap.size() && sm->_heap[reg.segment])
				sm->_heap[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
		}
	}

	// Normalise
	normal_map = normalise_hashmap_ptrs(sm, wm._map);

	return normal_map;
}
Exemplo n.º 4
0
Arquivo: gc.cpp Projeto: 86400/scummvm
AddrSet *findAllActiveReferences(EngineState *s) {
	assert(!s->_executionStack.empty());

	WorklistManager wm;

	// Initialize registers
	wm.push(s->r_acc);
	wm.push(s->r_prev);

	// Initialize value stack
	// We do this one by hand since the stack doesn't know the current execution stack
	Common::List<ExecStack>::const_iterator iter = s->_executionStack.reverse_begin();

	// Skip fake kernel stack frame if it's on top
	if ((*iter).type == EXEC_STACK_TYPE_KERNEL)
		--iter;

	assert((iter != s->_executionStack.end()) && ((*iter).type != EXEC_STACK_TYPE_KERNEL));

	const StackPtr sp = iter->sp;

	for (reg_t *pos = s->stack_base; pos < sp; pos++)
		wm.push(*pos);

	debugC(kDebugLevelGC, "[GC] -- Finished adding value stack");

	// Init: Execution Stack
	for (iter = s->_executionStack.begin();
	     iter != s->_executionStack.end(); ++iter) {
		const ExecStack &es = *iter;

		if (es.type != EXEC_STACK_TYPE_KERNEL) {
			wm.push(es.objp);
			wm.push(es.sendp);
			if (es.type == EXEC_STACK_TYPE_VARSELECTOR)
				wm.push(*(es.getVarPointer(s->_segMan)));
		}
	}

	debugC(kDebugLevelGC, "[GC] -- Finished adding execution stack");

	const Common::Array<SegmentObj *> &heap = s->_segMan->getSegments();
	uint heapSize = heap.size();

	for (uint i = 1; i < heapSize; i++) {
		if (heap[i]) {
			// Init: Explicitly loaded scripts
			if (heap[i]->getType() == SEG_TYPE_SCRIPT) {
				Script *script = (Script *)heap[i];

				if (script->getLockers()) { // Explicitly loaded?
					wm.pushArray(script->listObjectReferences());
				}
			}

#ifdef ENABLE_SCI32
			// Init: Explicitly opted-out bitmaps
			else if (heap[i]->getType() == SEG_TYPE_BITMAP) {
				BitmapTable *bt = static_cast<BitmapTable *>(heap[i]);

				for (uint j = 0; j < bt->_table.size(); j++) {
					if (bt->_table[j].data && bt->_table[j].data->getShouldGC() == false) {
						wm.push(make_reg(i, j));
					}
				}
			}
#endif
		}
	}

	debugC(kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set");

	processWorkList(s->_segMan, wm, heap);

	if (g_sci->_gfxPorts)
		g_sci->_gfxPorts->processEngineHunkList(wm);

	return normalizeAddresses(s->_segMan, wm._map);
}
Exemplo n.º 5
0
void add_outgoing_refs(void *refcon, reg_t addr) {
	WorklistManager *wm = (WorklistManager *)refcon;
	wm->push(addr);
}