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.mmtk.vm.gcspy; 014 015 import org.mmtk.utility.Log; 016 import org.vmmagic.unboxed.*; 017 import org.vmmagic.pragma.*; 018 019 /** 020 * Abstract class that provides generally useful 021 * methods. 022 */ 023 @Uninterruptible public abstract class Util { 024 025 /** 026 * Allocate an array of bytes with malloc 027 * 028 * @param size The size to allocate 029 * @return The start address of the memory allocated in C space 030 * @see #free 031 */ 032 public abstract Address malloc(int size); 033 034 /** 035 * Free an array of bytes previously allocated with malloc 036 * 037 * @param addr The address of some memory previously allocated with malloc 038 * @see #malloc 039 */ 040 public abstract void free(Address addr); 041 042 /** 043 * Dump a range in format [start,end) 044 * 045 * @param start The start of the range 046 * @param end The end of the range 047 */ 048 public static void dumpRange(Address start, Address end) { 049 Log.write("["); Log.write(start); 050 Log.write(","); Log.write(end); 051 Log.write(')'); 052 } 053 054 /** 055 * Convert a String to a 0-terminated array of bytes 056 * 057 * @param str The string to convert 058 * @return The address of a null-terminated array in C-space 059 */ 060 public abstract Address getBytes(String str); 061 062 /** 063 * Pretty print a size, converting from bytes to kilo- or mega-bytes as appropriate 064 * 065 * @param buffer The buffer (in C space) in which to place the formatted size 066 * @param size The size in bytes 067 */ 068 public abstract void formatSize(Address buffer, int size); 069 070 /** 071 * Pretty print a size, converting from bytes to kilo- or mega-bytes as appropriate 072 * 073 * @param format A format string 074 * @param bufsize The size of a buffer large enough to hold the formatted result 075 * @param size The size in bytes 076 */ 077 public abstract Address formatSize(String format, int bufsize, int size); 078 079 // public abstract Address formatSize(String format, int bufsize, int size); 080 081 /** 082 * Place a string representation of a long in an array of bytes 083 * without incurring allocation 084 * 085 * @param buffer The byte array 086 * @param value The long to convert 087 * @return The length of the string representation of the integer 088 * -1 indicates some problem (e.g the char buffer was too small) 089 */ 090 public static int numToBytes(byte[] buffer, long value) { 091 return numToBytes(buffer, value, 10); 092 } 093 094 /** 095 * Place a string representation of a long in an array of bytes 096 * without incurring allocation 097 * 098 * @param buffer The byte array 099 * @param value The long to convert 100 * @param radix the base to use for conversion 101 * @return The length of the string representation of the integer 102 * -1 indicates some problem (e.g the char buffer was too small) 103 */ 104 public static int numToBytes(byte[] buffer, long value, int radix) { 105 106 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) 107 radix = 10; 108 109 if (value == 0) { 110 buffer[0] = (byte)'0'; 111 return 1; 112 } 113 114 boolean negative; 115 long longValue; 116 int count; 117 if (!(negative = (value < 0))) { 118 longValue = -value; 119 count = 1; 120 } else { 121 longValue = value; 122 count = 2; 123 } 124 125 long j = longValue; 126 while ((j /= radix) != 0) count++; 127 if (count > buffer.length) 128 return -1; // overflow 129 130 int i = count; 131 do { 132 int ch = (int) -(longValue % radix); 133 if (ch > 9) 134 ch -= (10 - 'a'); 135 else 136 ch += '0'; 137 buffer [--i] = (byte) ch; 138 } while ((longValue /= radix) != 0); 139 if (negative) buffer [0] = (byte)'-'; 140 141 return count; 142 143 } 144 145 /** 146 * {@code sprintf(char *str, char *format, char* value)} 147 * 148 * @param str The destination 'string' (memory in C space) 149 * @param format The format 'string' (memory in C space) 150 * @param value The value 'string' (memory in C space) 151 * @return The number of characters printed (as returned by C's sprintf 152 */ 153 public abstract int sprintf(Address str, Address format, Address value); 154 155 /** 156 * Create an array of a particular type. 157 * The easiest way to use this is: 158 * {@code Foo[] x = (Foo [])Stream.createDataArray(new Foo[0], numElements);} 159 * @param templ a data array to use as a template 160 * @param numElements number of elements in new array 161 * @return the new array 162 */ 163 @Interruptible 164 public abstract Object createDataArray(Object templ, int numElements); 165 } 166