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 }