CACAO
array.hpp
Go to the documentation of this file.
1 /* src/vm/array.hpp - Java array functions
2 
3  Copyright (C) 1996-2014
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2008 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 
24 */
25 
26 
27 #ifndef ARRAY_HPP_
28 #define ARRAY_HPP_ 1
29 
30 #include "config.h"
31 #include <cassert> // for assert
32 #include <cstdio> // for NULL, printf
33 #include <stdint.h> // for int32_t, int8_t, int16_t, etc
34 #include "mm/gc.hpp" // for GCCriticalSection, etc
35 #include "threads/lockword.hpp" // for Lockword
36 #include "vm/class.hpp" // for classinfo
37 #include "vm/exceptions.hpp"
38 #include "vm/global.hpp" // for java_handle_t, java_array_t, etc
39 #include "vm/jit/builtin.hpp" // for builtin_canstore
40 #include "vm/os.hpp" // for os
41 #include "vm/primitive.hpp" // for primitivetypeinfo, etc
42 #include "vm/types.hpp" // for s4, s2
43 #include "vm/vftbl.hpp" // for vftbl_t
44 
45 /* array types ****************************************************************/
46 
47 /* CAUTION: Don't change the numerical values! These constants (with
48  the exception of ARRAYTYPE_OBJECT) are used as indices in the
49  primitive type table. */
50 
51 enum ArrayType {
60  ARRAYTYPE_OBJECT = PRIMITIVETYPE_VOID // don't use as index!
61 };
62 
63 
64 /* arraydescriptor *************************************************************
65 
66  For every array class an arraydescriptor is allocated which
67  describes the array class. The arraydescriptor is referenced from
68  the vftbl of the array class.
69 
70 *******************************************************************************/
71 
73  vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
74  vftbl_t *elementvftbl; /* vftbl of the element type, NULL for primitive */
75  ArrayType arraytype; /* ARRAYTYPE_* constant */
76  ArrayType elementtype; /* ARRAYTYPE_* constant */
77  s4 dataoffset; /* offset of the array data from object pointer */
78  s4 componentsize; /* size of a component in bytes */
79  s2 dimension; /* dimension of the array (always >= 1) */
80 };
81 
82 
83 /**
84  * This is a generic accessor class for Java arrays (of unspecified type),
85  * which can be used to safely operate on Java arrays in native code.
86  */
87 class Array {
88 protected:
89  // Handle of Java array.
91 
92 private:
93  // We don't want a Java arrays to be copied.
94  Array(Array* a) {}
95  Array(Array& a) {}
96 
97 public:
98  Array(java_handle_t* h);
99  Array(int32_t length, classinfo* arrayclass);
100  virtual ~Array() {}
101 
102  // Getters.
103  virtual java_handle_array_t* get_handle() const { return _handle; }
104  int32_t get_length() const;
105 
106  // Null checks.
107  bool is_null () const;
108  bool is_non_null() const;
109 
110  // Safe element modification functions for primitive values
112  void set_primitive_element(int32_t index, imm_union value);
113 
114  // Safe element modification functions for boxed values
116  void set_boxed_element(int32_t index, java_handle_t *o);
117 };
118 
119 
120 /**
121  * Constructor checks if passed handle really is a Java array.
122  */
124 {
125  if (h == NULL) {
126  _handle = NULL;
127  return;
128  }
129 
130 #if 0
131  classinfo* c;
132  LLNI_class_get(h, c);
133  if (!class_is_array(c)) {
134  printf("Array::Array(): WARNING, passed handle is not an array\n");
135  //exceptions_throw_illegalargumentexception("Argument is not an array");
137  _handle = NULL;
138  return;
139  }
140 #endif
141 
142  _handle = h;
143 }
144 
145 /**
146  * Creates an array of the given array type on the heap.
147  * The handle pointer to the array can be NULL in case of an exception.
148  */
149 inline Array::Array(int32_t size, classinfo* arrayclass)
150 {
151  // Sanity check.
152  assert(class_is_array(arrayclass));
153 
154  if (size < 0) {
156  _handle = NULL;
157  return;
158  }
159 
160  arraydescriptor* desc = arrayclass->vftbl->arraydesc;
161  int32_t dataoffset = desc->dataoffset;
162  int32_t componentsize = desc->componentsize;
163  int32_t actualsize = dataoffset + size * componentsize;
164 
165  // Check for overflow.
166 
167  if (((u4) actualsize) < ((u4) size)) {
169  _handle = NULL;
170  return;
171  }
172 
173  java_array_t* a = (java_array_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
174 
175  if (a == NULL) {
176  _handle = NULL;
177  return;
178  }
179 
180  LLNI_vftbl_direct(a) = arrayclass->vftbl;
181 
183 
184  a->size = size;
185 
187 }
188 
189 inline int32_t Array::get_length() const
190 {
191  if (is_null()) {
192  printf("Array::get_length(): WARNING, got null-pointer\n");
194  return -1;
195  }
196 
197  // XXX Fix me!
198  int32_t length = ((java_array_t*) _handle)->size;
199 
200  return length;
201 }
202 
203 inline bool Array::is_null() const
204 {
205  return (_handle == NULL);
206 }
207 
208 inline bool Array::is_non_null() const
209 {
210  return (_handle != NULL);
211 }
212 
213 
214 /**
215  * This is a template of an accessor class for Java arrays
216  * of a specific type.
217  */
218 template<class T> class ArrayTemplate : public Array {
219 protected:
220  ArrayTemplate(int32_t length, classinfo* arrayclass) : Array(length, arrayclass) {}
221 
222 public:
224 
225  // XXX This should be protected or private!
226  virtual T* get_raw_data_ptr() = 0;
227 
228  // Safe element modification functions
229  T get_element(int32_t index);
230  void set_element(int32_t index, T value);
231 
232  // Region copy functions
233  void get_region(int32_t offset, int32_t count, T* buffer);
234  void set_region(int32_t offset, int32_t count, const T* buffer);
235 };
236 
237 
238 template<class T> inline T ArrayTemplate<T>::get_element(int32_t index)
239 {
240  if (is_null()) {
242  return 0;
243  }
244 
245  if ((index < 0) || (index >= get_length())) {
247  return 0;
248  }
249 
250  T* ptr = get_raw_data_ptr();
251 
252  return ptr[index];
253 }
254 
255 template<class T> inline void ArrayTemplate<T>::set_element(int32_t index, T value)
256 {
257  if (is_null()) {
259  return;
260  }
261 
262  if ((index < 0) || (index >= get_length())) {
264  return;
265  }
266 
267  T* ptr = get_raw_data_ptr();
268 
269  ptr[index] = value;
270 }
271 
272 template<> inline void ArrayTemplate<java_handle_t*>::set_element(int32_t index, java_handle_t* value)
273 {
274  if (is_null()) {
276  return;
277  }
278 
279  // Sanity check.
280  assert(((java_array_t*) get_handle())->objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
281 
282  // Check if value can be stored
283  if (!builtin_canstore(get_handle(), value)) {
285  return;
286  }
287 
288  if ((index < 0) || (index >= get_length())) {
290  return;
291  }
292 
294 
295  ptr[index] = value;
296 }
297 
298 template<class T> inline void ArrayTemplate<T>::get_region(int32_t offset, int32_t count, T* buffer)
299 {
300  // Copy the array region inside a GC critical section.
302 
303  const T* ptr = get_raw_data_ptr();
304 
305  os::memcpy(buffer, ptr + offset, sizeof(T) * count);
306 }
307 
308 template<class T> inline void ArrayTemplate<T>::set_region(int32_t offset, int32_t count, const T* buffer)
309 {
310  // Copy the array region inside a GC critical section.
312 
313  T* ptr = get_raw_data_ptr();
314 
315  os::memcpy(ptr + offset, buffer, sizeof(T) * count);
316 }
317 
318 
319 /**
320  * Actual implementations of common Java array access classes.
321  */
322 class BooleanArray : public ArrayTemplate<uint8_t> {
323 public:
325  BooleanArray(int32_t length) : ArrayTemplate<uint8_t>(length, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass) {}
326  uint8_t* get_raw_data_ptr() { return ((java_booleanarray_t*) get_handle())->data; }
327 };
328 
329 class ByteArray : public ArrayTemplate<int8_t> {
330 public:
332  ByteArray(int32_t length) : ArrayTemplate<int8_t>(length, primitivetype_table[ARRAYTYPE_BYTE].arrayclass) {}
333  int8_t* get_raw_data_ptr() { return (int8_t*) ((java_bytearray_t*) get_handle())->data; }
334 };
335 
336 class CharArray : public ArrayTemplate<uint16_t> {
337 public:
339  CharArray(int32_t length) : ArrayTemplate<uint16_t>(length, primitivetype_table[ARRAYTYPE_CHAR].arrayclass) {}
340  uint16_t* get_raw_data_ptr() { return ((java_chararray_t*) get_handle())->data; }
341 };
342 
343 class ShortArray : public ArrayTemplate<int16_t> {
344 public:
346  ShortArray(int32_t length) : ArrayTemplate<int16_t>(length, primitivetype_table[ARRAYTYPE_SHORT].arrayclass) {}
347  int16_t* get_raw_data_ptr() { return ((java_shortarray_t*) get_handle())->data; }
348 };
349 
350 class IntArray : public ArrayTemplate<int32_t> {
351 public:
353  IntArray(int32_t length) : ArrayTemplate<int32_t>(length, primitivetype_table[ARRAYTYPE_INT].arrayclass) {}
354  int32_t* get_raw_data_ptr() { return ((java_intarray_t*) get_handle())->data; }
355 };
356 
357 class LongArray : public ArrayTemplate<int64_t> {
358 public:
360  LongArray(int32_t length) : ArrayTemplate<int64_t>(length, primitivetype_table[ARRAYTYPE_LONG].arrayclass) {}
361  int64_t* get_raw_data_ptr() { return ((java_longarray_t*) get_handle())->data; }
362 };
363 
364 class FloatArray : public ArrayTemplate<float> {
365 public:
367  FloatArray(int32_t length) : ArrayTemplate<float>(length, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass) {}
368  float* get_raw_data_ptr() { return ((java_floatarray_t*) get_handle())->data; }
369 };
370 
371 class DoubleArray : public ArrayTemplate<double> {
372 public:
374  DoubleArray(int32_t length) : ArrayTemplate<double>(length, primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass) {}
375  double* get_raw_data_ptr() { return ((java_doublearray_t*) get_handle())->data; }
376 };
377 
378 /**
379  * Actual implementation of access class for Java Object arrays.
380  */
381 class ObjectArray : public ArrayTemplate<java_handle_t*> {
382 public:
384  ObjectArray(int32_t length, classinfo* componentclass);
386 };
387 
388 /**
389  * Actual implementation of access class for java.lang.Class arrays.
390  */
391 class ClassArray : public ArrayTemplate<classinfo*> {
392 public:
393  ClassArray(int32_t length);
395 };
396 
397 #endif // ARRAY_HPP_
398 
399 
400 /*
401  * These are local overrides for various environment variables in Emacs.
402  * Please do not remove this and leave it at the end of the file, where
403  * Emacs will automagically detect them.
404  * ---------------------------------------------------------------------
405  * Local variables:
406  * mode: c++
407  * indent-tabs-mode: t
408  * c-basic-offset: 4
409  * tab-width: 4
410  * End:
411  * vim:noexpandtab:sw=4:ts=4:
412  */
void exceptions_throw_illegalargumentexception(void)
CharArray(java_handle_chararray_t *h)
Definition: array.hpp:338
ByteArray(java_handle_bytearray_t *h)
Definition: array.hpp:331
std::size_t index
BooleanArray(java_handle_booleanarray_t *h)
Definition: array.hpp:324
ShortArray(int32_t length)
Definition: array.hpp:346
uint16_t * get_raw_data_ptr()
Definition: array.hpp:340
float * get_raw_data_ptr()
Definition: array.hpp:368
ArrayType elementtype
Definition: array.hpp:76
LongArray(java_handle_longarray_t *h)
Definition: array.hpp:359
ShortArray(java_handle_shortarray_t *h)
Definition: array.hpp:345
virtual java_handle_array_t * get_handle() const
Definition: array.hpp:103
int8_t * get_raw_data_ptr()
Definition: array.hpp:333
void init()
Definition: lockword.hpp:61
uintptr_t lockword
Definition: global.hpp:265
This is a template of an accessor class for Java arrays of a specific type.
Definition: array.hpp:218
FloatArray(int32_t length)
Definition: array.hpp:367
Actual implementation of access class for Java Object arrays.
Definition: array.hpp:381
Array(Array &a)
Definition: array.hpp:95
int32_t * get_raw_data_ptr()
Definition: array.hpp:354
T get_element(int32_t index)
Definition: array.hpp:238
int16_t * get_raw_data_ptr()
Definition: array.hpp:347
DoubleArray(int32_t length)
Definition: array.hpp:374
Actual implementations of common Java array access classes.
Definition: array.hpp:322
vftbl_t * componentvftbl
Definition: array.hpp:73
double * get_raw_data_ptr()
Definition: array.hpp:375
static bool class_is_array(classinfo *c)
Definition: class.hpp:341
ArrayTemplate(java_handle_array_t *h)
Definition: array.hpp:223
void set_element(int32_t index, T value)
Definition: array.hpp:255
void get_region(int32_t offset, int32_t count, T *buffer)
Definition: array.hpp:298
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
ArrayTemplate(int32_t length, classinfo *arrayclass)
Definition: array.hpp:220
void set_primitive_element(int32_t index, imm_union value)
Sets a primitive element in the given Java array.
Definition: array.cpp:192
ByteArray(int32_t length)
Definition: array.hpp:332
void * heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect)
Definition: heap.c:302
int64_t * get_raw_data_ptr()
Definition: array.hpp:361
ArrayType
Definition: array.hpp:51
#define LLNI_class_get(obj, variable)
Definition: llni.hpp:60
CharArray(int32_t length)
Definition: array.hpp:339
Critical section for the GC.
Definition: gc.hpp:42
DoubleArray(java_handle_doublearray_t *h)
Definition: array.hpp:373
int32_t get_length() const
Definition: array.hpp:189
LongArray(int32_t length)
Definition: array.hpp:360
void exceptions_throw_nullpointerexception(void)
ObjectArray(java_handle_objectarray_t *h)
Definition: array.hpp:383
classinfo ** get_raw_data_ptr()
Definition: array.hpp:394
int32_t s4
Definition: types.hpp:45
static void * memcpy(void *dest, const void *src, size_t n)
Definition: os.hpp:492
java_object_t objheader
Definition: global.hpp:286
uint8_t * get_raw_data_ptr()
Definition: array.hpp:326
void exceptions_throw_negativearraysizeexception(void)
arraydescriptor * arraydesc
Definition: vftbl.hpp:101
BooleanArray(int32_t length)
Definition: array.hpp:325
bool is_non_null() const
Definition: array.hpp:208
void set_region(int32_t offset, int32_t count, const T *buffer)
Definition: array.hpp:308
uint32_t u4
Definition: types.hpp:46
vftbl_t * elementvftbl
Definition: array.hpp:74
IntArray(int32_t length)
Definition: array.hpp:353
void exceptions_throw_arrayindexoutofboundsexception(void)
This is a generic accessor class for Java arrays (of unspecified type), which can be used to safely o...
Definition: array.hpp:87
Lockword.
Definition: lockword.hpp:37
vftbl_t * vftbl
Definition: class.hpp:121
#define LLNI_vftbl_direct(obj)
Definition: llni.hpp:120
bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
Definition: builtin.cpp:576
ArrayType arraytype
Definition: array.hpp:75
java_handle_array_t * _handle
Definition: array.hpp:90
FloatArray(java_handle_floatarray_t *h)
Definition: array.hpp:366
int16_t s2
Definition: types.hpp:42
s4 componentsize
Definition: array.hpp:78
virtual T * get_raw_data_ptr()=0
ClassArray(int32_t length)
Creates an array of references to classinfos on the heap.
Definition: array.cpp:305
java_handle_t * get_boxed_element(int32_t index)
Returns a boxed element of the given Java array.
Definition: array.cpp:44
bool is_null() const
Definition: array.hpp:203
primitivetypeinfo primitivetype_table[PRIMITIVETYPE_MAX]
Definition: primitive.cpp:59
virtual ~Array()
Definition: array.hpp:100
Actual implementation of access class for java.lang.Class arrays.
Definition: array.hpp:391
const char const void jint length
Definition: jvmti.h:352
#define printf(...)
Definition: ssa2.cpp:40
imm_union get_primitive_element(int32_t index)
Returns a primitive element of the given Java array.
Definition: array.cpp:107
void exceptions_throw_outofmemoryerror(void)
Definition: exceptions.cpp:914
Array(Array *a)
Definition: array.hpp:94
void set_boxed_element(int32_t index, java_handle_t *o)
Sets a boxed element in the given Java array.
Definition: array.cpp:71
java_handle_t ** get_raw_data_ptr()
Definition: array.hpp:385
IntArray(java_handle_intarray_t *h)
Definition: array.hpp:352