gc_common.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,731 行 · 第 1/4 页
C
1,731 行
}/* * WARNING: GC-unsafe allocator. Use CVMID_allocNewInstance() in GC-safe * code. */CVMObject*CVMgcAllocNewInstance(CVMExecEnv* ee, CVMClassBlock* cb){ CVMObject* newInstance; CVMassert(CVMcbCheckRuntimeFlag(cb, LINKED)); CVMassert(cb != CVMsystemClass(java_lang_Class));#ifdef CVM_TEST_FAILED_ALLOCATION_GC /* Pretend to fail allocation to trigger a GC if necessary: */ failedAllocGCCount = ++failedAllocGCCount % CVM_NUM_ALLOCATIONS_PER_GC; if (failedAllocGCCount == 0) { newInstance = NULL; goto allocFailed; }#endif if (CVMgcPrivateLockHeapUnsafe(ee)) {#ifdef CVM_FASTALLOC_STATS slowLockCount++;#endif newInstance = doNewInstance(ee, cb, CVMgcimplAllocObject); CVMgcPrivateUnlockHeap(ee); } else {#ifdef CVM_FASTALLOC_STATS verySlowLockCount++;#endif newInstance = NULL; }#ifdef CVM_TEST_FAILED_ALLOCATION_GCallocFailed:#endif if (newInstance == NULL) { CVMObjectICell* theCell = CVMallocationRetryICell(ee); ObjAllocWrap aw; aw.cb = cb; stopTheWorldAndGCWithRetry(ee, CVMcbInstanceSize(cb), newInstanceRetry, &aw); newInstance = CVMID_icellDirect(ee, theCell); CVMID_icellSetNull(theCell); } if (CVMcbIs(cb, FINALIZABLE) && (newInstance != NULL)) { newInstance = handleFinalizableAllocation(ee, newInstance); CVMtraceWeakrefs(("WR: Registered a finalizable %C\n", cb)); } /* * check that a new object starts at an aligned address */ CVMassert((CVMAddr)CVMalignAddrUp(newInstance) == (CVMAddr)newInstance); return newInstance;} /* * WARNING: GC-unsafe allocator. Use CVMID_allocNewInstance() in GC-safe * code. */CVMObject*CVMgcAllocNewClassInstance(CVMExecEnv* ee, CVMClassBlock* cbOfJavaLangClass){ CVMObject* newInstance;#ifdef CVM_TEST_FAILED_ALLOCATION_GC /* Pretend to fail allocation to trigger a GC if necessary: */ failedAllocGCCount = ++failedAllocGCCount % CVM_NUM_ALLOCATIONS_PER_GC; if (failedAllocGCCount == 0) { newInstance = NULL; goto allocFailed; }#endif if (CVMgcPrivateLockHeapUnsafe(ee)) {#ifdef CVM_FASTALLOC_STATS slowLockCount++;#endif newInstance = doNewInstance(ee, CVMsystemClass(java_lang_Class), CVMgcimplAllocObject); CVMgcPrivateUnlockHeap(ee); } else {#ifdef CVM_FASTALLOC_STATS verySlowLockCount++;#endif newInstance = NULL; }#ifdef CVM_TEST_FAILED_ALLOCATION_GCallocFailed:#endif /* * If GC-unsafe allocation worked, then no worries. Just fill in */ /* Fill in the back-pointer */ if (newInstance != NULL) { /* * Access member variable of type 'int' * and cast it to a native pointer. The java type 'int' only garanties * 32 bit, but because one slot is used as storage space and * a slot is 64 bit on 64 bit platforms, it is possible * to store a native pointer without modification of * java source code. This assumes that all places in the C-code * are catched which set/get this member. */ CVMD_fieldWriteAddr(newInstance, CVMoffsetOfjava_lang_Class_classBlockPointer, (CVMAddr)cbOfJavaLangClass); } else { CVMObjectICell* theCell = CVMallocationRetryICell(ee); ObjAllocWrap aw; aw.cb = cbOfJavaLangClass; stopTheWorldAndGCWithRetry(ee, CVMcbInstanceSize(CVMsystemClass(java_lang_Class)), newClassInstanceRetry, &aw); newInstance = CVMID_icellDirect(ee, theCell); CVMID_icellSetNull(theCell); } CVMassert(newInstance == NULL || CVMobjectGetClass(newInstance)==CVMsystemClass(java_lang_Class)); return newInstance;} typedef struct ArrAllocWrap { CVMJavaInt arrayObjectSize; CVMClassBlock* arrayCb; CVMJavaInt arrayLen;} ArrAllocWrap;static voidnewArrayRetry(CVMExecEnv* ee, void* data){ ArrAllocWrap* aw = (ArrAllocWrap*)data; CVMObjectICell* theCell = CVMallocationRetryICell(ee); CVMArrayOfAnyType* newArray; CVMassert(CVMID_icellIsNull(theCell)); newArray = doNewArray(ee, aw->arrayObjectSize, aw->arrayCb, aw->arrayLen, CVMgcimplRetryAllocationAfterGC); CVMID_icellSetDirectWithAssertion(CVM_TRUE, theCell, (CVMObject*)newArray);}/* * Allocate heap array of length 'len'. The array type is 'arrayCb'. */CVMArrayOfAnyType*CVMgcAllocNewArray(CVMExecEnv* ee, CVMBasicType typeCode, CVMClassBlock* arrayCb, CVMJavaInt arrayLen){ CVMArrayOfAnyType* newArray; CVMJavaInt arrayObjectSize; CVMassert(CVMbasicTypeSizes[typeCode] != 0); /* * The size of the heap object to accommodate this array */ /* * Keep the correct alignment for the next object/array. */ arrayObjectSize = CVMalignAddrUp(CVMoffsetof(CVMArrayOfAnyType, elems) + CVMbasicTypeSizes[typeCode] * arrayLen); newArray = CVMgcAllocNewArrayWithInstanceSize(ee, arrayObjectSize, arrayCb, arrayLen); return newArray;}/* * Allocate heap array of length 'len'. The array type is 'arrayCb'. */CVMArrayOfAnyType*CVMgcAllocNewArrayWithInstanceSize(CVMExecEnv* ee, CVMJavaInt arrayObjectSize, CVMClassBlock* arrayCb, CVMJavaInt arrayLen){ CVMArrayOfAnyType* newArray; CVMassert(CVMcbCheckRuntimeFlag(arrayCb, LINKED));#ifdef CVM_TEST_FAILED_ALLOCATION_GC /* Pretend to fail allocation to trigger a GC if necessary: */ failedAllocGCCount = ++failedAllocGCCount % CVM_NUM_ALLOCATIONS_PER_GC; if (failedAllocGCCount == 0) { newArray = NULL; goto allocFailed; }#endif if (CVMgcPrivateLockHeapUnsafe(ee)) {#ifdef CVM_FASTALLOC_STATS slowLockCount++;#endif newArray = doNewArray(ee, arrayObjectSize, arrayCb, arrayLen, CVMgcimplAllocObject); CVMgcPrivateUnlockHeap(ee); } else {#ifdef CVM_FASTALLOC_STATS verySlowLockCount++;#endif newArray = NULL; }#ifdef CVM_TEST_FAILED_ALLOCATION_GCallocFailed:#endif if (newArray == NULL) { CVMObjectICell* theCell = CVMallocationRetryICell(ee); ArrAllocWrap aw; aw.arrayObjectSize = arrayObjectSize; aw.arrayCb = arrayCb; aw.arrayLen = arrayLen; stopTheWorldAndGCWithRetry(ee, arrayObjectSize, newArrayRetry, &aw); newArray = (CVMArrayOfAnyType*)CVMID_icellDirect(ee, theCell); CVMID_icellSetNull(theCell); } return newArray;}/* * WARNING: GC-unsafe allocator. Use CVMID_allocNewInstance() in GC-safe * code. */static CVMObject*doNewInstance(CVMExecEnv* ee, CVMClassBlock* cb, CVMObject* (*allocateInstance)(CVMExecEnv* ee, CVMUint32 numBytes)){ CVMObject* newInstance; newInstance = (*allocateInstance)(ee, CVMcbInstanceSize(cb)); /* * Caller responsible for handling failed allocation */ if (newInstance == NULL) { return NULL; } /* Zero out object */ /* %comment f003 */ memset((void*)newInstance, 0, CVMcbInstanceSize(cb)); /* Set header of new object */ newInstance->hdr.clas = cb; /* sync type 0 */ CVMobjMonitorSet(newInstance, 0, CVM_LOCKSTATE_UNLOCKED); /* * Make sure that our notion of what the default header word is * matches that created by the above CVMobjMonitorSet */ CVMassert(CVMobjectVariousWord(newInstance) == CVM_OBJECT_DEFAULT_VARIOUS_WORD);#ifdef CVM_JVMPI /* Notify the profiler of an object allocation: */ if (CVMjvmpiEventObjectAllocIsEnabled()) { /* NOTE: When we get here, we may or may not be GC unsafe. If we're not GC unsafe, then we must be in a GC safe all condition which precludes GC from running. JVMPI will become GC safe when calling the profiling agent, but GC will be disabled for that duration. So, the new object will be safe from GC. */ CVMjvmpiPostObjectAllocEvent(ee, newInstance); }#endif /* CVM_JVMPI */ CVMtraceGcAlloc(("GC_COMMON: Allocated <%C> (size=%d) => 0x%x\n", cb, CVMcbInstanceSize(cb), newInstance)); /* * check that a new object starts at an aligned address */ CVMassert((CVMAddr)CVMalignAddrUp(newInstance) == (CVMAddr)newInstance); return newInstance;}/* * Allocate heap array of length 'len'. The array type is 'arrayCb'. */static CVMArrayOfAnyType*doNewArray(CVMExecEnv* ee, CVMJavaInt arrayObjectSize, CVMClassBlock* arrayCb, CVMJavaInt arrayLen, CVMObject* (*allocateInstance)(CVMExecEnv* ee, CVMUint32 numBytes)){ CVMArrayOfAnyType* newArray; CVMassert(arrayCb != 0); if (arrayLen >= (1 << 28)) { /* Don't bother. arrayObjectSize would overflow for this if the array type was a long or a double. The chances of such an allocation being satisfied are slim to none anyway. */ return NULL; } newArray = (CVMArrayOfAnyType*)(*allocateInstance)(ee, arrayObjectSize); /* * Caller responsible for handling failed allocation */ if (newArray == NULL) { return NULL; } /* Zero out object */ memset((void*)newArray, 0, arrayObjectSize); /* Set header of new object */ newArray->hdr.clas = arrayCb; /* sync type 0 */ CVMobjMonitorSet(newArray, 0, CVM_LOCKSTATE_UNLOCKED); /* * Make sure that our notion of what the default header word is * matches that created by the above CVMobjMonitorSet */ CVMassert(CVMobjectVariousWord(newArray) == CVM_OBJECT_DEFAULT_VARIOUS_WORD); newArray->length = arrayLen;#ifdef CVM_JVMPI /* Notify the profiler of an object allocation: */ if (CVMjvmpiEventObjectAllocIsEnabled()) { /* NOTE: JVMPI will become GC safe when calling the profiling agent, but GC will be disabled for that duration: */ CVMjvmpiPostObjectAllocEvent(ee, (CVMObject *) newArray); }#endif /* CVM_JVMPI */ CVMtraceGcAlloc(("GC_COMMON: Allocated <%C> (size=%d, len=%d) => 0x%x\n", arrayCb, arrayObjectSize, arrayLen, newArray)); /* * check that a new object starts at an aligned address */ CVMassert((CVMAddr)CVMalignAddrUp(newArray) == (CVMAddr)newArray); return newArray;}#if 0voidCVMnullFrameScanner(CVMFrame* frame, CVMStackChunk* chunk, CVMRefCallbackFunc callback, void* data){ CVMassert(!CVMframeIsTransition(frame) && !CVMframeIsJava(frame) && !CVMframeIsJNI(frame)); return;}#endif/* * The following is private to the root scanner, and is used to cart * arguments to CVMclassScanCallback */struct CVMClassScanOptions { CVMGCOptions *gcOpts; CVMRefCallbackFunc callback; void* data;};typedef struct CVMClassScanOptions CVMClassScanOptions;/* * This callback is used for keeping system classes live. */static voidCVMclassScanSystemClassCallback(CVMExecEnv* ee, CVMClassBlock* cb, void* opts){ CVMClassScanOptions* options = (CVMClassScanOptions*)opts; if (CVMcbClassLoader(cb) == NULL) { /* This makes sure a class is not scanned in a cycle */#if defined(CVM_INSPECTOR) || defined(CVM_JVMPI) || defined(CVM_JVMTI) { CVMGCOptions *gcOpts = options->gcOpts; if (gcOpts->isProfilingPass) { CVMGCProfilingInfo *info = (CVMGCProfilingInfo *)options->data; info->u.clazz.cb = cb; } }#endif CVMscanClassIfNeeded(ee, cb, options->callback, options->data); }}/* * Clear the scanned flag of a classblock */static voidCVMclassClearScannedFlagCallback(CVMExecEnv* ee, CVMClassBlock* cb, void* opts){ CVMtraceGcScan(("GC: Clearing marked bit of class %C (0x%x)\n", cb, cb)); CVMcbClearGcScanned(cb);}/* * Process special objects with liveness info from a particular GC * implementation. This covers special scans like string intern table, * weak references and monitor structures. */voidCVMgcProcessSpecialWithLivenessInfo(CVMExecEnv* ee, CVMGCOptions* gcOpts, CVMRefLivenessQueryFunc isLive, void* isLiveData, CVMRefCallbackFunc transitiveScanner, void* transitiveScannerData){ CVMgcProcessWeakrefWithLivenessInfo(ee, gcOpts, isLive, isLiveData, transitiveScanner, transitiveScannerData); CVMgcProcessInternedStringsWithLivenessInfo(ee, gcOpts, isLive, isLiveData, transitiveScanner, transitiveScannerData); CVMgcProcessSpecialWithLivenessInfoWithoutWeakRefs(ee, gcOpts, isLive, isLiveData, transitiveScanner, transitiveScannerData);}/* Process weak references with liveness info from a particular GC * implementation. * isLive - a predicate that returns true if an object is strongly referenced * transitiveScanner - a callback that marks an object and all its children */voidCVMgcProcessWeakrefWithLivenessInfo(CVMExecEnv* ee, CVMGCOptions* gcOpts, CVMRefLivenessQueryFunc isLive, void* isLiveData,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?