001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.mm.mmtk;
014
015import org.jikesrvm.VM;
016import org.jikesrvm.scheduler.RVMThread;
017import org.jikesrvm.util.Services;
018import org.vmmagic.pragma.*;
019
020@Uninterruptible
021public final class Strings extends org.mmtk.vm.Strings {
022
023  @Override
024  public void write(char [] c, int len) {
025    VM.sysWrite(c, len);
026  }
027
028  @Override
029  public void writeThreadId(char [] c, int len) {
030    VM.tsysWrite(c, len);
031  }
032
033  @Override
034  public int copyStringToChars(String str, char [] dst,
035                               int dstBegin, int dstEnd) {
036    if (!VM.runningVM)
037      return naiveCopyStringToChars(str, dst, dstBegin, dstEnd);
038    else
039      return safeCopyStringToChars(str, dst, dstBegin, dstEnd);
040  }
041
042  /**
043   * Copies characters from the string into the character array.
044   * Thread switching is disabled during this method's execution.
045   * <p>
046   * <b>TODO:</b> There are special memory management semantics here that
047   * someone should document.
048   *
049   * @param str the source string
050   * @param dst the destination array
051   * @param dstBegin the start offset in the destination array
052   * @param dstEnd the index after the last character in the
053   * destination to copy to
054   * @return the number of characters copied.
055   */
056  private int safeCopyStringToChars(String str, char [] dst,
057                                    int dstBegin, int dstEnd) {
058    if (VM.VerifyAssertions) VM._assert(VM.runningVM);
059    // FIXME Why do we need to disable thread switching here, in uninterruptible code??
060    RVMThread.getCurrentThread().disableYieldpoints();
061    char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str);
062    int str_length = java.lang.JikesRVMSupport.getStringLength(str);
063    int str_offset = java.lang.JikesRVMSupport.getStringOffset(str);
064    int n = (dstBegin + str_length <= dstEnd) ? str_length : (dstEnd - dstBegin);
065    for (int i = 0; i < n; i++) {
066      Services.setArrayNoBarrier(dst, dstBegin + i, str_backing[str_offset + i]);
067    }
068    RVMThread.getCurrentThread().enableYieldpoints();
069    return n;
070  }
071  /**
072   * Copies characters from the string into the character array.
073   * Thread switching is disabled during this method's execution.
074   *
075   * @param str the source string
076   * @param dst the destination array
077   * @param dstBegin the start offset in the destination array
078   * @param dstEnd the index after the last character in the
079   * destination to copy to
080   * @return the number of characters copied.
081   */
082  @UninterruptibleNoWarn
083  private int naiveCopyStringToChars(String str, char [] dst,
084                                     int dstBegin, int dstEnd) {
085    if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
086    int len = str.length();
087    int n = (dstBegin + len <= dstEnd) ? len : (dstEnd - dstBegin);
088    for (int i = 0; i < n; i++)
089      Services.setArrayNoBarrier(dst, dstBegin + i, str.charAt(i));
090    return n;
091  }
092}