/*
* 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.
*/
/*
* Class loader.
*/
#ifndef _DALVIK_OO_CLASS
#define _DALVIK_OO_CLASS
/*
* The classpath and bootclasspath differ in that only the latter is
* consulted when looking for classes needed by the VM. When searching
* for an arbitrary class definition, we start with the bootclasspath,
* look for optional packages (a/k/a standard extensions), and then try
* the classpath.
*
* In Dalvik, a class can be found in one of three ways:
* - as a "loose" .class file in a directory
* - as a .class file held in a JAR archive
* - in a .dex file
*
* These three may be freely intermixed in a classpath specification.
* Ordering is significant. (Currently only ".dex" is supported directly
* by the VM.)
*/
typedef struct ClassPathEntry {
enum {
kCpeUnknown = 0,
kCpeDir,
kCpeJar,
kCpeDex,
kCpeLastEntry /* used as sentinel at end of array */
} kind;
char* fileName;
void* ptr; /* JarFile* or DexFile* */
} ClassPathEntry;
bool dvmClassStartup(void);
void dvmClassShutdown(void);
bool dvmPrepBootClassPath(bool isNormalStart);
/*
* Boot class path accessors, for class loader getResources().
*/
int dvmGetBootPathSize(void);
StringObject* dvmGetBootPathResource(const char* name, int idx);
void dvmDumpBootClassPath(void);
/*
* Determine whether "path" is a member of "cpe".
*/
bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path);
/*
* Set clazz->serialNumber to the next available value.
*/
void dvmSetClassSerialNumber(ClassObject* clazz);
/*
* Find the class with the given descriptor. Load it if it hasn't already
* been.
*
* "loader" is the initiating class loader.
*/
ClassObject* dvmFindClass(const char* descriptor, Object* loader);
ClassObject* dvmFindClassNoInit(const char* descriptor, Object* loader);
/*
* Like dvmFindClass, but only for system classes.
*/
ClassObject* dvmFindSystemClass(const char* descriptor);
ClassObject* dvmFindSystemClassNoInit(const char* descriptor);
/*
* Find a loaded class by descriptor. Returns the first one found.
* Because there can be more than one if class loaders are involved,
* this is not an especially good API. (Currently only used by the
* debugger and "checking" JNI.)
*
* "descriptor" should have the form "Ljava/lang/Class;" or
* "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form
* class name.
*/
ClassObject* dvmFindLoadedClass(const char* descriptor);
/*
* Load the named class (by descriptor) from the specified DEX file.
* Used by class loaders to instantiate a class object from a
* VM-managed DEX.
*/
ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor,
Object* classLoader);
/*
* Link a loaded class. Normally done as part of one of the "find class"
* variations, this is only called explicitly for synthetic class
* generation (e.g. reflect.Proxy).
*/
bool dvmLinkClass(ClassObject* clazz, bool classesResolved);
/*
* Determine if a class has been initialized.
*/
INLINE bool dvmIsClassInitialized(const ClassObject* clazz) {
return (clazz->status == CLASS_INITIALIZED);
}
bool dvmIsClassInitializing(const ClassObject* clazz);
/*
* Initialize a class.
*/
bool dvmInitClass(ClassObject* clazz);
/*
* Retrieve the system class loader.
*/
Object* dvmGetSystemClassLoader(void);
/*
* Utility functions.
*/
ClassObject* dvmLookupClass(const char* descriptor, Object* loader,
bool unprepOkay);
void dvmFreeClassInnards(ClassObject* clazz);
bool dvmAddClassToHash(ClassObject* clazz);
void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader);
bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader);
/*
* Update method's "nativeFunc" and "insns" after native method resolution.
*/
void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func,
const u2* insns);
/*
* Set the method's "registerMap" field.
*/
void dvmSetRegisterMap(Method* method, const RegisterMap* pMap);
/*
* Make a method's DexCode (which includes the bytecode) read-write or
* read-only. The conversion to read-write may involve making a new copy
* of the DexCode, and in normal operation the read-only state is not
* actually enforced.
*/
void dvmMakeCodeReadWrite(Method* meth);
void dvmMakeCodeReadOnly(Method* meth);
/*
* During DEX optimizing, add an extra DEX to the bootstrap class path.
*/
void dvmSetBootPathExtraDex(DvmDex* pDvmDex);
/*
* Debugging.
*/
void dvmDumpClass(const ClassObject* clazz, int flags);
void dvmDumpAllClasses(int flags);
void dvmDumpLoaderStats(const char* msg);
int dvmGetNumLoadedClasses();
#ifdef PROFILE_FIELD_ACCESS
void dvmDumpFieldAccessCounts(void);
#endif
/* flags for dvmDumpClass / dvmDumpAllClasses */
#define kDumpClassFullDetail 1
#define kDumpClassClassLoader (1 << 1)
#define kDumpClassInitialized (1 << 2)
/*
* Store a copy of the method prototype descriptor string
* for the given method into the given DexStringCache, returning the
* stored string for convenience.
*/
INLINE char* dvmCopyDescriptorStringFromMethod(const Method* method,
DexStringCache *pCache)
{
const char* result =
dexProtoGetMethodDescriptor(&method->prototype, pCache);
return dexStringCacheEnsureCopy(pCache, result);
}
/*
* Compute the number of argument words (u4 units) required by the
* given method's prototype. For example, if the method descriptor is
* "(IJ)D", this would return 3 (one for the int, two for the long;
* return value isn't relevant).
*/
INLINE int dvmComputeMethodArgsSize(const Method* method)
{
return dexProtoComputeArgsSize(&method->prototype);
}
/*
* Compare the two method prototypes. The two prototypes are compared
* as if by strcmp() on the result of dexProtoGetMethodDescriptor().
*/
INLINE int dvmCompareMethodProtos(const Method* method1,
const Method* method2)
{
return dexProtoCompare(&method1->prototype, &method2->prototype);
}
/*
* Compare the two method prototypes, considering only the parameters
* (i.e. ignoring the return types). The two prototypes are compared
* as if by strcmp() on the result of dexProtoGetMethodDescriptor().
*/
INLINE int dvmCompareMethodParameterProtos(const Method* method1,
const Method* method2)
{
return dexProtoCompareParameters(&method1->prototype, &method2->prototype);
}
/*
* Compare the two method names and prototypes, a la strcmp(). The
* name is considered the "major" order and the prototype the "minor"
* order. The prototypes are compared as if by dexProtoGetMethodDescriptor().
*/
int dvmCompareMethodNamesAndProtos(const Method* method1,
const Method* method2);
/*
* Compare the two method names and prototypes, a la strcmp(), ignoring
* the return type. The name is considered the "major" order and the
* prototype the "minor" order. The prototypes are compared as if by
* dexProtoGetMethodDescriptor().
*/
int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
const Method* method2);
/*
* Compare a method descriptor string with the prototype of a method,
* as if by converting the descriptor to a DexProto and comparing it
* with dexProtoCompare().
*/
INLINE int dvmCompareDescriptorAndMethodProto(const char* descriptor,
const Method* method)
{
// Sense is reversed.
return -dexProtoCompareToDescriptor(&method->prototype, descriptor);
}
/*
* Compare a (name, prototype) pair with the (name, prototype) of
* a method, a la strcmp(). The name is considered the "major" order and
* the prototype the "minor" order. The descriptor and prototype are
* compared as if by dvmCompareDescriptorAndMethodProto().
*/
int dvmCompareNameProtoAndMethod(const char* name,
const DexProto* proto, const Method* method);
/*
* Compare a (name, method descriptor) pair with the (name, prototype) of
* a method, a la strcmp(). The name is considered the "major" order and
* the prototype the "minor" order. The descriptor and prototype are
* compared as if by dvmCompareDescriptorAndMethodProto().
*/
int dvmCompareNameDescriptorAndMethod(const char* name,
const char* descriptor, const Method* method);
#endif /*_DALVIK_OO_CLASS*/