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      @Override
025      public void write(char [] c, int len) {
026        VM.sysWrite(c, len);
027      }
028    
029      @Override
030      public void writeThreadId(char [] c, int len) {
031        VM.tsysWrite(c, len);
032      }
033    
034    
035      @Override
036      public int copyStringToChars(String str, char [] dst,
037                                   int dstBegin, int dstEnd) {
038        if (!VM.runningVM)
039          return naiveCopyStringToChars(str, dst, dstBegin, dstEnd);
040        else
041          return safeCopyStringToChars(str, dst, dstBegin, dstEnd);
042      }
043    
044      /**
045       * Copies characters from the string into the character array.
046       * Thread switching is disabled during this method's execution.
047       * <p>
048       * <b>TODO:</b> There are special memory management semantics here that
049       * someone should document.
050       *
051       * @param str the source string
052       * @param dst the destination array
053       * @param dstBegin the start offset in the destination array
054       * @param dstEnd the index after the last character in the
055       * destination to copy to
056       * @return the number of characters copied.
057       */
058      private int safeCopyStringToChars(String str, char [] dst,
059                                        int dstBegin, int dstEnd) {
060        if (VM.VerifyAssertions) VM._assert(VM.runningVM);
061        // FIXME Why do we need to disable thread switching here, in uninterruptible code??
062        RVMThread.getCurrentThread().disableYieldpoints();
063        char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str);
064        int str_length = java.lang.JikesRVMSupport.getStringLength(str);
065        int str_offset = java.lang.JikesRVMSupport.getStringOffset(str);
066        int n = (dstBegin + str_length <= dstEnd) ? str_length : (dstEnd - dstBegin);
067        for (int i = 0; i < n; i++) {
068          Services.setArrayNoBarrier(dst, dstBegin + i, str_backing[str_offset+i]);
069        }
070        RVMThread.getCurrentThread().enableYieldpoints();
071        return n;
072      }
073      /**
074       * Copies characters from the string into the character array.
075       * Thread switching is disabled during this method's execution.
076       *
077       * @param str the source string
078       * @param dst the destination array
079       * @param dstBegin the start offset in the destination array
080       * @param dstEnd the index after the last character in the
081       * destination to copy to
082       * @return the number of characters copied.
083       */
084      @UninterruptibleNoWarn
085      private int naiveCopyStringToChars(String str, char [] dst,
086                                         int dstBegin, int dstEnd) {
087        if (VM.VerifyAssertions) VM._assert(!VM.runningVM);
088        int len = str.length();
089        int n = (dstBegin + len <= dstEnd) ? len : (dstEnd - dstBegin);
090        for (int i = 0; i < n; i++)
091          Services.setArrayNoBarrier(dst, dstBegin + i, str.charAt(i));
092        return n;
093      }
094    }