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 }