vector.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 380 行

C
380
字号
/* * @(#)Vector.c	1.14 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/interpreter.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/common_exceptions.h"#if 0#include "generated/offsets/java_util_Vector.h"#include "generated/offsets/java_util_AbstractList.h"#endif#if 0#undef FIELD_READ_ELEMENTDATA#define FIELD_READ_ELEMENTDATA(obj, val)         \    CVMD_fieldReadRef(                           \        obj,                                     \        CVMoffsetOfjava_util_Vector_elementData, \        val)#undef FIELD_READ_ELEMENTCOUNT#define FIELD_READ_ELEMENTCOUNT(obj, val)         \    CVMD_fieldReadInt(                            \        obj,                                      \        CVMoffsetOfjava_util_Vector_elementCount, \        val)#undef FIELD_WRITE_ELEMENTDATA#define FIELD_WRITE_ELEMENTDATA(obj, val)        \    CVMD_fieldWriteRef(                          \        obj,                                     \        CVMoffsetOfjava_util_Vector_elementData, \        val);#undef FIELD_WRITE_ELEMENTCOUNT#define FIELD_WRITE_ELEMENTCOUNT(obj, val)        \    CVMD_fieldWriteInt(                           \        obj,                                      \        CVMoffsetOfjava_util_Vector_elementCount, \        val);#endif#if 0/*  * Helper routine that implements the unsynchronized  * semantics of ensureCapacity. *  * Note: This routine may block and initiate GC. */static voidCVMensureCapacityHelper(CVMExecEnv* ee, CVMObjectICell *thisICell,                        CVMJavaInt minCapacity){    CVMObject *thisObject = CVMID_icellDirect(ee, thisICell);    CVMObject *elementDataObject;    CVMJavaInt oldCapacity;    FIELD_READ_ELEMENTDATA(thisObject, elementDataObject);    /* NULL check. */    if (elementDataObject == NULL) {        CVMthrowNullPointerException(ee, NULL);        return;    }        oldCapacity = CVMD_arrayGetLength((CVMArrayOfRef *)elementDataObject);    if (minCapacity > oldCapacity) {        CVMArrayOfRef *newData;        CVMJavaInt newCapacity;        CVMJavaInt capacityIncrement;        CVMJavaInt elementCount;        /* Calculate the new capacity */        CVMD_fieldReadInt(thisObject,                          CVMoffsetOfjava_util_Vector_capacityIncrement,                          capacityIncrement);        newCapacity = (capacityIncrement > 0) ?            (oldCapacity + capacityIncrement) : (oldCapacity * 2);        if (newCapacity < minCapacity) {            newCapacity = minCapacity;        }        /* Allocate an array with the new capacity */         /* NOTE: CVMgcAllocNewArray may block and initiate GC. */        newData = (CVMArrayOfRef *)CVMgcAllocNewArray(            ee, CVM_T_CLASS,             (CVMClassBlock*)CVMbasicTypeArrayClassblocks[CVM_T_CLASS],             newCapacity);        if (newData == NULL) {            CVMthrowOutOfMemoryError(ee, NULL);            return;        }        /*          * Copy the contents from the old array to          * the new array, then set elementData to be         * the new one.          */        thisObject = CVMID_icellDirect(ee, thisICell);        FIELD_READ_ELEMENTDATA(thisObject, elementDataObject);        /*          * Get the number of existing elements. Can't trust         * the number though.         */        FIELD_READ_ELEMENTCOUNT(thisObject, elementCount);        if (elementCount > oldCapacity) {            CVMthrowArrayIndexOutOfBoundsException(ee, NULL);            return;         }        CVMD_arrayCopyRef((CVMArrayOfRef *)elementDataObject, 0,                           newData, 0, elementCount);        FIELD_WRITE_ELEMENTDATA(thisObject, (CVMObject *)newData);    }}#endif#if 0/* * Class:       java/util/Vector * Method:      ensureCapacityHelper * Signature:   (I)V * * This implements the unsynchronized semantics of ensureCapacity. * Synchronized methods in Vector class can internally call this * method for ensuring capacity without incurring the cost of an * extra synchronization. */CNIEXPORT CNIResultCodeCNIjava_util_Vector_ensureCapacityHelper(CVMExecEnv* ee,                                         CVMStackVal32 *arguments,                                         CVMMethodBlock **p_mb){    CVMObjectICell *thisICell = &arguments[0].j.r;    CVMJavaInt minCapacity = arguments[1].j.i;    /* CNI policy: offer a gc-safe checkpoint */    CVMD_gcSafeCheckPoint(ee, {}, {});    /* Call helper routine, which may throw exception */    CVMensureCapacityHelper(ee, thisICell, minCapacity);    if (CVMexceptionOccurred(ee)) {        return CNI_EXCEPTION;    }    return CNI_VOID;}#endif#if 0/* * Class:       java/util/Vector * Method:      elementAt * Signature:   (I)Ljava/lang/Object; */CNIEXPORT CNIResultCodeCNIjava_util_Vector_elementAt(CVMExecEnv* ee, CVMStackVal32 *arguments,                              CVMMethodBlock **p_mb){    CVMObjectICell *thisICell = &arguments[0].j.r;    CVMJavaInt index = arguments[1].j.i;    CVMObject *thisObject;      CVMJavaInt elementCount;    CVMObject *elementDataObject;    CVMObject *theElementObject;    CVMArrayOfRef * elementData;    CVMJavaInt elementDataLen;    /* CNI policy: offer a gc-safe checkpoint */    CVMD_gcSafeCheckPoint(ee, {}, {});    /*      * NOTE: This is a synchronized method. The interpreter      * loop does not take care of synchronization for CNI      * method. So we need to do it here.     */    if (!CVMfastTryLock(ee, CVMID_icellDirect(ee, thisICell))) {        /* May become GC-safe */        if (!CVMobjectLock(ee, thisICell)) {            CVMthrowOutOfMemoryError(ee, NULL);            return CNI_EXCEPTION;        }    }    thisObject = CVMID_icellDirect(ee, thisICell);    FIELD_READ_ELEMENTDATA(thisObject, elementDataObject);    /* NULL check. */    if (elementDataObject == NULL) {        /* Unlock the object before return */        if (!CVMfastTryUnlock(ee, thisObject)) {            if (!CVMobjectUnlock(ee, thisICell)) {                CVMthrowIllegalMonitorStateException(ee,                    "current thread not owner");                return CNI_EXCEPTION;            }        }        CVMthrowNullPointerException(ee, NULL);        return CNI_EXCEPTION;     }    FIELD_READ_ELEMENTCOUNT(thisObject, elementCount);    elementData = (CVMArrayOfRef *)elementDataObject;      /*      * Check array bounds. We can't trust elementCount since elementData     * and elementCount are protected fields. They can be reset in a     * subclass.     */    elementDataLen = CVMD_arrayGetLength(elementData);     if (index >= elementCount || index >= elementDataLen) {        /* Unlock the object before return */        if (!CVMfastTryUnlock(ee, thisObject)) {            if (!CVMobjectUnlock(ee, thisICell)) {                CVMthrowIllegalMonitorStateException(ee,                    "current thread not owner");                return CNI_EXCEPTION;            }        }        if (elementCount != elementDataLen) {            elementCount = elementDataLen;         }        CVMthrowArrayIndexOutOfBoundsException(ee, "%d >= %d",                                               index, elementCount);        return CNI_EXCEPTION;    }else if (index < 0) {        /* Unlock the object before return */        if (!CVMfastTryUnlock(ee, thisObject)) {            if (!CVMobjectUnlock(ee, thisICell)) {                CVMthrowIllegalMonitorStateException(ee,                    "current thread not owner");                return CNI_EXCEPTION;            }        }        CVMthrowArrayIndexOutOfBoundsException(ee, "%d < 0", index);        return CNI_EXCEPTION;    }     CVMD_arrayReadRef(elementData, index, theElementObject);     CVMID_icellSetDirect(ee, &arguments[0].j.r, theElementObject);    /* Unlock the object before return */    if (!CVMfastTryUnlock(ee, thisObject)) {        if (!CVMobjectUnlock(ee, thisICell)) {            CVMthrowIllegalMonitorStateException(ee,                "current thread not owner");            return CNI_EXCEPTION;        }    }    return CNI_SINGLE; }#endif#if 0/* * Class:       java/util/Vector * Method:      addElement * Signature:   (Ljava/lang/Object;)V */CNIEXPORT CNIResultCodeCNIjava_util_Vector_addElement(CVMExecEnv* ee, CVMStackVal32 *arguments,                               CVMMethodBlock **p_mb){    CVMObjectICell *thisICell = &arguments[0].j.r;    CVMObjectICell *objICell = &arguments[1].j.r;    CVMObject *thisObject;    CVMObject *obj;    CVMObject *elementDataObject;    CVMJavaInt modCount;    CVMJavaInt elementCount;    /* CNI policy: offer a gc-safe checkpoint */    CVMD_gcSafeCheckPoint(ee, {}, {});    /* Note: This is a synchronized method */    if (!CVMfastTryLock(ee, CVMID_icellDirect(ee, thisICell))) {         /* CVMobjectLock may become GC-safe */         if (!CVMobjectLock(ee, thisICell)) {             CVMthrowOutOfMemoryError(ee, NULL);             return CNI_EXCEPTION;         }    }    thisObject = CVMID_icellDirect(ee, thisICell);    /* Increment modCount */    CVMD_fieldReadInt(thisObject,                      CVMoffsetOfjava_util_AbstractList_modCount,                      modCount);    modCount ++;    CVMD_fieldWriteInt(thisObject,                       CVMoffsetOfjava_util_AbstractList_modCount,                       modCount);    /* Get elementCount */    FIELD_READ_ELEMENTCOUNT(thisObject, elementCount);    elementCount ++;    /*      * Ensure capacity. May become GC-safe.      * May throw exception.     */    CVMensureCapacityHelper(ee, thisICell, elementCount);    /* Check exception */    if (CVMexceptionOccurred(ee)) {        /* Unlock the object before return */        if (!CVMfastTryUnlock(ee, CVMID_icellDirect(ee, thisICell))) {            if (!CVMobjectUnlock(ee, thisICell)) {                CVMthrowIllegalMonitorStateException(ee,                    "current thread not owner");            }        }        return CNI_EXCEPTION;    }        /* Add the new element */    thisObject = CVMID_icellDirect(ee, thisICell);    obj = CVMID_icellDirect(ee, objICell);    /*      * We don't need to do NULL check here since CVMensureCapacityHelper     * already did it for us.     */    FIELD_READ_ELEMENTDATA(thisObject, elementDataObject);    CVMD_arrayWriteRef((CVMArrayOfRef *)elementDataObject,                       elementCount - 1,                       obj);    /* Don't forget write back elementCount and elementData*/    FIELD_WRITE_ELEMENTCOUNT(thisObject, elementCount);    FIELD_WRITE_ELEMENTDATA(thisObject, elementDataObject);    /* Unlock the object before return */    if (!CVMfastTryUnlock(ee, thisObject)) {        if (!CVMobjectUnlock(ee, thisICell)) {            CVMthrowIllegalMonitorStateException(ee,                "current thread not owner");            return CNI_EXCEPTION;        }    }     return CNI_VOID;}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?