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 + -
显示快捷键?