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.gcspy; 014 015 import org.mmtk.utility.Constants; 016 import org.mmtk.utility.Log; 017 import org.mmtk.plan.Plan; 018 import org.mmtk.vm.VM; 019 020 import org.jikesrvm.runtime.Magic; 021 import static org.jikesrvm.runtime.SysCall.sysCall; 022 import org.jikesrvm.classloader.RVMArray; 023 import org.jikesrvm.objectmodel.ObjectModel; 024 import org.jikesrvm.runtime.RuntimeEntrypoints; 025 026 import org.vmmagic.unboxed.*; 027 import org.vmmagic.pragma.*; 028 029 /** 030 * This class provides generally useful methods. 031 */ 032 @Uninterruptible public class Util extends org.mmtk.vm.gcspy.Util implements Constants { 033 private static final boolean DEBUG_ = false; 034 public static final int KILOBYTE = 1024; 035 public static final int MEGABYTE = 1024 * 1024; 036 037 @Override 038 public final Address malloc(int size) { 039 if (org.jikesrvm.VM.BuildWithGCSpy) { 040 Address rtn = sysCall.sysMalloc(size); 041 if (rtn.isZero()) VM.assertions.fail("GCspy malloc failure"); 042 return rtn; 043 } else 044 return Address.zero(); 045 } 046 047 @Override 048 public final void free(Address addr) { 049 if (org.jikesrvm.VM.BuildWithGCSpy) 050 if (!addr.isZero()) 051 sysCall.sysFree(addr); 052 } 053 054 /** 055 * Convert a String to a 0-terminated array of bytes 056 * <p> 057 * WARNING: we call out to String.length and String.charAt, both of 058 * which are interruptible. We protect these calls with a 059 * swLock/swUnlock mechanism, as per VM.sysWrite on String. 060 * 061 * @param str The string to convert 062 * @return The address of a null-terminated array in C-space 063 */ 064 @Override 065 public final Address getBytes(String str) { 066 if (org.jikesrvm.VM.BuildWithGCSpy) { 067 if (str == null) 068 return Address.zero(); 069 070 if (DEBUG_) { 071 Log.write("getBytes: "); Log.write(str); Log.write("->"); 072 } 073 074 // Grab some memory sufficient to hold the null terminated string, 075 // rounded up to an integral number of ints. 076 char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str); 077 int str_length = java.lang.JikesRVMSupport.getStringLength(str); 078 int str_offset = java.lang.JikesRVMSupport.getStringOffset(str); 079 int size = (str_length + 4) & -4; 080 Address rtn = malloc(size); 081 082 // Write the string into it, one byte at a time (dodgy conversion) 083 for (int i=0; i < str_length; i++) { 084 rtn.store((byte)str_backing[str_offset+i], Offset.fromIntSignExtend(i)); 085 } 086 // Zero rest of byte[] 087 for (int i=str_length; i < size; i++) { 088 rtn.store((byte)0, Offset.fromIntSignExtend(i-str_offset)); 089 } 090 if (DEBUG_) { 091 sysCall.sysWriteBytes(2/*SysTraceFd*/, rtn, size); Log.write("\n"); 092 } 093 return rtn; 094 } else { 095 return Address.zero(); 096 } 097 } 098 099 @Override 100 public final void formatSize(Address buffer, int size) { 101 if (org.jikesrvm.VM.BuildWithGCSpy) 102 sysCall.gcspyFormatSize(buffer, size); 103 } 104 105 106 @Override 107 public final Address formatSize(String format, int bufsize, int size) { 108 if (org.jikesrvm.VM.BuildWithGCSpy) { 109 // - sprintf(tmp, "Current Size: %s\n", gcspy_formatSize(size)); 110 Address tmp = malloc(bufsize); 111 Address formattedSize = malloc(bufsize); 112 Address currentSize = getBytes(format); 113 formatSize(formattedSize, size); 114 sprintf(tmp, currentSize, formattedSize); 115 return tmp; 116 } else { 117 return Address.zero(); 118 } 119 } 120 121 @Override 122 @Interruptible 123 public Object createDataArray(Object templ, int numElements) { 124 if (org.jikesrvm.VM.BuildWithGCSpy) { 125 RVMArray array = Magic.getObjectType(templ).asArray(); 126 return RuntimeEntrypoints.resolvedNewArray(numElements, 127 array.getLogElementSize(), 128 ObjectModel.computeArrayHeaderSize(array), 129 array.getTypeInformationBlock(), 130 Plan.ALLOC_GCSPY, 131 ObjectModel.getAlignment(array), 132 ObjectModel.getOffsetForAlignment(array, false), 133 0); 134 } else { 135 return null; 136 } 137 } 138 139 //----------- Various methods modelled on string.c ---------------------// 140 141 @Override 142 public final int sprintf(Address str, Address format, Address value) { 143 if (org.jikesrvm.VM.BuildWithGCSpy) 144 return sysCall.gcspySprintf(str, format, value); 145 else 146 return 0; 147 } 148 }