ccmintrinsics.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,291 行 · 第 1/3 页

C
1,291
字号
/* * @(#)ccmintrinsics.c	1.18 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/ccee.h"#include "javavm/include/common_exceptions.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/interpreter.h"#include "javavm/include/jit/jit.h"#include "javavm/include/porting/jit/jit.h"#include "javavm/include/jit/jitintrinsic.h"#include "javavm/include/jit/jitirnode.h"#include "fdlibm.h"#include "javavm/export/jvm.h"#include "generated/offsets/java_lang_String.h"#ifdef CVMJIT_INTRINSICS#undef MIN#define MIN(x,y) ((x) < (y) ? (x) : (y))#undef FIELD_READ_COUNT#define FIELD_READ_COUNT(obj, val) \    CVMD_fieldReadInt(obj,         \        CVMoffsetOfjava_lang_String_count, val)#undef FIELD_READ_VALUE#define FIELD_READ_VALUE(obj, val) \    CVMD_fieldReadRef(obj,         \        CVMoffsetOfjava_lang_String_value, val)#undef FIELD_READ_OFFSET#define FIELD_READ_OFFSET(obj, val) \    CVMD_fieldReadInt(obj,          \        CVMoffsetOfjava_lang_String_offset, val)#ifndef CVMCCM_DISABLE_SHARED_STRING_CHARAT_INTRINSIC/* Purpose: Intrinsic version of String.charAt(). */CVMJavaCharCVMCCMintrinsic_java_lang_String_charAt(CVMCCExecEnv *ccee,                                        CVMObject *self, CVMJavaInt index){    CVMJavaInt count;    CVMJavaInt offset;    CVMObject *value;    CVMJavaChar c;        CVMassert(CVMD_isgcUnsafe(CVMcceeGetEE(ccee)));    FIELD_READ_COUNT(self, count);        /* The following also checks for (index < 0) by casting index into a       CVMUint32 before comparing against count: */    if (((CVMUint32)index) >= count) {        goto errorCase;    }    FIELD_READ_VALUE(self, value);    FIELD_READ_OFFSET(self, offset);    CVMD_arrayReadChar((CVMArrayOfChar*)value, index+offset, c);    return c;errorCase:    /* NOTE: We put the error case at the bottom to increase cache locality       for the non-error case above. */    {        CVMExecEnv *ee = CVMcceeGetEE(ccee);        CVMCCMruntimeLazyFixups(ee);        CVMthrowStringIndexOutOfBoundsException(            ee, "String index out of range: %d", index);        CVMCCMhandleException(ccee);    }    return 0;}#endif#ifndef CVMCCM_DISABLE_SHARED_STRING_COMPARETO_INTRINSIC/* Purpose: Intrinsic version of String.compareTo(). */CVMJavaIntCVMCCMintrinsic_java_lang_String_compareTo(CVMCCExecEnv *ccee,                                           CVMObject *self, CVMObject *other){    CVMObject *value1, *value2;    CVMJavaInt n, offset1, offset2;    CVMJavaInt len1, len2;    CVMassert(CVMD_isgcUnsafe(CVMcceeGetEE(ccee)));    /* If other is null, a NullPointerException should be thrown.  The       caller is responsible for NULL checking self. */    if (other == NULL) {        goto errorCase;    }    /* Get count, value, and offset */    FIELD_READ_COUNT(self, len1);    FIELD_READ_COUNT(other, len2);    n = MIN(len1, len2);    FIELD_READ_VALUE(self, value1);    FIELD_READ_VALUE(other, value2);    FIELD_READ_OFFSET(self, offset1);    FIELD_READ_OFFSET(other, offset2);    /* Now compare */#ifdef CVMGC_HAS_NO_CHAR_READ_BARRIER    {        CVMJavaChar *c1p, *c2p, *last1;        CVMAddr scratch;        /* NOTE: CVMDprivate_arrayElemLoc() is used here because we know for           sure that we won't be becoming GC safe during the string comparison           below.  This is only done as a speed optimization here, and should           not be used elsewhere without careful consideration of the           conequences.        */        c1p = (CVMJavaChar *)	    CVMDprivate_arrayElemLoc((CVMArrayOfChar*)value1, offset1);        c2p = (CVMJavaChar *)	    CVMDprivate_arrayElemLoc((CVMArrayOfChar*)value2, offset2);        last1 = c1p + n;        scratch = ((CVMAddr)c1p ^ (CVMAddr)c2p) & 0x3;        if (scratch == 0) {            CVMUint32 *ilast1;	    CVMUint32 *i1p, *i2p;            /* c1p and c2p are both equally aligned.  Do aligned               comparison: */            /* First compare the leading char is appropriate: */            if ((((CVMAddr)c1p & 0x3) != 0) && (c1p != last1)) {                CVMJavaChar c1 = *c1p++;                CVMJavaChar c2 = *c2p++;                if (c1 != c2) {                    return (CVMJavaInt)c1 - (CVMJavaInt)c2;                }            }            /* Now c1p and c2p should be word aligned: */            ilast1 = (CVMUint32 *)((CVMAddr)last1 & ~0x3);	    /* Avoid ++ on a cast pointer by assigning them here */	    i1p = (CVMUint32*)c1p;	    i2p = (CVMUint32*)c2p;            while (i1p < ilast1) {                if (*i1p++ != *i2p++) {                    goto intMismatch;                }            }	    /*	     * set c1p, c2p to current pointers in case we need them	     * for doing character compares.	     */	    c1p = (CVMJavaChar *)i1p;	    c2p = (CVMJavaChar *)i2p;            /* Compare the trailing char if appropriate: */            goto doCharCompare;        intMismatch:            /* Back up the int comparison and go let the char comparison take               care of it: */            c1p = (CVMJavaChar *)(i1p - 1);            c2p = (CVMJavaChar *)(i2p - 1);            goto doCharCompare;        } else {        doCharCompare:            /* c1p and c2p are not equally aligned.  Do unaligned comparison:*/            while (c1p < last1) {                CVMJavaChar c1 = *c1p++;                CVMJavaChar c2 = *c2p++;                if (c1 != c2) {                    return (CVMJavaInt)c1 - (CVMJavaInt)c2;                }            }            return len1 - len2;        }    }#else    {        CVMJavaInt last = offset1 + n;        if (offset1 == offset2) {            /* This is an optimized case */            while (offset1 < last) {                CVMJavaChar c1, c2;                CVMD_arrayReadChar((CVMArrayOfChar*)value1, offset1, c1);                CVMD_arrayReadChar((CVMArrayOfChar*)value2, offset1, c2);                if (c1 != c2) {                    return (CVMJavaInt)c1 - (CVMJavaInt)c2;                }                offset1++;            }        } else {            while (offset1 < last) {                CVMJavaChar c1, c2;                CVMD_arrayReadChar((CVMArrayOfChar*)value1, offset1, c1);                CVMD_arrayReadChar((CVMArrayOfChar*)value2, offset2, c2);                if (c1 != c2) {                    return (CVMJavaInt)c1 - (CVMJavaInt)c2;                }                offset1++;                offset2++;            }        }    }    return len1 - len2;#endiferrorCase:    /* NOTE: We put the error case at the bottom to increase cache locality       for the non-error case above. */    {        CVMExecEnv *ee = CVMcceeGetEE(ccee);        CVMCCMruntimeLazyFixups(ee);        CVMthrowNullPointerException(ee, NULL);        CVMCCMhandleException(ccee);    }    return 0;}#endif#ifndef CVMCCM_DISABLE_SHARED_STRING_EQUALS_INTRINSIC/* Purpose: Intrinsic version of String.equals(). */CVMJavaBooleanCVMCCMintrinsic_java_lang_String_equals(CVMObject *self, CVMObject *other){    CVMassert(CVMD_isgcUnsafe(CVMgetEE()));    if (self == other) {        /* Same object, return true directly. */        return CVM_TRUE;    } else if (other == NULL) {        /*          * If anObject is null, the Java version          * always returns False, unless this String         * is also null, in which case a NullPointerException         * is already thrown by the interpreter.         */        return CVM_FALSE;     }    if (CVMobjectGetClass(other) == CVMsystemClass(java_lang_String)) {        CVMJavaInt count1, count2;        FIELD_READ_COUNT(self, count1);        FIELD_READ_COUNT(other, count2);        if (count1 == count2) {            CVMObject *value1, *value2;            CVMJavaInt offset1, offset2;            FIELD_READ_VALUE(self, value1);            FIELD_READ_VALUE(other, value2);            FIELD_READ_OFFSET(self, offset1);             FIELD_READ_OFFSET(other, offset2);#ifdef CVMGC_HAS_NO_CHAR_READ_BARRIER            {                CVMJavaChar *c1p, *c2p, *last1;                CVMAddr scratch;                /* NOTE: CVMDprivate_arrayElemLoc() is used here because we                   know for sure that we won't be becoming GC safe during the                   string comparison below.  This is only done as a speed                   optimization here, and should not be used elsewhere without                   careful consideration of the conequences.                */                c1p = (CVMJavaChar *)		    CVMDprivate_arrayElemLoc((CVMArrayOfChar*)value1, offset1);                c2p = (CVMJavaChar *)		    CVMDprivate_arrayElemLoc((CVMArrayOfChar*)value2, offset2);                last1 = c1p + count1;                scratch = ((CVMAddr)c1p ^ (CVMAddr)c2p) & 0x3;                if (scratch == 0) {                  CVMUint32 *ilast1;		  CVMUint32 *i1p, *i2p;                    /* c1 and c2 are both equally aligned.  Do aligned                       comparison: */                    /* First compare the leading char is appropriate: */                    if ((((CVMAddr)c1p & 0x3) != 0) && (c1p != last1)) {                        if (*c1p++ != *c2p++) {                            return CVM_FALSE;                        }                    }                    /* Now c1 and c2 should be word aligned: */		    /* Avoid ++ on a cast pointer by assigning them here */		    i1p = (CVMUint32*)c1p;		    i2p = (CVMUint32*)c2p;                    ilast1 = (CVMUint32 *)((CVMAddr)last1 & ~0x3);                    while (i1p < ilast1) {                        if (*i1p++ != *i2p++) {                            return CVM_FALSE;                        }                    }                    /* Compare the trailing char if appropriate: */                    if ((CVMJavaChar*)i1p < last1){ 			c1p = (CVMJavaChar*)i1p;			c2p = (CVMJavaChar*)i2p;			if (*c1p != *c2p) {			    return CVM_FALSE;			}                    }                    return CVM_TRUE;                } else {                    /* c1 and c2 are not equally aligned.  Do unaligned                       comparison: */                    while (c1p < last1) {                        if (*c1p++ != *c2p++) {                            return CVM_FALSE;                        }                    }                    return CVM_TRUE;                }            }#else            while (count1-- > 0) {                CVMJavaChar c1, c2;                CVMD_arrayReadChar((CVMArrayOfChar*)value1, offset1, c1);                CVMD_arrayReadChar((CVMArrayOfChar*)value2, offset2, c2);                if (c1 != c2) {                    return CVM_FALSE;                }                offset1++;                offset2++;            }            return CVM_TRUE;#endif        }     }    return CVM_FALSE;}#endif#ifndef CVMCCM_DISABLE_SHARED_STRING_GETCHARS_INTRINSIC/* Purpose: Intrinsic version of String.getChars(). */voidCVMCCMintrinsic_java_lang_String_getChars(CVMCCExecEnv *ccee,                                          CVMObject *self,                                          CVMJavaInt srcBegin,                                          CVMJavaInt srcEnd,                                          CVMArrayOfChar *dst,                                          CVMJavaInt dstBegin){    CVMJavaInt count;    CVMJavaInt offset;    CVMJavaInt dstLen = 0;    CVMObject *value;    CVMClassBlock *dstCb = NULL;    CVMassert(CVMD_isgcUnsafe(CVMcceeGetEE(ccee)));    FIELD_READ_COUNT(self, count);    if (srcEnd > count || srcBegin < 0 || srcBegin > srcEnd) {        goto errorCase;    }    /* Check NULL for dstObject */    if (dst == NULL) {        goto errorCase;    }    /* Check whether dst is a char array */    dstCb = CVMobjectGetClass(dst);    if (!CVMisArrayClass(dstCb) || CVMarrayBaseType(dstCb) != CVM_T_CHAR) {        goto errorCase;    }    /* Array bounds checking for dst*/    dstLen = CVMD_arrayGetLength(dst);    if ((((CVMUint32)dstBegin) > dstLen) ||         (dstBegin + srcEnd - srcBegin > dstLen)) {        goto errorCase;    }    FIELD_READ_VALUE(self, value);    FIELD_READ_OFFSET(self, offset);    CVMD_arrayCopyChar((CVMArrayOfChar*)value, offset + srcBegin,                        dst, dstBegin, srcEnd - srcBegin);     return;errorCase:    {        CVMExecEnv *ee = CVMcceeGetEE(ccee);        CVMCCMruntimeLazyFixups(ee);            if (srcBegin < 0) {            CVMthrowStringIndexOutOfBoundsException(                ee, "String index out of range: %d", srcBegin);        } else if (srcEnd > count) {            CVMthrowStringIndexOutOfBoundsException(                ee, "String index out of range: %d", srcEnd);        } else if (srcBegin > srcEnd) {            CVMthrowStringIndexOutOfBoundsException(                ee, "String index out of range: %d", srcEnd - srcBegin);        } else if (dst == NULL) {            CVMthrowNullPointerException(ee, NULL);        } else if (!CVMisArrayClass(dstCb) ||                   CVMarrayBaseType(dstCb) != CVM_T_CHAR) {            CVMthrowArrayStoreException(ee, NULL);        } else if (dstBegin < 0 || dstBegin > dstLen ||                    dstBegin + srcEnd - srcBegin > dstLen) {

⌨️ 快捷键说明

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