コード例 #1
0
void
OMR_MethodDictionary::formatEntryProperties(const OMR_MethodDictionaryEntry *entry, char **str) const
{
	if (_numProperties == 0) {
		*str = NULL;
	} else {
		OMRPORT_ACCESS_FROM_OMRVM(_vm);
		size_t buflen = _numProperties; /* space between each property + nul-terminator, might include some extra if we have nulls */
		for (size_t i = 0; i < _numProperties; ++i) {
			if (NULL != entry->propertyValues[i]) {
				buflen += strlen(entry->propertyValues[i]);
			}
		}

		char *buf = (char *)omrmem_allocate_memory(buflen, OMRMEM_CATEGORY_OMRTI);
		uintptr_t bufUsed = 0;
		if (NULL != buf) {
			bufUsed += omrstr_printf(buf, (uintptr_t)buflen, "%s", entry->propertyValues[0]);
			for (size_t i = 1; i < _numProperties; ++i) {
				if (NULL != entry->propertyValues[i]) {
					bufUsed += omrstr_printf(buf + bufUsed, (uintptr_t)buflen - bufUsed, " %s", entry->propertyValues[i]);
				}
			}
		}
		*str = buf;
	}
}
コード例 #2
0
ファイル: VerboseWriter.cpp プロジェクト: LinHu2016/omr
bool
MM_VerboseWriter::initialize(MM_EnvironmentBase* env)
{
	OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary());
	MM_GCExtensionsBase* ext = env->getExtensions();

	/* Initialize _header */
	const char* version = omrgc_get_version(env->getOmrVM());
	/* The length is -2 for the "%s" in VERBOSEGC_HEADER and +1 for '\0' */
	uintptr_t headerLength = strlen(version) + strlen(VERBOSEGC_HEADER) - 1;
	_header = (char*)ext->getForge()->allocate(sizeof(char) * headerLength, OMR::GC::AllocationCategory::DIAGNOSTIC, OMR_GET_CALLSITE());
	if (NULL == _header) {
		return false;
	}
	omrstr_printf(_header, headerLength, VERBOSEGC_HEADER, version);

	/* Initialize _footer */
	uintptr_t footerLength = strlen(VERBOSEGC_FOOTER) + 1;
	_footer = (char*)ext->getForge()->allocate(sizeof(char) * footerLength, OMR::GC::AllocationCategory::DIAGNOSTIC, OMR_GET_CALLSITE());
	if (NULL == _footer) {
		ext->getForge()->free(_header);
		return false;
	}
	omrstr_printf(_footer, footerLength, VERBOSEGC_FOOTER);
	
	return true;
}
コード例 #3
0
ファイル: testHelpers.cpp プロジェクト: dinogun/omr
/**
 * Removes a directory by recursively removing sub-directory and files.
 *
 * @param[in] portLibrary The port library
 * @param[in] directory to clean up
 *
 * @return void
 */
void
deleteControlDirectory(struct OMRPortLibrary *portLibrary, char *baseDir)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portLibrary);
	struct J9FileStat buf;

	omrfile_stat(baseDir, (uint32_t)0, &buf);

	if (buf.isDir != 1) {
		omrfile_unlink(baseDir);
	} else {
		char mybaseFilePath[EsMaxPath];
		char resultBuffer[EsMaxPath];
		uintptr_t rc, handle;

		omrstr_printf(mybaseFilePath, EsMaxPath, "%s", baseDir);
		rc = handle = omrfile_findfirst(mybaseFilePath, resultBuffer);
		while ((uintptr_t)-1 != rc) {
			char nextEntry[EsMaxPath];
			/* skip current and parent dir */
			if (resultBuffer[0] == '.') {
				rc = omrfile_findnext(handle, resultBuffer);
				continue;
			}
			omrstr_printf(nextEntry, EsMaxPath, "%s/%s", mybaseFilePath, resultBuffer);
			deleteControlDirectory(OMRPORTLIB, nextEntry);
			rc = omrfile_findnext(handle, resultBuffer);
		}
		if (handle != (uintptr_t)-1) {
			omrfile_findclose(handle);
		}
		omrfile_unlinkdir(mybaseFilePath);
	}
}
コード例 #4
0
/**
 * Initialize a new lock object.
 * A lock must be initialized before it may be used.
 *
 * @param env
 * @param options
 * @param name Lock name
 * @return TRUE on success
 * @note Creates a store barrier.
 */
bool
MM_LightweightNonReentrantLock::initialize(MM_EnvironmentBase *env, ModronLnrlOptions *options, const char * name)
{
	OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary());

	/* initialize variables in case constructor was not called */
	_initialized = false;
	_tracing = NULL;
	_extensions = env->getExtensions();

	if (NULL != _extensions) {
		J9Pool* tracingPool = _extensions->_lightweightNonReentrantLockPool;
		if (NULL != tracingPool) {
			omrthread_monitor_enter(_extensions->_lightweightNonReentrantLockPoolMutex);
			_tracing = (J9ThreadMonitorTracing *)pool_newElement(tracingPool);
			omrthread_monitor_exit(_extensions->_lightweightNonReentrantLockPoolMutex);

			if (NULL == _tracing) {
				goto error_no_memory;
			}
			_tracing->monitor_name = NULL;

			if (NULL != name) {
				uintptr_t length = omrstr_printf(NULL, 0, "[%p] %s", this, name) + 1;
				if (length > MAX_LWNR_LOCK_NAME_SIZE) {
					goto error_no_memory;
				}
				_tracing->monitor_name = _nameBuf;
				if (NULL == _tracing->monitor_name) {
					goto error_no_memory;
				}
				omrstr_printf(_tracing->monitor_name, length, "[%p] %s", this, name);
			}
		}
	}

#if defined(OMR_ENV_DATA64)
	if(0 != (((uintptr_t)this) % sizeof(uintptr_t))) {
		omrtty_printf("GC FATAL: LWNRL misaligned.\n");
		abort();
	}
#endif

#if defined(J9MODRON_USE_CUSTOM_SPINLOCKS)

	_initialized = omrgc_spinlock_init(&_spinlock) ? false : true;

	_spinlock.spinCount1 = options->spinCount1;
	_spinlock.spinCount2 = options->spinCount2;
	_spinlock.spinCount3 = options->spinCount3;
#else /* J9MODRON_USE_CUSTOM_SPINLOCKS */
	_initialized = MUTEX_INIT(_mutex) ? true : false;
#endif /* J9MODRON_USE_CUSTOM_SPINLOCKS */

	return _initialized;

error_no_memory:
	return false;
}
コード例 #5
0
uintptr_t
MM_VerboseHandlerOutput::getTagTemplate(char *buf, uintptr_t bufsize, uintptr_t id, const char *type, uintptr_t contextId, uint64_t timeus, uint64_t wallTimeMs)
{
	OMRPORT_ACCESS_FROM_OMRVM(_omrVM);
	uintptr_t bufPos = 0;
	bufPos += omrstr_printf(buf, bufsize, "id=\"%zu\" type=\"%s\" timems=\"%llu.%03.3llu\" contextid=\"%zu\" timestamp=\"", id, type, timeus / 1000, timeus % 1000, contextId);
	bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_PRE_MS, wallTimeMs);
	bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "%03llu", wallTimeMs % 1000);
	bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_POST_MS, wallTimeMs);
	bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "\"");

	return bufPos;
}
コード例 #6
0
uintptr_t
MM_VerboseHandlerOutput::getTagTemplate(char *buf, uintptr_t bufsize, uint64_t wallTimeMs)
{
	OMRPORT_ACCESS_FROM_OMRVM(_omrVM);
	uintptr_t bufPos = 0;
	bufPos += omrstr_printf(buf, bufsize, "timestamp=\"");
	bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_PRE_MS, wallTimeMs);
	bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "%03llu", wallTimeMs % 1000);
	bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_POST_MS, wallTimeMs);
	bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "\"");

	return bufPos;
}
コード例 #7
0
ファイル: GCConfigTest.cpp プロジェクト: is00hcw/omr
ObjectEntry *
GCConfigTest::createObject(const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);
	ObjectEntry *objEntry = NULL;

	char *objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM);
	if (NULL == objName) {
		omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__);
		goto done;
	}
	omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow);

	objEntry = find(objName);
	if (NULL != objEntry) {
#if defined(OMRGCTEST_DEBUG)
		omrtty_printf("Found object %s in object table.\n", objEntry->name);
#endif
		omrmem_free_memory(objName);
	} else {
		objEntry = allocateHelper(objName, size);
		if (NULL != objEntry) {
			/* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */
			if ((ROOT == objType) || (NORMAL == objType)) {
				gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(objEntry->objPtr);
			}
		} else {
			omrmem_free_memory(objName);
		}
	}

done:
	return objEntry;
}
コード例 #8
0
bool
MM_VerboseHandlerOutput::getThreadName(char *buf, uintptr_t bufLen, OMR_VMThread *vmThread)
{
	OMRPORT_ACCESS_FROM_OMRVM(_omrVM);
	omrstr_printf(buf, bufLen, "OMR_VMThread [%p]",vmThread);

	return true;
}
コード例 #9
0
ファイル: xml.c プロジェクト: LinHu2016/omr
uintptr_t
escapeXMLString(OMRPortLibrary *portLibrary, char *outBuf, uintptr_t outBufLen, const char *string, uintptr_t stringLen)
{
	uintptr_t stringPos = 0;
	uintptr_t outBufPos = 0;
	OMRPORT_ACCESS_FROM_OMRPORT(portLibrary);

	if (0 == outBufLen) {
		return 0;
	}
	/* null terminate in case we can't fit anything in the buffer */
	outBuf[0] = '\0';

	for (stringPos = 0; stringPos < stringLen; ++stringPos) {
		uintptr_t tmpBufLen = 0;
		char tmpBuf[8];

		switch (string[stringPos]) {
		case '<':
			strcpy(tmpBuf, "&lt;");
			break;
		case '>':
			strcpy(tmpBuf, "&gt;");
			break;
		case '&':
			strcpy(tmpBuf, "&amp;");
			break;
		case '\'':
			strcpy(tmpBuf, "&apos;");
			break;
		case '\"':
			strcpy(tmpBuf, "&quot;");
			break;
		default:
			if (((uint8_t)(string[stringPos])) < 0x20) {
				/* use XML escape sequence for characters below 0x20 */
				omrstr_printf(tmpBuf, sizeof(tmpBuf), "&#x%X;", (uint32_t)string[stringPos]);
			} else {
				tmpBuf[0] = string[stringPos];
				tmpBuf[1] = '\0';
			}
			break;
		}

		/* finish if the output buffer is full */
		tmpBufLen = strlen(tmpBuf);
		if (outBufPos + tmpBufLen > outBufLen - 1) {
			break;
		}

		strcpy(outBuf + outBufPos, tmpBuf);
		outBufPos += tmpBufLen;
	}
	return stringPos;
}
コード例 #10
0
ファイル: agentNegativeTest.cpp プロジェクト: ChengJin01/omr
/*
 * Test scenario for CorruptedAgent:
 * 	- create an empty agent file
 *  - call omr_agent_create() and OMR_Agent::createAgent by providing the empty agent file
 *  - expect openLibrary() to fail
 */
TEST_F(RASAgentNegativeTest, CorruptedAgent)
{
	intptr_t fileDescriptor;
	char fileName[256];
	char agentName[256];
	char hostname[128];
	OMRPORT_ACCESS_FROM_OMRVM(&testVM.omrVM);
	ASSERT_EQ(0, gethostname(hostname, sizeof(hostname)));

	/* generate machine specific file name to prevent conflict between multiple tests running on shared drive */
	omrstr_printf(agentName, sizeof(agentName), "corruptedAgent_%s", hostname);

	/* create fileName with platform-dependent shared library prefix & suffix.
	 *  for Windows, fileName = corruptedAgent_<hostname>.dll
	 *  for Unix, fileName = libcorruptedAgent_<hostname>.so
	 *  for OSX, fileName = libcorruptedAgent_<hostname>.dylib
	 */
#if defined(WIN32) || defined(WIN64)
	omrstr_printf(fileName, sizeof(fileName), "%s.dll", agentName);
#elif defined(OSX)
	omrstr_printf(fileName, sizeof(fileName), "lib%s.dylib", agentName);
#else /* defined(OSX) */
	omrstr_printf(fileName, sizeof(fileName), "lib%s.so", agentName);
#endif /* defined(WIN32) || defined(WIN64) */

	/* create the empty agent file with permission 751*/
	fileDescriptor = omrfile_open(fileName, EsOpenCreate | EsOpenWrite, 0751);
	ASSERT_NE(-1, fileDescriptor) << "omrfile_open \"" << fileName << "\" failed";
	omrfile_close(fileDescriptor);

	/* call omr_agent_create() by providing the empty agent file */
	struct OMR_Agent *agentC = omr_agent_create(&testVM.omrVM, agentName);
	ASSERT_FALSE(NULL == agentC) << "testAgent: createAgent() " << agentName << " failed";
	OMRTEST_ASSERT_ERROR(OMR_ERROR_ILLEGAL_ARGUMENT, omr_agent_openLibrary(agentC));

	/* call OMR_Agent::createAgent() by providing the empty agent file */
	OMR_Agent *agentCPP = OMR_Agent::createAgent(&testVM.omrVM, agentName);
	ASSERT_FALSE(NULL == agentCPP) << "testAgent: createAgent() failed";
	OMRTEST_ASSERT_ERROR(OMR_ERROR_ILLEGAL_ARGUMENT, agentCPP->openLibrary());

	omrfile_unlink(fileName);
}
コード例 #11
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::insertGarbage()
{
	OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM);
	int32_t rt = 0;

	char fullNamePrefix[MAX_NAME_LENGTH];
	omrstr_printf(fullNamePrefix, sizeof(fullNamePrefix), "%s_%d", gp.namePrefix, gp.garbageSeq++);
	int32_t breadth = 2;
	uintptr_t totalSize = (uintptr_t)(gp.accumulatedSize * gp.percentage) / 100;
	uintptr_t objSize = 0;
	if (0 == strcmp(gp.structure, "node")) {
		objSize = totalSize;
	} else if (0 == strcmp(gp.structure, "tree")) {
		objSize = 64;
	}

#if defined(OMRGCTEST_DEBUG)
		omrtty_printf("Inserting garbage %s of %dB (%f%% of previous object/tree size %dB) ...\n", fullNamePrefix, totalSize, gp.percentage, gp.accumulatedSize);
#endif

	omrobjectptr_t rootObj = NULL;
	rt = createFixedSizeTree(&rootObj, fullNamePrefix, GARBAGE_ROOT, totalSize, objSize, breadth);
	OMRGCTEST_CHECK_RT(rt);

	/* remove garbage root object from the root set */
	if (NULL != rootObj) {
		char rootObjName[MAX_NAME_LENGTH];
		omrstr_printf(rootObjName, MAX_NAME_LENGTH, "%s_%d_%d", fullNamePrefix, 0, 0);
		rt = removeObjectFromRootTable(rootObjName);
		OMRGCTEST_CHECK_RT(rt);
	}

	/* reset accumulatedSize */
	gp.accumulatedSize = 0;

done:
	return rt;
}
コード例 #12
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::createObject(omrobjectptr_t *obj, char **objName, const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);
	int32_t rt = 0;
	ObjectEntry *objEntry = NULL;

	*objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM);
	if (NULL == *objName) {
		rt = 1;
		omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__);
		goto done;
	}
	omrstr_printf(*objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow);

	if (0 == objectTable.find(&objEntry, *objName)) {
#if defined(OMRGCTEST_DEBUG)
		omrtty_printf("Find object %s in hash table.\n", *objName);
#endif
		*obj = objEntry->objPtr;
	} else {
		rt = allocateHelper(obj, *objName, size);
		OMRGCTEST_CHECK_RT(rt);

		/* keep object in table */
		rt = objectTable.add(*objName, *obj, 0);
		OMRGCTEST_CHECK_RT(rt)

		/* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */
		if ((ROOT == objType) || (NORMAL == objType)) {
			gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(*obj);
		}
	}

done:
	return rt;
}
コード例 #13
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);

	int32_t rt = 0;
	OMR_VM *omrVMPtr = exampleVM->_omrVM;
	int32_t numOfParents = 0;

	/* Create objects and store them in the root table or the slot object based on objType. */
	if ((ROOT == objType) || (GARBAGE_ROOT == objType)) {
		for (int32_t i = 0; i < breadthElem->value; i++) {
			omrobjectptr_t obj;
			char *objName = NULL;

			uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t);
			rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated);
			OMRGCTEST_CHECK_RT(rt);
			numOfFieldsElem = numOfFieldsElem->linkNext;

			/* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating
			 * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/
			RootEntry rEntry;
			rEntry.name = objName;
			rEntry.rootPtr = obj;
			if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) {
				rt = 1;
				omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__);
				goto done;
			}

			/* insert garbage per node */
			if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
				rt = insertGarbage();
				OMRGCTEST_CHECK_RT(rt);
			}
		}
	} else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) {
		char parentName[MAX_NAME_LENGTH];
		omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0);
		ObjectEntry *parentEntry;
		rt = objectTable.find(&parentEntry, parentName);
		if (0 != rt) {
			omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
			goto done;
		}
		omrobjectptr_t parent = parentEntry->objPtr;
		GC_ObjectIterator objectIterator(omrVMPtr, parent);
		objectIterator.restore(parentEntry->numOfRef);
		for (int32_t i = 0; i < breadthElem->value; i++) {
			omrobjectptr_t obj;
			char *objName = NULL;
			uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t);
			rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated);
			OMRGCTEST_CHECK_RT(rt);
			numOfFieldsElem = numOfFieldsElem->linkNext;
			GC_SlotObject *slotObject = NULL;
			if (NULL != (slotObject = objectIterator.nextSlot())) {
#if defined(OMRGCTEST_DEBUG)
				omrtty_printf("\tadd to slot of parent(%llu) %d\n", parent, parentEntry->numOfRef + i);
#endif
				/* Add object to parent's slot. If it's the top of the garbage tree, temporarily keep it in the slot until
				 * the rest of the tree is allocated. */
				slotObject->writeReferenceToSlot(obj);
			} else {
				rt = 1;
				omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName);
				goto done;
			}

			/* insert garbage per node */
			if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
				rt = insertGarbage();
				OMRGCTEST_CHECK_RT(rt);
			}
		}
		parentEntry->numOfRef += breadthElem->value;
	} else {
		rt = 1;
		goto done;
	}

	/* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */
	if (ROOT == objType) {
		objType = NORMAL;
	} else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) {
		objType = GARBAGE_CHILD;
	}
	numOfParents = breadthElem->value;
	breadthElem = breadthElem->linkNext;
	for (int32_t i = 1; i < depth; i++) {
		int32_t nthInRow = 0;
		for (int32_t j = 0; j < numOfParents; j++) {
			char parentName[MAX_NAME_LENGTH];
			omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j);
			ObjectEntry *parentEntry;
			rt = objectTable.find(&parentEntry, parentName);
			if (0 != rt) {
				omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
				goto done;
			}
			omrobjectptr_t parent = parentEntry->objPtr;
			GC_ObjectIterator objectIterator(omrVMPtr, parent);
			objectIterator.restore(parentEntry->numOfRef);
			for (int32_t k = 0; k < breadthElem->value; k++) {
				omrobjectptr_t obj;
				char *objName = NULL;
				uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t);
				rt = createObject(&obj, &objName, namePrefixStr, objType, i, nthInRow, sizeCalculated);
				OMRGCTEST_CHECK_RT(rt);
				numOfFieldsElem = numOfFieldsElem->linkNext;
				nthInRow += 1;
				GC_SlotObject *slotObject = NULL;
				if (NULL != (slotObject = objectIterator.nextSlot())) {
#if defined(OMRGCTEST_DEBUG)
					omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k);
#endif
					slotObject->writeReferenceToSlot(obj);
				} else {
					rt = 1;
					omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName);
					goto done;
				}

				/* insert garbage per node */
				if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
					rt = insertGarbage();
					OMRGCTEST_CHECK_RT(rt);
				}
			}
			parentEntry->numOfRef += breadthElem->value;
		}
		numOfParents = nthInRow;
		breadthElem = breadthElem->linkNext;
	}

done:
	return rt;
}
コード例 #14
0
ファイル: omrtracecomponent.cpp プロジェクト: ChengJin01/omr
omr_error_t
initialiseComponentData(UtComponentData **componentDataPtr, UtModuleInfo *moduleInfo, const char *componentName)
{
	OMRPORT_ACCESS_FROM_OMRPORT(OMR_TRACEGLOBAL(portLibrary));

	UtComponentData *componentData = (UtComponentData *)omrmem_allocate_memory(sizeof(UtComponentData), OMRMEM_CATEGORY_TRACE);

	UT_DBGOUT(2, ("<UT> initialiseComponentData: %s\n", componentName));
	if (componentData == NULL) {
		UT_DBGOUT(1, ("<UT> Unable to allocate componentData for %s\n", componentName));
		return OMR_ERROR_OUT_OF_NATIVE_MEMORY;
	}

	initHeader(&componentData->header, UT_TRACE_COMPONENT_DATA, sizeof(UtComponentData));
	componentData->componentName = (char *)omrmem_allocate_memory(strlen(componentName) + 1, OMRMEM_CATEGORY_TRACE);
	if (componentData->componentName == NULL) {
		UT_DBGOUT(1, ("<UT> Unable to allocate componentData's name field for %s\n", componentName));
		return OMR_ERROR_OUT_OF_NATIVE_MEMORY;
	}
	strcpy(componentData->componentName, componentName);

	/* Setup the fully qualified name here as when we come to print out trace counters the modules may have been
	 * freed already. */
	if (moduleInfo->traceVersionInfo->traceVersion >= 7 && moduleInfo->containerModule != NULL) {
		char qualifiedName[MAX_QUALIFIED_NAME_LENGTH];
		omrstr_printf(qualifiedName, MAX_QUALIFIED_NAME_LENGTH, "%s(%s)", moduleInfo->name, moduleInfo->containerModule->name);
		componentData->qualifiedComponentName = (char *)omrmem_allocate_memory(strlen(qualifiedName) + 1, OMRMEM_CATEGORY_TRACE);
		if (componentData->qualifiedComponentName == NULL) {
			UT_DBGOUT(1, ("<UT> Unable to allocate componentData's name field for %s\n", componentName));
			return OMR_ERROR_OUT_OF_NATIVE_MEMORY;
		}
		strcpy(componentData->qualifiedComponentName, qualifiedName);
	} else {
		componentData->qualifiedComponentName = componentData->componentName;
	}

	if (moduleInfo->formatStringsFileName != NULL) {
		componentData->formatStringsFileName = (char *)omrmem_allocate_memory(strlen(moduleInfo->formatStringsFileName) + 1, OMRMEM_CATEGORY_TRACE);
		if (componentData->formatStringsFileName == NULL) {
			UT_DBGOUT(1, ("<UT> Unable to allocate componentData's format strings file name field for %s\n", componentName));
			return OMR_ERROR_OUT_OF_NATIVE_MEMORY;
		}
		strcpy(componentData->formatStringsFileName, moduleInfo->formatStringsFileName);
	} else {
		componentData->formatStringsFileName = NULL;
	}

	componentData->moduleInfo = moduleInfo;
	componentData->tracepointCount = moduleInfo->count;
	componentData->numFormats = 0;
	componentData->tracepointFormattingStrings = NULL;
	componentData->tracepointcounters = NULL;
	componentData->alreadyfailedtoloaddetails = 0;
	componentData->next = NULL;
	componentData->prev = NULL;

	*componentDataPtr = componentData;
	UT_DBGOUT(2, ("<UT> initialiseComponentData complete: %s\n", componentName));

	return OMR_ERROR_NONE;
}
コード例 #15
0
ファイル: GCConfigTest.cpp プロジェクト: is00hcw/omr
int32_t
GCConfigTest::createFixedSizeTree(ObjectEntry **rootEntryIndirectPtr, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);
	*rootEntryIndirectPtr = NULL;

	int32_t rt = 0;
	uintptr_t bytesLeft = totalSize;
	if (bytesLeft < objSize) {
		objSize = bytesLeft;
		if (objSize <= 0) {
			return rt;
		}
	}
	bytesLeft -= objSize;
	rt = 1;

	int32_t depth = 1;
	int32_t numOfParents = 1;

	/* allocate the root object and add it to the object table */
	*rootEntryIndirectPtr = createObject(namePrefixStr, objType, 0, 0, objSize);
	if (NULL == *rootEntryIndirectPtr) {
		goto done;
	}

	/* add it to the root table */
	RootEntry rootEntry;
	rootEntry.name = (*rootEntryIndirectPtr)->name;
	rootEntry.rootPtr = (*rootEntryIndirectPtr)->objPtr;
	if (NULL == hashTableAdd(exampleVM->rootTable, &rootEntry)) {
		omrtty_printf("%s:%d Failed to add new root entry %s to root table!\n", __FILE__, __LINE__, rootEntry.name);
		goto done;
	}

	/* create the rest of the tree */
	if (ROOT == objType) {
		objType = NORMAL;
	} else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) {
		objType = GARBAGE_CHILD;
	}
	while (bytesLeft > 0) {
		int32_t nthInRow = 0;
		for (int32_t j = 0; j < numOfParents; j++) {
			char parentName[MAX_NAME_LENGTH];
			omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j);
			ObjectEntry *parentEntry = find(parentName);
			if (NULL == parentEntry) {
				omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
				goto done;
			}
			for (int32_t k = 0; k < breadth; k++) {
				if (bytesLeft < objSize) {
					objSize = bytesLeft;
					if (objSize <= 0) {
						rt = 0;
						goto done;
					}
				}
				ObjectEntry *childEntry = createObject(namePrefixStr, objType, depth, nthInRow, objSize);
				if (NULL == childEntry) {
					goto done;
				}
				parentEntry = find(parentName);
				if (NULL == parentEntry) {
					omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
					goto done;
				}
				if (0 != attachChildEntry(parentEntry, childEntry)) {
					goto done;
				}
				bytesLeft -= objSize;
				nthInRow += 1;
			}
			parentEntry = find(parentName);
			if (NULL == parentEntry) {
				omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
				goto done;
			}
		}
		numOfParents = nthInRow;
		depth += 1;
	}
	*rootEntryIndirectPtr = find(rootEntry.name);
	if (NULL == *rootEntryIndirectPtr) {
		omrtty_printf("%s:%d Could not find root of fixed-size tree %s in object table.\n", __FILE__, __LINE__, rootEntry.name);
		goto done;
	}
	rt = 0;
done:
	return rt;
}
コード例 #16
0
ファイル: testProcessHelpers.cpp プロジェクト: bjornvar/omr
intptr_t
j9process_create(OMRPortLibrary *portLibrary, const char *command[], uintptr_t commandLength, const char *dir, uint32_t options, OMRProcessHandle *processHandle)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portLibrary);
	intptr_t rc = 0;
	OMRProcessHandleStruct *processHandleStruct = NULL;

#if defined(WIN32)
	STARTUPINFOW sinfo;
	PROCESS_INFORMATION pinfo;
	SECURITY_ATTRIBUTES sAttrib;
	wchar_t *unicodeDir = NULL;
	wchar_t *unicodeCmdline = NULL;
	wchar_t *unicodeEnv = NULL;
	OMRProcessWin32Pipes pipes;
	DWORD dwMode = PIPE_NOWAIT;	/* it's only used if OMRPORT_PROCESS_NONBLOCKING_IO is set */

	if (0 == commandLength) {
		return OMRPROCESS_ERROR;
	}

	processHandleStruct = (OMRProcessHandleStruct *)omrmem_allocate_memory(sizeof(OMRProcessHandleStruct), OMRMEM_CATEGORY_PORT_LIBRARY);

	ZeroMemory(&sinfo, sizeof(sinfo));
	ZeroMemory(&pinfo, sizeof(pinfo));
	ZeroMemory(&sAttrib, sizeof(sAttrib));

	sinfo.cb = sizeof(sinfo);
	sinfo.dwFlags = STARTF_USESTDHANDLES;

	/* Allow handle inheritance */
	sAttrib.bInheritHandle = 1;
	sAttrib.nLength = sizeof(sAttrib);

	ZeroMemory(&pipes, sizeof(OMRProcessWin32Pipes));

	// Create input pipe
	if (0 == CreatePipe(&(pipes.inR), &(pipes.inW), &sAttrib, 512)) {
		closeAndDestroyPipes(&pipes);
		return OMRPROCESS_ERROR;
	} else {
		if (0 == DuplicateHandle(GetCurrentProcess(), pipes.inW, GetCurrentProcess(),
								 &(pipes.inDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) {
			closeAndDestroyPipes(&pipes);
			return OMRPROCESS_ERROR;
		}
		if (0 == CloseHandle(pipes.inW)) {
			closeAndDestroyPipes(&pipes);
			return OMRPROCESS_ERROR;
		}
		pipes.inW = NULL;
	}
	sinfo.hStdInput = pipes.inR;
	processHandleStruct->inHandle = (intptr_t)pipes.inDup;

	if (OMRPROCESS_DEBUG == options) {
		processHandleStruct->outHandle = OMRPROCESS_INVALID_FD;
		if (sinfo.dwFlags == STARTF_USESTDHANDLES) {
			sinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
		}
		processHandleStruct->errHandle = OMRPROCESS_INVALID_FD;
		if (sinfo.dwFlags == STARTF_USESTDHANDLES) {
			sinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
		}
	} else {
		// Create output pipe
		if (0 == CreatePipe(&(pipes.outR), &(pipes.outW), &sAttrib, 512)) {
			closeAndDestroyPipes(&pipes);
			return OMRPROCESS_ERROR;
		} else {
			if (0 == DuplicateHandle(GetCurrentProcess(), pipes.outR, GetCurrentProcess(),
									 &(pipes.outDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) {
				closeAndDestroyPipes(&pipes);
				return OMRPROCESS_ERROR;
			}
			if (0 == CloseHandle(pipes.outR)) {
				closeAndDestroyPipes(&pipes);
				return OMRPROCESS_ERROR;
			}
			pipes.outR = NULL;
		}
		processHandleStruct->outHandle = (intptr_t)pipes.outDup;
		sinfo.hStdOutput = pipes.outW;

		// create error pipe
		if (0 == CreatePipe(&(pipes.errR), &(pipes.errW), &sAttrib, 512)) {
			closeAndDestroyPipes(&pipes);
			return OMRPROCESS_ERROR;
		} else {
			if (0 == DuplicateHandle(GetCurrentProcess(), pipes.errR, GetCurrentProcess(),
									 &(pipes.errDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) {
				closeAndDestroyPipes(&pipes);
				return OMRPROCESS_ERROR;
			}
			if (NULL != pipes.errR) {
				if (0 == CloseHandle(pipes.errR)) {
					closeAndDestroyPipes(&pipes);
					return OMRPROCESS_ERROR;
				}
			}
			pipes.errR = NULL;
		}
		processHandleStruct->errHandle = (intptr_t)pipes.errDup;
		sinfo.hStdError = pipes.errW;
	}

	if (0 == rc) {
		rc = getUnicodeCmdline(OMRPORTLIB, command, commandLength, &unicodeCmdline);
		if (0 == rc) {
			if (NULL != dir) {
				size_t length = strlen(dir);
				unicodeDir = (wchar_t *)omrmem_allocate_memory((length + 1) * 2, OMRMEM_CATEGORY_PORT_LIBRARY);
				if (NULL == unicodeDir) {
					rc = OMRPROCESS_ERROR;
				} else {
					convertFromUTF8(OMRPORTLIB, dir, unicodeDir, length + 1);
				}
			}

			if (0 == rc) {
				DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT;

				if (0 == CreateProcessW( /* CreateProcessW returns 0 upon failure */
						NULL,
						unicodeCmdline,
						NULL,
						NULL,
						TRUE,
						creationFlags,		/* add DEBUG_ONLY_THIS_PROCESS for smoother debugging */
						unicodeEnv,
						unicodeDir,
						&sinfo,
						&pinfo)				/* Pointer to PROCESS_INFORMATION structure; */
				) {
					rc = OMRPROCESS_ERROR;
				} else {
					processHandleStruct->procHandle = (intptr_t) pinfo.hProcess;
					/* Close Handles passed to child if there is any */
					CloseHandle(pipes.inR);
					if (OMRPROCESS_DEBUG != options) {
						CloseHandle(pipes.outW);
						CloseHandle(pipes.errW);
					}
					CloseHandle(pinfo.hThread);	/* Implicitly created, a leak otherwise*/
				}
			}
		}
	}

	if (NULL != unicodeCmdline) {
		omrmem_free_memory(unicodeCmdline);
	}
	if (NULL != unicodeDir) {
		omrmem_free_memory(unicodeDir);
	}
	if (NULL != unicodeEnv) {
		omrmem_free_memory(unicodeEnv);
	}

	if (0 != rc) {
		/* If an error occurred close all handles */
		closeAndDestroyPipes(&pipes);
	} else {
		*processHandle = processHandleStruct;
	}

	return rc;
#else /* defined(WIN32) */
	const char *cmd = NULL;
	int grdpid;
	unsigned int i;
	int newFD[3][2];
	int forkedChildProcess[2];
	int pipeFailed = 0;
	int errorNumber = 0;
	char **newCommand;
	uintptr_t newCommandSize;

	if (0 == commandLength) {
		return OMRPROCESS_ERROR;
	}

	for (i = 0; i < 3; i += 1) {
		newFD[i][0] = OMRPROCESS_INVALID_FD;
		newFD[i][1] = OMRPROCESS_INVALID_FD;
	}
	/* Build the new io pipes (in/out/err) */
	if (-1 == pipe(newFD[0])) {
		pipeFailed = 1;
	}
	if (OMRPROCESS_DEBUG != options) {
		if (-1 == pipe(newFD[1])) {
			pipeFailed = 1;
		}
		if (-1 == pipe(newFD[2])) {
			pipeFailed = 1;
		}
	}
	if (-1 == pipe(forkedChildProcess)) { /* pipe for synchronization */
		forkedChildProcess[0] = OMRPROCESS_INVALID_FD;
		forkedChildProcess[1] = OMRPROCESS_INVALID_FD;
		pipeFailed = 1;
	}

	if (pipeFailed) {
		for (i = 0; i < 3; i++) {
			if (OMRPROCESS_INVALID_FD != newFD[i][0]) {
				if (-1 != rc) {
					rc = close(newFD[i][0]);
				}
				if (-1 != rc) {
					rc = close(newFD[i][1]);
				}
			}
		}
		if (OMRPROCESS_INVALID_FD != forkedChildProcess[0]) {
			if (-1 != rc) {
				rc = close(forkedChildProcess[0]);
			}
			if (-1 != rc) {
				rc = close(forkedChildProcess[1]);
			}
		}
		return OMRPROCESS_ERROR;
	}

	if (-1 != rc) {
		rc = setFdCloexec(forkedChildProcess[0]);
	}
	if (-1 != rc) {
		rc = setFdCloexec(forkedChildProcess[1]);
	}

	/* Create a NULL terminated array to contain the command for call to execv[p|e]()
	 * We could do this in the child, but if mem_allocate_memory fails, it's easier to diagnose
	 * failure in parent. Remember to free the memory
	 */
	newCommandSize = (commandLength + 1) * sizeof(uintptr_t);
	newCommand = (char **)omrmem_allocate_memory(newCommandSize, OMRMEM_CATEGORY_PORT_LIBRARY);
	if (NULL == newCommand) {
		return OMRPROCESS_ERROR;
	}
	memset(newCommand, 0, newCommandSize);

	for (i = 0 ; i < commandLength; i += 1) {
#if defined(OSX)
		newCommand[i] = (char *)omrmem_allocate_memory(strlen(command[i]) + 1, OMRMEM_CATEGORY_PORT_LIBRARY);
		omrstr_printf(newCommand[i], strlen(command[i]) + 1, command[i]);
#else /* defined(OSX) */
		intptr_t translateStatus = translateModifiedUtf8ToPlatform(OMRPORTLIB, command[i], strlen(command[i]), &(newCommand[i]));
		if (0 != translateStatus) {
			unsigned int j = 0;
			/* most likely out of memory, free the strings we just converted. */
			for (j = 0; j < i; j += 1) {
				if (NULL != newCommand[j]) {
					omrmem_free_memory(newCommand[j]);
				}
			}
			return translateStatus;
		}
#endif /* defined(OSX) */
	}
	cmd = newCommand[0];

	newCommand[commandLength] = NULL;

	grdpid = fork();
	if (grdpid == 0) {
		/* Child process */
		char dummy = '\0';

		/* Redirect pipes so grand-child inherits new pipes */
		rc = dup2(newFD[0][0], 0);
		if (-1 != rc) {
			if (OMRPROCESS_DEBUG != options) {
				rc = dup2(newFD[1][1], 1);
				if (-1 != rc) {
					rc = dup2(newFD[2][1], 2);
				}
			}
		}

		/* tells the parent that that very process is running */
		rc = write(forkedChildProcess[1], (void *) &dummy, 1);

		if ((-1 != rc) && dir) {
			rc = chdir(dir);
		}

		if (-1 != rc) {
			/* Try to perform the execv; on success, it does not return */
			rc = execvp(cmd, newCommand);
		}

		/* If we get here, tell the parent that the execv failed! Send the error number. */
		if (-1 != rc) {
			rc = write(forkedChildProcess[1], &errno, sizeof(errno));
		}
		if (-1 != rc) {
			rc = close(forkedChildProcess[0]);
		}
		if (-1 != rc) {
			rc = close(forkedChildProcess[1]);
		}
		/* If the exec failed, we must exit or there will be two VM processes running. */
		exit(rc);
	} else {
		/* In the parent process */
		char dummy;

		for (i = 0; i < commandLength; i++) {
			if (NULL != newCommand[i]) {
				omrmem_free_memory(newCommand[i]);
			}
		}
		omrmem_free_memory(newCommand);

		if ((OMRPROCESS_INVALID_FD != newFD[0][0]) && (-1 != rc)) {
			rc = close(newFD[0][0]);
		}
		if ((OMRPROCESS_INVALID_FD != newFD[1][1]) && (-1 != rc)) {
			rc = close(newFD[1][1]);
		}
		if ((OMRPROCESS_INVALID_FD != newFD[2][1]) && (-1 != rc)) {
			rc = close(newFD[2][1]);
		}

		if (grdpid == -1) { /* the fork failed */
			/* close the open pipes */
			if (-1 != rc) {
				rc = close(forkedChildProcess[0]);
			}
			if (-1 != rc) {
				rc = close(forkedChildProcess[1]);
			}
			if ((OMRPROCESS_INVALID_FD != newFD[0][1]) && (-1 != rc)) {
				rc = close(newFD[0][1]);
			}
			if ((OMRPROCESS_INVALID_FD != newFD[1][0]) && (-1 != rc)) {
				rc = close(newFD[1][0]);
			}
			if ((OMRPROCESS_INVALID_FD != newFD[2][0]) && (-1 != rc)) {
				rc = close(newFD[2][0]);
			}
			return OMRPROCESS_ERROR;
		}

		/* Store the rw handles to the childs io */
		processHandleStruct = (OMRProcessHandleStruct *)omrmem_allocate_memory(sizeof(OMRProcessHandleStruct), OMRMEM_CATEGORY_PORT_LIBRARY);
		processHandleStruct->inHandle = (intptr_t)newFD[0][1];
		if (OMRPROCESS_DEBUG == options) {
			processHandleStruct->outHandle = OMRPROCESS_INVALID_FD;
			processHandleStruct->errHandle = OMRPROCESS_INVALID_FD;
		} else {
			processHandleStruct->outHandle = (intptr_t)newFD[1][0];
			processHandleStruct->errHandle = (intptr_t)newFD[2][0];
		}

		processHandleStruct->procHandle = (intptr_t)grdpid;
		processHandleStruct->pid = (int32_t)grdpid;

		/* let the forked child start. */
		rc = close(forkedChildProcess[1]);
		if (-1 != rc) {
			rc = read(forkedChildProcess[0], &dummy, 1);
		}

		/* [PR CMVC 143339]
		 * Instead of using timeout to determine if child process has been created successfully,
		 * a single block read/write pipe call is used, if process creation failed, errorNumber
		 * with sizeof(errno) will be returned, otherwise, read will fail due to pipe closure.
		 */
		if (-1 != rc) {
			rc = read(forkedChildProcess[0], &errorNumber, sizeof(errno));
		}
		if (-1 != rc) {
			rc = close(forkedChildProcess[0]);
		}

		if (rc == sizeof(errno)) {
			return OMRPROCESS_ERROR;
		}
		*processHandle = processHandleStruct;
		return rc;
	}

	return OMRPROCESS_ERROR;
#endif /* defined(WIN32) */
}
コード例 #17
0
ファイル: hookable.cpp プロジェクト: bjornvar/omr
/*
 * Inform all registered listeners that the specified event has occurred. Details about the
 * event should be available through eventData.
 *
 * If the J9HOOK_TAG_ONCE bit is set in the taggedEventNum, then the event is disabled
 * before the listeners are informed. Any attempts to add listeners to a TAG_ONCE event
 * once it has been reported will fail.
 *
 * This function should not be called directly. It should be called through the hook interface
 *
 */
static void
J9HookDispatch(struct J9HookInterface **hookInterface, uintptr_t taggedEventNum, void *eventData)
{
	uintptr_t eventNum = taggedEventNum & J9HOOK_EVENT_NUM_MASK;
	J9CommonHookInterface *commonInterface = (J9CommonHookInterface *)hookInterface;
	J9HookRecord *record = HOOK_RECORD(commonInterface, eventNum);
	OMREventInfo4Dump *eventDump = J9HOOK_DUMPINFO(commonInterface, eventNum);
	uintptr_t samplingInterval = (taggedEventNum & J9HOOK_TAG_SAMPLING_MASK) >> 16;
	bool sampling = false;

	if (taggedEventNum & J9HOOK_TAG_ONCE) {
		uint8_t oldFlags;

		omrthread_monitor_enter(commonInterface->lock);
		oldFlags = HOOK_FLAGS(commonInterface, eventNum);
		/* clear the HOOKED and RESERVED flags and set the DISABLED flag */
		HOOK_FLAGS(commonInterface, eventNum) = (oldFlags | J9HOOK_FLAG_DISABLED) & ~(J9HOOK_FLAG_RESERVED | J9HOOK_FLAG_HOOKED);
		omrthread_monitor_exit(commonInterface->lock);

		if (oldFlags & J9HOOK_FLAG_DISABLED) {
			/* already reported */
			return;
		}
	}

	while (record) {
		J9HookFunction function;
		void *userData;
		uintptr_t id;

		/* ensure that the id is read before any other fields */
		id = record->id;
		if (HOOK_IS_VALID_ID(id)) {
			VM_AtomicSupport::readBarrier();

			function = record->function;
			userData = record->userData;

			/* now read the id again to make sure that nothing has changed */
			VM_AtomicSupport::readBarrier();
			if (record->id == id) {
				uint64_t startTime = 0;
				uintptr_t count = 0;
				if (NULL != eventDump) {
					count = VM_AtomicSupport::add((volatile uintptr_t *)&eventDump->count, 1);
					sampling = (1 >= samplingInterval) || ((100 >= samplingInterval) && (0 == (count % samplingInterval)));
				} else {
					sampling =  false;
				}
				OMRPORT_ACCESS_FROM_OMRPORT(commonInterface->portLib);
				if (sampling) {
					startTime = omrtime_current_time_millis();
				}

				function(hookInterface, eventNum, eventData, userData);

				if (sampling) {
					uint64_t timeDelta = omrtime_current_time_millis() - startTime;

					eventDump->lastHook.startTime = startTime;
					eventDump->lastHook.callsite = record->callsite;
					eventDump->lastHook.func_ptr = (void *)record->function;
					eventDump->lastHook.duration = timeDelta;

					if ((eventDump->longestHook.duration < timeDelta) ||
						(0 == eventDump->longestHook.startTime)) {
							eventDump->longestHook.startTime = startTime;
							eventDump->longestHook.callsite = record->callsite;
							eventDump->longestHook.func_ptr = (void *)record->function;
							eventDump->longestHook.duration = timeDelta;
					}

					if (commonInterface->threshold4Trace <= timeDelta) {
						const char *callsite = "UNKNOWN";
						char buffer[32];
						if (NULL != record->callsite) {
							callsite = record->callsite;
						} else {
							/* if the callsite info can not be retrieved, use callback function pointer instead  */
							omrstr_printf(buffer, sizeof(buffer), "0x%p", record->function);
							callsite = buffer;
						}
						Trc_Hook_Dispatch_Exceed_Threshold_Event(callsite, timeDelta);
					}
				}
			} else {
				/* this record has been updated while we were reading it. Skip it. */
			}
		}

		record = record->next;
	}
}
コード例 #18
0
ファイル: omrerrorTest.cpp プロジェクト: bjornvar/omr
/**
 * Verify port library error handling operations.
 *
 * Error codes are stored in per thread buffers so errors reported by one thread
 * do not effect those reported by a second.  Errors stored via the helper
 * function @ref omrerror.c::omrerror_set_last_error_with_message_format "omrerror_set_last_error_with_message_format()"
 * are recorded in the per thread buffers without an error message.
 * Verify the @ref omrerror_last_error_message "omrerror_last_error_message()" returns
 * the correct message.
 */
TEST(PortErrorTest, error_test3)
{
	OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
	const char *testName = "omrerror_test3";

	const char *message;
	const char *formatMessage1 = "This is a test message with format specifiers %s %d";
	const char *formatMessage2 = "This is also a test message with format specifiers %s %d";
	const char *arg1 = "arg1";
	int32_t arg2 = 1;
	char knownMessage[1024]; /* 1024 is large enough to hold format message */
	int32_t errorCode;

	reportTestEntry(OMRPORTLIB, testName);

	/* Delete the ptBuffers */
	omrport_tls_free();

	/* In theory there is now nothing stored, if we really did free the buffers.
	 * Guess it is time to find out
	 */
	message = omrerror_last_error_message();
	if (0 != strlen(message)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned message of length %d expected %d\n", strlen(message), 0);
	}

	/* Set an error message, verify it is what we get back */
	omrstr_printf(knownMessage, 1024, formatMessage1, arg1, arg2);
	errorCode = omrerror_set_last_error_with_message_format(200, formatMessage1, arg1, arg2);
	message = omrerror_last_error_message();
	if (200 != errorCode) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error_with_message() returned %d expected %d\n", errorCode, 200);
	}
	if (strlen(message) != strlen(knownMessage)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned length %d expected %d\n", strlen(message), strlen(knownMessage));
	}
	if (0 != memcmp(message, knownMessage, strlen(knownMessage))) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected \"%s\"\n", message, knownMessage);
	}

	/* Again, different message */
	omrstr_printf(knownMessage, 1024, formatMessage2, arg1, arg2);
	errorCode = omrerror_set_last_error_with_message_format(100, formatMessage2, arg1, arg2);
	message = omrerror_last_error_message();
	if (100 != errorCode) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error_with_message() returned %d expected %d\n", errorCode, 100);
	}
	if (strlen(message) != strlen(knownMessage)) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned length %d expected %d\n", strlen(message), strlen(knownMessage));
	}
	if (0 != memcmp(message, knownMessage, strlen(knownMessage))) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected \"%s\"\n", message, knownMessage);
	}

	/* Delete the ptBuffers, verify no error is stored */
	omrport_tls_free();
	errorCode = omrerror_last_error_number();
	if (0 != errorCode) {
		outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, 0);
	}
	reportTestExit(OMRPORTLIB, testName);
}
コード例 #19
0
ファイル: GCConfigTest.cpp プロジェクト: is00hcw/omr
int32_t
GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);

	int32_t rt = 1;
	int32_t numOfParents = 0;

	/* Create objects and store them in the root table or the slot object based on objType. */
	if ((ROOT == objType) || (GARBAGE_ROOT == objType)) {
		for (int32_t i = 0; i < breadthElem->value; i++) {
			uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t);
			ObjectEntry *objectEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated);
			if (NULL == objectEntry) {
				goto done;
			}
			numOfFieldsElem = numOfFieldsElem->linkNext;

			/* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating
			 * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/
			RootEntry rEntry;
			rEntry.name = objectEntry->name;
			rEntry.rootPtr = objectEntry->objPtr;
			if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) {
				omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__);
				goto done;
			}

			/* insert garbage per node */
			if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
				int32_t grt = insertGarbage();
				OMRGCTEST_CHECK_RT(grt);
			}
		}
	} else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) {
		char parentName[MAX_NAME_LENGTH];
		omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0);
		for (int32_t i = 0; i < breadthElem->value; i++) {
			uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t);
			ObjectEntry *childEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated);
			if (NULL == childEntry) {
				goto done;
			}
			ObjectEntry *parentEntry = find(parentName);
			if (NULL == parentEntry) {
				omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
				goto done;
			}
			if (0 != attachChildEntry(parentEntry, childEntry)) {
				goto done;
			}
			numOfFieldsElem = numOfFieldsElem->linkNext;

			/* insert garbage per node */
			if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
				int32_t grt = insertGarbage();
				OMRGCTEST_CHECK_RT(grt);
			}
		}
	} else {
		goto done;
	}

	/* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */
	if (ROOT == objType) {
		objType = NORMAL;
	} else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) {
		objType = GARBAGE_CHILD;
	}
	numOfParents = breadthElem->value;
	breadthElem = breadthElem->linkNext;
	for (int32_t i = 1; i < depth; i++) {
		int32_t nthInRow = 0;
		for (int32_t j = 0; j < numOfParents; j++) {
			char parentName[MAX_NAME_LENGTH];
			omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j);
			for (int32_t k = 0; k < breadthElem->value; k++) {
				uintptr_t sizeCalculated = sizeof(omrobjectptr_t) + numOfFieldsElem->value * sizeof(fomrobject_t);
				ObjectEntry *childEntry = createObject(namePrefixStr, objType, i, nthInRow, sizeCalculated);
				if (NULL == childEntry) {
					goto done;
				}
				ObjectEntry *parentEntry = find(parentName);
				if (NULL == parentEntry) {
					omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
					goto done;
				}
				if (0 != attachChildEntry(parentEntry, childEntry)) {
					goto done;
				}
				numOfFieldsElem = numOfFieldsElem->linkNext;
				nthInRow += 1;

				/* insert garbage per node */
				if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) {
					int32_t grt = insertGarbage();
					OMRGCTEST_CHECK_RT(grt);
				}
			}
		}
		numOfParents = nthInRow;
		breadthElem = breadthElem->linkNext;
	}
	rt = 0;
done:
	return rt;
}
コード例 #20
0
ファイル: omrosdump.c プロジェクト: LinHu2016/omr
/**
 * @internal
 * Generate an IEATDUMP
 *
 * @param[in] portLibrary the port library
 * @param[in,out] asciiLabel the filename to use in ascii. Lowercase letters are _not_ allowed
 * @param[in,out] ebcdicLabel the filename to use in ebcdic. Lowercase letters are _not_ allowed
 * @param[out] returnCode the zOS return code from the IEATDUMP call
 * @param[out] reasonCode the zOS reason code from the IEATDUMP call
 *  *
 * @return 0 if IEATDUMP was actually called, non-zero if there was an error that prevented us
 *  		getting that far
 *
 * If we return 0, it's the callers responsibility to check returnCode to find out if the TDUMP was
 * actually successful
 *
 * Note that asciiLabel and ebcdicLabel should represent the same
 *  filename as both are used in this function
 */
static intptr_t
tdump(struct OMRPortLibrary *portLibrary, char *asciiLabel, char *ebcdicLabel, uint32_t *returnCode, uint32_t *reasonCode)
{
	struct ioparms_t {
		uint64_t plist[256];
		uint32_t retcode;
		uint32_t rsncode;
		uint32_t retval;
	} *ioParms31;

	struct dsn_pattern_t {
		unsigned char len;
		char dsn[256];
	} *dsnPattern31;

	/* _TDUMP subroutine expects 31 bit addresses */
	ioParms31 = __malloc31(sizeof(*ioParms31));
	if (ioParms31 == NULL) {
		omrtty_err_printf(portLibrary, "__malloc31 failed to allocate buffer for ioParms31\n");
		return 1;
	}
	memset(ioParms31, 0, sizeof(*ioParms31));

	dsnPattern31 = __malloc31(sizeof(*dsnPattern31));
	if (dsnPattern31 == NULL) {
		omrtty_err_printf(portLibrary, "__malloc31 failed to allocate buffer for dsnPattern31\n");
		free(ioParms31);
		return 2;
	}
	memset(dsnPattern31, 0, sizeof(*dsnPattern31));

	strcpy(dsnPattern31->dsn, ebcdicLabel);
	dsnPattern31->len = strlen(ebcdicLabel);

	/* Note: the actual IEATDUMP options are specified on the assembler macro call in omrgenerate_ieat_dumps.s. The
	 * message below needs to be kept consistent with the options set on the macro call.
	 */
	omrtty_err_printf(portLibrary, "IEATDUMP in progress with options SDATA=(LPA,GRSQ,LSQA,NUC,PSA,RGN,SQA,SUM,SWA,TRT)\n");

	_TDUMP(ioParms31, dsnPattern31);

	if (returnCode) {
		*returnCode = ioParms31->retcode;
	}

	if (reasonCode) {
		*reasonCode = ioParms31->rsncode;
	}

	if (ioParms31->retcode) {
		/*
		 * Please refer to VMDESIGN 1459 about IEATDUMP failure recovery
		 */
		char errmsg[1024];

		omrtty_err_printf(portLibrary, "IEATDUMP failure for DSN='%s' RC=0x%08X RSN=0x%08X\n", asciiLabel, ioParms31->retcode, ioParms31->rsncode);

		memset(errmsg, 0, sizeof errmsg);

		omrstr_printf(portLibrary, errmsg, sizeof errmsg, "JVMDMP025I IEATDUMP failed RC=0x%08X RSN=0x%08X DSN=%s", ioParms31->retcode, ioParms31->rsncode, asciiLabel);
		omrsyslog_write(portLibrary, 0, errmsg);
	} else {
		omrtty_err_printf(portLibrary, "IEATDUMP success for DSN='%s'\n", asciiLabel);
	}

	free(dsnPattern31);
	free(ioParms31);

	return 0;
}
コード例 #21
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
void
GCConfigTest::TearDown()
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);

	/* free root table */
	hashTableFree(exampleVM->rootTable);

	/* free object table */
	objectTable.free();

	/* close verboseManager and clean up verbose files */
	verboseManager->closeStreams(env);
	verboseManager->disableVerboseGC();
	verboseManager->kill(env);
	if (false == gcTestEnv->keepLog) {
		if (0 == numOfFiles) {
			J9FileStat buf;
			int32_t fileStatRC = -1;
			fileStatRC = omrfile_stat(verboseFile, 0, &buf);
			if (0 == fileStatRC) {
				if (1 == buf.isFile) {
					omrfile_unlink(verboseFile);
				}
			}
		} else {
			for (int32_t seq = 1; seq <= (int32_t)numOfFiles; seq++) {
				char verboseFileSeq[MAX_NAME_LENGTH];
				omrstr_printf(verboseFileSeq, MAX_NAME_LENGTH, "%s.%03zu", verboseFile, seq);
				J9FileStat buf;
				int32_t fileStatRC = -1;
				fileStatRC = omrfile_stat(verboseFileSeq, 0, &buf);
				if (0 > fileStatRC) {
					if (1 != buf.isFile) {
						break;
					}
				}
				omrfile_unlink(verboseFileSeq);
			}
		}
	}
	omrmem_free_memory((void *)verboseFile);

	/* Shut down the dispatcher threads */
	omr_error_t rc = OMR_GC_ShutdownDispatcherThreads(exampleVM->_omrVMThread);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownDispatcherThreads failed, rc=" << rc;

	/* Shut down collector */
	rc = OMR_GC_ShutdownCollector(exampleVM->_omrVMThread);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownCollector failed, rc=" << rc;

	/* Detach from VM */
	rc = OMR_Thread_Free(exampleVM->_omrVMThread);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_Thread_Free failed, rc=" << rc;

	/* Shut down heap */
	rc = OMR_GC_ShutdownHeap(exampleVM->_omrVM);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownHeap failed, rc=" << rc;

	printMemUsed("TearDown()", gcTestEnv->portLib);
}
コード例 #22
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::verifyVerboseGC(pugi::xpath_node_set verboseGCs)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);
	int32_t rt = 0;
	uintptr_t seq = 1;
	size_t numOfNode = verboseGCs.size();
	bool *isFound = (bool *)omrmem_allocate_memory(sizeof(int32_t) * numOfNode, OMRMEM_CATEGORY_MM);
	if (NULL == isFound) {
		rt = 1;
		omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__);
		goto done;
	}
	for (size_t i = 0; i < numOfNode; i++) {
		isFound[i] = false;
	}

	/* Loop through multiple files if rolling log is enabled */
	do {
		pugi::xml_document verboseDoc;
		if (0 == numOfFiles) {
			verboseDoc.load_file(verboseFile);
			omrtty_printf("Parsing verbose log %s:\n", verboseFile);
#if defined(OMRGCTEST_PRINTFILE)
			printFile(verboseFile);
#endif
		} else {
			char currentVerboseFile[MAX_NAME_LENGTH];
			omrstr_printf(currentVerboseFile, MAX_NAME_LENGTH, "%s.%03zu", verboseFile, seq++);
			pugi::xml_parse_result result = verboseDoc.load_file(currentVerboseFile);
			if (pugi::status_file_not_found == result.status) {
				break;
			}
			omrtty_printf("Parsing verbose log %s:\n", currentVerboseFile);
#if defined(OMRGCTEST_PRINTFILE)
			printFile(currentVerboseFile);
#endif
		}

		/* verify each xquery criteria */
		int32_t i = 0;
		for (pugi::xpath_node_set::const_iterator it = verboseGCs.begin(); it != verboseGCs.end(); ++it) {
			const char *xpathNodesStr = it->node().attribute("xpathNodes").value();
			const char *xqueryStr = it->node().attribute("xquery").value();

			pugi::xpath_query resultQuery(xqueryStr);
			if (!resultQuery) {
				rt = 1;
				omrtty_printf("%s:%d Invalid xquery string \"%s\" specified in configuration file.\n", __FILE__, __LINE__, xqueryStr);
				goto done;
			}

			pugi::xpath_query nodeQuery(xpathNodesStr);
			if (!nodeQuery) {
				rt = 1;
				omrtty_printf("%s:%d Invalid xpathNodes string \"%s\" specified in configuration file.\n", __FILE__, __LINE__, xpathNodesStr);
				goto done;
			}

			pugi::xpath_node_set xpathNodes = nodeQuery.evaluate_node_set(verboseDoc);
			if (!xpathNodes.empty()) {
				bool isPassed = true;
				omrtty_printf("Verifying xquery \"%s\" on xpath \"%s\":\n", xqueryStr, xpathNodesStr);
				for (pugi::xpath_node_set::const_iterator it = xpathNodes.begin(); it != xpathNodes.end(); ++it) {
					pugi::xml_node node = it->node();
					if (!resultQuery.evaluate_boolean(node)) {
						rt = 1;
						isPassed = false;
						omrtty_printf("\t*FAILED* on node <%s", node.name());
						for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) {
							omrtty_printf("\t%s=%s", attr.name(), attr.value());
						}
						omrtty_printf(">\n");
					}
				}
				if (isPassed) {
					omrtty_printf("*PASSED*\n");
				}
				isFound[i] = true;
			}
			i += 1;
		}
		omrtty_printf("\n");
	} while (seq <= numOfFiles);

	for (size_t i = 0; i < numOfNode; i++) {
		if (!isFound[i]) {
			rt = 1;
			omrtty_printf("*FAILED* Could not find xpath node \"%s\" in verbose output.\n", verboseGCs[i].node().attribute("xpathNodes").value());
		}
	}

done:
	omrmem_free_memory((void *)isFound);
	return rt;
}
コード例 #23
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::allocationWalker(pugi::xml_node node)
{
	OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM);
	int32_t rt = 0;
	AttributeElem *numOfFieldsElem = NULL;
	AttributeElem *breadthElem = NULL;
	int32_t depth = 0;
	OMRGCObjectType objType = INVALID;

	const char *namePrefixStr = node.attribute("namePrefix").value();
	const char *numOfFieldsStr = node.attribute("numOfFields").value();
	const char *typeStr = node.attribute("type").value();
	const char *breadthStr = node.attribute("breadth").value();
	const char *depthStr = node.attribute("depth").value();

	if (0 != strcmp(node.name(), "object")) {
		/* allow non-object node nested inside allocation? */
		goto done;
	}
	if ((0 == strcmp(namePrefixStr, "")) || (0 == strcmp(typeStr, "")) || (0 == strcmp(numOfFieldsStr, ""))) {
		rt = 1;
		omrtty_printf("%s:%d Invalid XML input: please specify namePrefix, type and numOfFields for object %s.\n", __FILE__, __LINE__, namePrefixStr);
		goto done;
	}
	/* set default value for breadth and depth to 1 */
	if (0 == strcmp(breadthStr, "")) {
		breadthStr = "1";
	}
	if (0 == strcmp(depthStr, "")) {
		depthStr = "1";
	}

	depth = atoi(depthStr);
	objType = parseObjectType(node);
	rt = parseAttribute(&numOfFieldsElem, numOfFieldsStr);
	OMRGCTEST_CHECK_RT(rt)
	rt = parseAttribute(&breadthElem, breadthStr);
	OMRGCTEST_CHECK_RT(rt);

	/* process current xml node, perform allocation for single object or object tree */
	rt = processObjNode(node, namePrefixStr, objType, numOfFieldsElem, breadthElem, depth);
	OMRGCTEST_CHECK_RT(rt);

	/* only single object can contain nested child object */
	if ((0 == strcmp(breadthStr, "1")) && (0 == strcmp(depthStr, "1"))) {
		for (pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) {
			rt = allocationWalker(childNode);
			OMRGCTEST_CHECK_RT(rt);
		}
	}

	/* After the entire garbage tree is allocated, remove garbage root object from the root set
	 * or remove garbage top object from the slot of its parent object. */
	if (GARBAGE_ROOT == objType) {
		for (int32_t i = 0; i < breadthElem->value; i++) {
			char objName[MAX_NAME_LENGTH];
			omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i);
			rt = removeObjectFromRootTable(objName);
			OMRGCTEST_CHECK_RT(rt);
		}
	} else if (GARBAGE_TOP == objType) {
		char parentName[MAX_NAME_LENGTH];
		omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0);
		ObjectEntry *parentEntry;
		rt = objectTable.find(&parentEntry, parentName);
		if (0 != rt) {
			omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
			goto done;
		}
		omrobjectptr_t parentPtr = parentEntry->objPtr;
		for (int32_t i = 0; i < breadthElem->value; i++) {
			char objName[MAX_NAME_LENGTH];
			omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i);
			rt = removeObjectFromParentSlot(objName, parentPtr);
			OMRGCTEST_CHECK_RT(rt);
		}
	}

	/* insert garbage per tree */
	if ((0 == strcmp(gp.frequency, "perRootStruct")) && (ROOT == objType)){
		rt = insertGarbage();
		OMRGCTEST_CHECK_RT(rt);
	}

done:
	freeAttributeList(breadthElem);
	freeAttributeList(numOfFieldsElem);
	return rt;
}
コード例 #24
0
ファイル: omrosbacktrace_impl.c プロジェクト: bjornvar/omr
/* This function takes a thread structure already populated with a backtrace by j9introspect_backtrace_thread
 * and looks up the symbols for the frames. The format of the string generated is:
 * 		symbol_name (statement_id instruction_pointer [module+offset])
 * If it isn't possible to determine any of the items in the string then they are omitted. If no heap is specified
 * then this function will use malloc to allocate the memory necessary for the symbols which must be freed by the caller.
 *
 * @param portLbirary a pointer to an initialized port library
 * @param threadInfo a thread structure populated with a backtrace
 * @param heap a heap from which to allocate any necessary memory. If NULL malloc is used instead.
 *
 * @return the number of frames for which a symbol was constructed.
 */
uintptr_t
omrintrospect_backtrace_symbols_raw(struct OMRPortLibrary *portLibrary,
	J9PlatformThread *threadInfo, J9Heap *heap)
{
	J9PlatformStackFrame *frame;
	int i;

	for (i = 0, frame = threadInfo->callstack; frame != NULL;
		frame = frame->parent_frame, i++) {
		char output_buf[512];
		char *cursor = output_buf;
		Dl_info dlInfo;
		uintptr_t length;
		uintptr_t iar = frame->instruction_pointer;
		uintptr_t symbol_offset = 0;
		uintptr_t module_offset = 0;
		const char *symbol_name = "";
		const char *module_name = "<unknown>";
		short symbol_length = 0;

		memset(&dlInfo, 0, sizeof(Dl_info));

		/* do the symbol resolution while we're here */
		if (dladdr((void*) iar, &dlInfo)) {
			if (dlInfo.dli_sname != NULL) {
				uintptr_t sym = (uintptr_t) dlInfo.dli_saddr;
				symbol_name = dlInfo.dli_sname;
				symbol_length = strlen(symbol_name);
				symbol_offset = iar - (uintptr_t) sym;
			}

			if (dlInfo.dli_fname != NULL) {
				/* strip off the full path if possible */
				module_name = strrchr(dlInfo.dli_fname, '/');
				if (module_name != NULL) {
					module_name++;
				}
				else {
					module_name = dlInfo.dli_fname;
				}
			}

			if (dlInfo.dli_fbase != NULL) {
				/* set the module offset */
				module_offset = iar - (uintptr_t) dlInfo.dli_fbase;
			}
		}

		/* sanity check */
		if (symbol_name == NULL) {
			symbol_name = "";
			symbol_length = 0;
		}

		/* symbol_name+offset (id, instruction_pointer [module+offset]) */
		if (symbol_length > 0) {
			cursor += omrstr_printf(portLibrary, cursor,
				sizeof(output_buf) - (cursor - output_buf), "%.*s",
				symbol_length, symbol_name);
			cursor += omrstr_printf(portLibrary, cursor,
				sizeof(output_buf) - (cursor - output_buf), "+0x%x ",
				symbol_offset);
		}
		cursor += omrstr_printf(portLibrary, cursor,
			sizeof(output_buf) - (cursor - output_buf), "(0x%p",
			frame->instruction_pointer);
		if (module_name[0] != '\0') {
			cursor += omrstr_printf(portLibrary, cursor,
				sizeof(output_buf) - (cursor - output_buf), " [%s+0x%x]",
				module_name, module_offset);
		}
		*(cursor++) = ')';
		*cursor = 0;

		length = (cursor - output_buf) + 1;
		if (heap != NULL) {
			frame->symbol = portLibrary->heap_allocate(portLibrary, heap,
				length);
		}
		else {
			frame->symbol = portLibrary->mem_allocate_memory(portLibrary,
				length, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY);
		}

		if (frame->symbol != NULL) {
			strncpy(frame->symbol, output_buf, length);
		}
		else {
			frame->symbol = NULL;
			if (!threadInfo->error) {
				threadInfo->error = ALLOCATION_FAILURE;
			}
			i--;
		}
	}

	return i;
}
コード例 #25
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
int32_t
GCConfigTest::createFixedSizeTree(omrobjectptr_t *rootObj, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth)
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);
	int32_t rt = 0;
	OMR_VM *omrVMPtr = exampleVM->_omrVM;
	int32_t depth = 1;
	int32_t numOfParents = 1;
	uintptr_t bytesLeft = totalSize;

	if (bytesLeft < objSize) {
		objSize = bytesLeft;
		if (objSize <= 0) {
			return rt;
		}
	}

	/* allocate the root object */
	char *rootObjName = NULL;
	rt = createObject(rootObj, &rootObjName, namePrefixStr, objType, 0, 0, objSize);
	OMRGCTEST_CHECK_RT(rt);
	bytesLeft -= objSize;

	/* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating
	 * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/
	RootEntry rEntry;
	rEntry.name = rootObjName;
	rEntry.rootPtr = *rootObj;
	if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) {
		rt = 1;
		omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__);
		goto done;
	}

	/* create the rest of the tree */
	if (ROOT == objType) {
		objType = NORMAL;
	} else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) {
		objType = GARBAGE_CHILD;
	}
	while (bytesLeft > 0) {
		int32_t nthInRow = 0;
		for (int32_t j = 0; j < numOfParents; j++) {
			char parentName[MAX_NAME_LENGTH];
			omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j);
			ObjectEntry *parentEntry;
			rt = objectTable.find(&parentEntry, parentName);
			if (0 != rt) {
				omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName);
				goto done;
			}
			omrobjectptr_t parent = parentEntry->objPtr;
			GC_ObjectIterator objectIterator(omrVMPtr, parent);
			objectIterator.restore(parentEntry->numOfRef);
			for (int32_t k = 0; k < breadth; k++) {
				if (bytesLeft < objSize) {
					objSize = bytesLeft;
					if (objSize <= 0) {
						goto done;
					}
				}
				omrobjectptr_t obj;
				char *objName = NULL;
				rt = createObject(&obj, &objName, namePrefixStr, objType, depth, nthInRow, objSize);
				OMRGCTEST_CHECK_RT(rt);
				bytesLeft -= objSize;
				nthInRow += 1;
				GC_SlotObject *slotObject = NULL;
				if (NULL != (slotObject = objectIterator.nextSlot())) {
#if defined(OMRGCTEST_DEBUG)
					omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k);
#endif
					slotObject->writeReferenceToSlot(obj);
				} else {
					rt = 1;
					omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName);
					goto done;
				}
			}
			parentEntry->numOfRef += breadth;
		}
		numOfParents = nthInRow;
		depth += 1;
	}

done:
	return rt;
}
コード例 #26
0
ファイル: GCConfigTest.cpp プロジェクト: DanHeidinga/omr
void
GCConfigTest::SetUp()
{
	OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib);

	printMemUsed("Setup()", gcTestEnv->portLib);

	/* Initialize heap and collector */
	MM_StartupManagerTestExample startupManager(exampleVM->_omrVM, GetParam());
	omr_error_t rc = OMR_GC_IntializeHeapAndCollector(exampleVM->_omrVM, &startupManager);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_GC_IntializeHeapAndCollector failed, rc=" << rc;

	/* Attach calling thread to the VM */
	exampleVM->_omrVMThread = NULL;
	rc = OMR_Thread_Init(exampleVM->_omrVM, NULL, &exampleVM->_omrVMThread, "OMRTestThread");
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_Thread_Init failed, rc=" << rc;

	/* Kick off the dispatcher threads */
	rc = OMR_GC_InitializeDispatcherThreads(exampleVM->_omrVMThread);
	ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_GC_InitializeDispatcherThreads failed, rc=" << rc;
	env = MM_EnvironmentBase::getEnvironment(exampleVM->_omrVMThread);

	/* load config file */
	omrtty_printf("Configuration File: %s\n", GetParam());
#if defined(OMRGCTEST_PRINTFILE)
	printFile(GetParam());
#endif
	pugi::xml_parse_result result = doc.load_file(GetParam());
	if (!result) {
		FAIL() << "Failed to load test configuration file (" << GetParam() << ") with error description: " << result.description() << ".";
	}

	/* parse verbose information and initialize verbose manager */
	pugi::xml_node optionNode = doc.select_node("/gc-config/option").node();
	const char *verboseFileNamePrefix = optionNode.attribute("verboseLog").value();
	numOfFiles = (uintptr_t)optionNode.attribute("numOfFiles").as_int();
	uintptr_t numOfCycles = (uintptr_t)optionNode.attribute("numOfCycles").as_int();
	if (0 == strcmp(verboseFileNamePrefix, "")) {
		verboseFileNamePrefix = "VerboseGCOutput";
	}
	verboseFile = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM);
	if (NULL == verboseFile) {
		FAIL() << "Failed to allocate native memory.";
	}
	omrstr_printf(verboseFile, MAX_NAME_LENGTH, "%s_%d_%lld.xml", verboseFileNamePrefix, omrsysinfo_get_pid(), omrtime_current_time_millis());
	verboseManager = MM_VerboseManager::newInstance(env, exampleVM->_omrVM);
	verboseManager->configureVerboseGC(exampleVM->_omrVM, verboseFile, numOfFiles, numOfCycles);
	omrtty_printf("Verbose File: %s\n", verboseFile);
#if defined(OMRGCTEST_DEBUG)
	omrtty_printf("Verbose GC log name: %s; numOfFiles: %d; numOfCycles: %d.\n", verboseFile, numOfFiles, numOfCycles);
#endif
	verboseManager->enableVerboseGC();
	verboseManager->setInitializedTime(omrtime_hires_clock());

	/* create object table */
	objectTable.create();

	/* create root table */
	exampleVM->rootTable = hashTableNew(
		gcTestEnv->portLib, OMR_GET_CALLSITE(), 0, sizeof(RootEntry), 0, 0, OMRMEM_CATEGORY_MM,
		rootTableHashFn, rootTableHashEqualFn, NULL, NULL);
}