/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Garbage-collecting allocator.
*/
#ifndef _DALVIK_ALLOC_ALLOC
#define _DALVIK_ALLOC_ALLOC
#include <stdlib.h>
/*
* Initialization.
*/
bool dvmGcStartup(void);
bool dvmCreateStockExceptions(void);
bool dvmGcStartupAfterZygote(void);
void dvmGcShutdown(void);
/*
* Do any last-minute preparation before we call fork() for the first time.
*/
bool dvmGcPreZygoteFork(void);
/*
* Basic allocation function.
*
* The new object will be added to the "tracked alloc" table unless
* flags is ALLOC_DONT_TRACK or ALLOC_NO_GC.
*
* Returns NULL and throws an exception on failure.
*/
void* dvmMalloc(size_t size, int flags);
/*
* Allocate a new object.
*
* The new object will be added to the "tracked alloc" table unless
* flags is ALLOC_DONT_TRACK or ALLOC_NO_GC.
*
* Returns NULL and throws an exception on failure.
*/
Object* dvmAllocObject(ClassObject* clazz, int flags);
/*
* Clear flags set by dvmMalloc. Pass in a bit mask of the flags that
* should be cleared.
*/
void dvmClearAllocFlags(Object* obj, int mask);
/* flags for dvmMalloc */
enum {
ALLOC_DEFAULT = 0x00,
ALLOC_NO_GC = 0x01, /* do not garbage collect this object */
ALLOC_DONT_TRACK = 0x02, /* don't add to internal tracking list */
ALLOC_FINALIZABLE = 0x04, /* call finalize() before freeing */
// ALLOC_NO_MOVE?
};
/*
* Call when a request is so far off that we can't call dvmMalloc(). Throws
* an exception with the specified message.
*/
void dvmThrowBadAllocException(const char* msg);
/*
* Track an object reference that is currently only visible internally.
* This is called automatically by dvmMalloc() unless ALLOC_DONT_TRACK
* is set.
*
* The "self" argument is allowed as an optimization; it may be NULL.
*/
void dvmAddTrackedAlloc(Object* obj, Thread* self);
/*
* Remove an object from the internal tracking list.
*
* Does nothing if "obj" is NULL.
*
* The "self" argument is allowed as an optimization; it may be NULL.
*/
void dvmReleaseTrackedAlloc(Object* obj, Thread* self);
/*
* Like dvmReleaseTrackedAlloc, but only does the release if "allocFlags"
* indicates that it's necessary to do so.
*/
INLINE void dvmReleaseTrackedAllocIFN(Object* obj, Thread* self, int allocFlags)
{
if ((allocFlags & (ALLOC_NO_GC|ALLOC_DONT_TRACK)) == 0)
dvmReleaseTrackedAlloc(obj, self);
}
/*
* Returns true iff <obj> points to a valid allocated object.
*/
bool dvmIsValidObject(const Object* obj);
/*
* Create a copy of an object.
*
* The new object will be added to the "tracked alloc" table.
*/
Object* dvmCloneObject(Object* obj);
/*
* Validate the object pointer. Returns "false" and throws an exception if
* "obj" is null or invalid.
*
* This may be used in performance critical areas as a null-pointer check;
* anything else here should be for debug builds only. In particular, for
* "release" builds we want to skip the call to dvmIsValidObject() -- the
* classfile validation will screen out code that puts invalid data into
* object reference registers.
*/
INLINE int dvmValidateObject(Object* obj)
{
if (obj == NULL) {
dvmThrowException("Ljava/lang/NullPointerException;", NULL);
return false;
}
#ifdef WITH_EXTRA_OBJECT_VALIDATION
if (!dvmIsValidObject(obj)) {
dvmAbort();
dvmThrowException("Ljava/lang/InternalError;",
"VM detected invalid object ptr");
return false;
}
#endif
#ifndef NDEBUG
/* check for heap corruption */
if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
dvmAbort();
dvmThrowException("Ljava/lang/InternalError;",
"VM detected invalid object class ptr");
return false;
}
#endif
return true;
}
/*
* Determine the exact number of GC heap bytes used by an object. (Internal
* to heap code except for debugging.)
*/
size_t dvmObjectSizeInHeap(const Object* obj);
/*
* Gets the current ideal heap utilization, represented as a number
* between zero and one.
*/
float dvmGetTargetHeapUtilization(void);
/*
* Sets the new ideal heap utilization, represented as a number
* between zero and one.
*/
void dvmSetTargetHeapUtilization(float newTarget);
/*
* If set is true, sets the new minimum heap size to size; always
* returns the current (or previous) size. If size is zero,
* removes the current minimum constraint (if present).
*/
size_t dvmMinimumHeapSize(size_t size, bool set);
/*
* Updates the internal count of externally-allocated memory. If there's
* enough room for that memory, returns true. If not, returns false and
* does not update the count.
*
* May cause a GC as a side-effect.
*/
bool dvmTrackExternalAllocation(size_t n);
/*
* Reduces the internal count of externally-allocated memory.
*/
void dvmTrackExternalFree(size_t n);
/*
* Returns the number of externally-allocated bytes being tracked by
* dvmTrackExternalAllocation/Free().
*/
size_t dvmGetExternalBytesAllocated(void);
#endif /*_DALVIK_ALLOC_ALLOC*/