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     */
013    package org.jikesrvm.mm.mmtk;
014    
015    import org.jikesrvm.VM;
016    import org.jikesrvm.Services;
017    import org.jikesrvm.scheduler.RVMThread;
018    
019    import org.vmmagic.pragma.*;
020    
021    @Uninterruptible
022    public final class Strings extends org.mmtk.vm.Strings {
023      /**
024       * Log a message.
025       *
026       * @param c character array with message starting at index 0
027       * @param len number of characters in message
028       */
029      public void write(char [] c, int len) {
030        VM.sysWrite(c, len);
031      }
032    
033      /**
034       * Log a thread identifier and a message.
035       *
036       * @param c character array with message starting at index 0
037       * @param len number of characters in message
038       */
039      public void writeThreadId(char [] c, int len) {
040        VM.tsysWrite(c, len);
041      }
042    
043      /**
044       * Copies characters from the string into the character array.
045       * Thread switching is disabled during this method's execution.
046       *
047       * @param str the source string
048       * @param dst the destination array
049       * @param dstBegin the start offset in the desination array
050       * @param dstEnd the index after the last character in the
051       * destination to copy to
052       * @return the number of characters copied.
053       */
054      public int copyStringToChars(String str, char [] dst,
055                                   int dstBegin, int dstEnd) {
056        if (!VM.runningVM)
057          return naiveCopyStringToChars(str, dst, dstBegin, dstEnd);
058        else
059          return safeCopyStringToChars(str, dst, dstBegin, dstEnd);
060      }
061      /**
062       * Copies characters from the string into the character array.
063       * Thread switching is disabled during this method's execution.
064       * <p>
065       * <b>TODO:</b> There are special memory management semantics here that
066       * someone should document.
067       *
068       * @param str the source string
069       * @param dst the destination array
070       * @param dstBegin the start offset in the destination array
071       * @param dstEnd the index after the last character in the
072       * destination to copy to
073       * @return the number of characters copied.
074       */
075      private int safeCopyStringToChars(String str, char [] dst,
076                                        int dstBegin, int dstEnd) {
077        if (VM.VerifyAssertions) VM._assert(VM.runningVM);
078        // FIXME Why do we need to disable thread switching here, in uninterruptible code??
079        RVMThread.getCurrentThread().disableYieldpoints();
080        char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str);
081        int str_length = java.lang.JikesRVMSupport.getStringLength(str);
082        int str_offset = java.lang.JikesRVMSupport.getStringOffset(str);
083        int n = (dstBegin + str_length <= dstEnd) ? str_length : (dstEnd - dstBegin);
084        for (int i = 0; i < n; i++) {
085          Services.setArrayNoBarrier(dst, dstBegin + i, str_backing[str_offset+i]);
086        }
087        RVMThread.getCurrentThread().enableYieldpoints();
088        return n;
089      }
090      /**
091       * Copies characters from the string into the character array.
092       * Thread switching is disabled during this method's execution.
093       *
094       * @param str the source string
095       * @param dst the destination array
096       * @param dstBegin the start offset in the destination array
097       * @param dstEnd the index after the last character in the
098       * destination to copy to
099       * @return the number of characters copied.
100       */
101      @UninterruptibleNoWarn
102      private int naiveCopyStringToChars(String str, char [] dst,
103                                         int dstBegin, int dstEnd) {
104        if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
105        int len = str.length();
106        int n = (dstBegin + len <= dstEnd) ? len : (dstEnd - dstBegin);
107        for (int i = 0; i < n; i++)
108          Services.setArrayNoBarrier(dst, dstBegin + i, str.charAt(i));
109        return n;
110      }
111    }