Exemplo n.º 1
0
TEST(string, __memcmp16) {
  StringTestState<unsigned short> state(SMALL);

  for (size_t i = 0; i < state.n; i++) {
    for (size_t j = 0; j < POS_ITER; j++) {
      state.NewIteration();

      unsigned short mask = 0xffff;
      unsigned short c1 = rand() & mask;
      unsigned short c2 = rand() & mask;

      std::fill(state.ptr1, state.ptr1 + state.MAX_LEN, c1);
      std::fill(state.ptr2, state.ptr2 + state.MAX_LEN, c1);

      int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]);
      state.ptr2[pos] = c2;

      int expected = (static_cast<unsigned short>(c1) - static_cast<unsigned short>(c2));
      int actual = __memcmp16(state.ptr1, state.ptr2, (size_t) state.MAX_LEN);

      ASSERT_EQ(expected, actual);
    }
  }
}
Exemplo n.º 2
0
/*
 * public boolean equals(Object anObject)
 */
bool javaLangString_equals(u4 arg0, u4 arg1, u4 arg2, u4 arg3,
    JValue* pResult)
{
    /*
     * Null reference check on "this".
     */
    if ((Object*) arg0 == NULL) {
        dvmThrowNullPointerException(NULL);
        return false;
    }

    /* quick test for comparison with itself */
    if (arg0 == arg1) {
        pResult->i = true;
        return true;
    }

    /*
     * See if the other object is also a String.
     *
     * str.equals(null) is expected to return false, presumably based on
     * the results of the instanceof test.
     */
    if (arg1 == 0 || ((Object*) arg0)->clazz != ((Object*) arg1)->clazz) {
        pResult->i = false;
        return true;
    }

    /*
     * This would be simpler and faster if we promoted StringObject to
     * a full representation, lining up the C structure fields with the
     * actual object fields.
     */
    int thisCount, thisOffset, compCount, compOffset;
    ArrayObject* thisArray;
    ArrayObject* compArray;
    const u2* thisChars;
    const u2* compChars;

    /* quick length check */
    thisCount = dvmGetFieldInt((Object*) arg0, STRING_FIELDOFF_COUNT);
    compCount = dvmGetFieldInt((Object*) arg1, STRING_FIELDOFF_COUNT);
    if (thisCount != compCount) {
        pResult->i = false;
        return true;
    }

    /*
     * You may, at this point, be tempted to pull out the hashCode fields
     * and compare them.  If both fields have been initialized, and they
     * are not equal, we can return false immediately.
     *
     * However, the hashCode field is often not set.  If it is set,
     * there's an excellent chance that the String is being used as a key
     * in a hashed data structure (e.g. HashMap).  That data structure has
     * already made the comparison and determined that the hashes are equal,
     * making a check here redundant.
     *
     * It's not clear that checking the hashes will be a win in "typical"
     * use cases.  We err on the side of simplicity and ignore them.
     */

    thisOffset = dvmGetFieldInt((Object*) arg0, STRING_FIELDOFF_OFFSET);
    compOffset = dvmGetFieldInt((Object*) arg1, STRING_FIELDOFF_OFFSET);
    thisArray = (ArrayObject*)
        dvmGetFieldObject((Object*) arg0, STRING_FIELDOFF_VALUE);
    compArray = (ArrayObject*)
        dvmGetFieldObject((Object*) arg1, STRING_FIELDOFF_VALUE);
    thisChars = ((const u2*)(void*)thisArray->contents) + thisOffset;
    compChars = ((const u2*)(void*)compArray->contents) + compOffset;

#ifdef HAVE__MEMCMP16
    pResult->i = (__memcmp16(thisChars, compChars, thisCount) == 0);
# ifdef CHECK_MEMCMP16
    int otherRes = (memcmp(thisChars, compChars, thisCount * 2) == 0);
    if (pResult->i != otherRes) {
        badMatch((StringObject*) arg0, (StringObject*) arg1,
            otherRes, pResult->i, "equals-1");
    }
# endif
#else
    /*
     * Straightforward implementation, examining 16 bits at a time.  The
     * direction of the loop doesn't matter, and starting at the end may
     * give us an advantage when comparing certain types of strings (e.g.
     * class names).
     *
     * We want to go forward for benchmarks against __memcmp16 so we get a
     * meaningful comparison when the strings don't match (could also test
     * with palindromes).
     */
    int i;
    //for (i = 0; i < thisCount; i++)
    for (i = thisCount-1; i >= 0; --i)
    {
        if (thisChars[i] != compChars[i]) {
            pResult->i = false;
            return true;
        }
    }
    pResult->i = true;
#endif

    return true;
}
Exemplo n.º 3
0
/*
 * public int compareTo(String s)
 */
bool javaLangString_compareTo(u4 arg0, u4 arg1, u4 arg2, u4 arg3,
    JValue* pResult)
{
    /*
     * Null reference check on "this".  Normally this is performed during
     * the setup of the virtual method call.  We need to do it before
     * anything else.  While we're at it, check out the other string,
     * which must also be non-null.
     */
    if ((Object*) arg0 == NULL || (Object*) arg1 == NULL) {
        dvmThrowNullPointerException(NULL);
        return false;
    }

    /* quick test for comparison with itself */
    if (arg0 == arg1) {
        pResult->i = 0;
        return true;
    }

    /*
     * This would be simpler and faster if we promoted StringObject to
     * a full representation, lining up the C structure fields with the
     * actual object fields.
     */
    int thisCount, thisOffset, compCount, compOffset;
    ArrayObject* thisArray;
    ArrayObject* compArray;
    const u2* thisChars;
    const u2* compChars;
    int minCount, countDiff;

    thisCount = dvmGetFieldInt((Object*) arg0, STRING_FIELDOFF_COUNT);
    compCount = dvmGetFieldInt((Object*) arg1, STRING_FIELDOFF_COUNT);
    countDiff = thisCount - compCount;
    minCount = (countDiff < 0) ? thisCount : compCount;
    thisOffset = dvmGetFieldInt((Object*) arg0, STRING_FIELDOFF_OFFSET);
    compOffset = dvmGetFieldInt((Object*) arg1, STRING_FIELDOFF_OFFSET);
    thisArray = (ArrayObject*)
        dvmGetFieldObject((Object*) arg0, STRING_FIELDOFF_VALUE);
    compArray = (ArrayObject*)
        dvmGetFieldObject((Object*) arg1, STRING_FIELDOFF_VALUE);
    thisChars = ((const u2*)(void*)thisArray->contents) + thisOffset;
    compChars = ((const u2*)(void*)compArray->contents) + compOffset;

#ifdef HAVE__MEMCMP16
    /*
     * Use assembly version, which returns the difference between the
     * characters.  The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
     * because the interpreter converts the characters to 32-bit integers
     * *without* sign extension before it subtracts them (which makes some
     * sense since "char" is unsigned).  So what we get is the result of
     * 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
     */
    int otherRes = __memcmp16(thisChars, compChars, minCount);
# ifdef CHECK_MEMCMP16
    int i;
    for (i = 0; i < minCount; i++) {
        if (thisChars[i] != compChars[i]) {
            pResult->i = (s4) thisChars[i] - (s4) compChars[i];
            if (pResult->i != otherRes) {
                badMatch((StringObject*) arg0, (StringObject*) arg1,
                    pResult->i, otherRes, "compareTo");
            }
            return true;
        }
    }
# endif
    if (otherRes != 0) {
        pResult->i = otherRes;
        return true;
    }

#else
    /*
     * Straightforward implementation, examining 16 bits at a time.  Compare
     * the characters that overlap, and if they're all the same then return
     * the difference in lengths.
     */
    int i;
    for (i = 0; i < minCount; i++) {
        if (thisChars[i] != compChars[i]) {
            pResult->i = (s4) thisChars[i] - (s4) compChars[i];
            return true;
        }
    }
#endif

    pResult->i = countDiff;
    return true;
}