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