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}