Mercurial > hg > graal-jvmci-8
comparison src/share/vm/utilities/array.hpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | bd7a7ce2e264 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
25 #ifndef SHARE_VM_UTILITIES_ARRAY_HPP | 25 #ifndef SHARE_VM_UTILITIES_ARRAY_HPP |
26 #define SHARE_VM_UTILITIES_ARRAY_HPP | 26 #define SHARE_VM_UTILITIES_ARRAY_HPP |
27 | 27 |
28 #include "memory/allocation.hpp" | 28 #include "memory/allocation.hpp" |
29 #include "memory/allocation.inline.hpp" | 29 #include "memory/allocation.inline.hpp" |
30 #include "memory/metaspace.hpp" | |
30 | 31 |
31 // correct linkage required to compile w/o warnings | 32 // correct linkage required to compile w/o warnings |
32 // (must be on file level - cannot be local) | 33 // (must be on file level - cannot be local) |
33 extern "C" { typedef int (*ftype)(const void*, const void*); } | 34 extern "C" { typedef int (*ftype)(const void*, const void*); } |
34 | 35 |
95 assert(length >= 0, "illegal length"); | 96 assert(length >= 0, "illegal length"); |
96 _length = length; | 97 _length = length; |
97 _data = (void*) NEW_C_HEAP_ARRAY(char *, esize * length, F); | 98 _data = (void*) NEW_C_HEAP_ARRAY(char *, esize * length, F); |
98 } | 99 } |
99 | 100 |
101 void initialize(size_t esize, int length) { | |
102 // In debug set array to 0? | |
103 } | |
104 | |
100 #ifdef ASSERT | 105 #ifdef ASSERT |
101 void init_nesting(); | 106 void init_nesting(); |
102 #endif | 107 #endif |
103 | 108 |
104 // helper functions | 109 // helper functions |
121 void base_remove_at(size_t size, int i) { base_class::remove_at(size, i); } \ | 126 void base_remove_at(size_t size, int i) { base_class::remove_at(size, i); } \ |
122 \ | 127 \ |
123 public: \ | 128 public: \ |
124 /* creation */ \ | 129 /* creation */ \ |
125 array_name() : base_class() {} \ | 130 array_name() : base_class() {} \ |
126 array_name(const int length) : base_class(esize, length) {} \ | 131 explicit array_name(const int length) : base_class(esize, length) {} \ |
127 array_name(const int length, const etype fx) { initialize(length, fx); } \ | 132 array_name(const int length, const etype fx) { initialize(length, fx); } \ |
128 void initialize(const int length) { base_class::initialize(esize, length); } \ | 133 void initialize(const int length) { base_class::initialize(esize, length); } \ |
129 void initialize(const int length, const etype fx) { \ | 134 void initialize(const int length, const etype fx) { \ |
130 initialize(length); \ | 135 initialize(length); \ |
131 for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \ | 136 for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \ |
290 // Arrays for basic types | 295 // Arrays for basic types |
291 | 296 |
292 define_array(boolArray, bool) define_stack(boolStack, boolArray) | 297 define_array(boolArray, bool) define_stack(boolStack, boolArray) |
293 define_array(intArray , int ) define_stack(intStack , intArray ) | 298 define_array(intArray , int ) define_stack(intStack , intArray ) |
294 | 299 |
300 // Array for metadata allocation | |
301 | |
302 template <typename T> | |
303 class Array: public MetaspaceObj { | |
304 friend class MetadataFactory; | |
305 friend class VMStructs; | |
306 friend class MethodHandleCompiler; // special case | |
307 protected: | |
308 int _length; // the number of array elements | |
309 T _data[1]; // the array memory | |
310 | |
311 void initialize(int length) { | |
312 _length = length; | |
313 } | |
314 | |
315 private: | |
316 // Turn off copy constructor and assignment operator. | |
317 Array(const Array<T>&); | |
318 void operator=(const Array<T>&); | |
319 | |
320 void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) { | |
321 size_t word_size = Array::size(length); | |
322 return (void*) Metaspace::allocate(loader_data, word_size, read_only, | |
323 Metaspace::NonClassType, CHECK_NULL); | |
324 } | |
325 | |
326 static size_t byte_sizeof(int length) { return sizeof(Array<T>) + MAX2(length - 1, 0) * sizeof(T); } | |
327 | |
328 explicit Array(int length) : _length(length) { | |
329 assert(length >= 0, "illegal length"); | |
330 } | |
331 | |
332 Array(int length, T init) : _length(length) { | |
333 assert(length >= 0, "illegal length"); | |
334 for (int i = 0; i < length; i++) { | |
335 _data[i] = init; | |
336 } | |
337 } | |
338 | |
339 public: | |
340 | |
341 // standard operations | |
342 int length() const { return _length; } | |
343 T* data() { return _data; } | |
344 bool is_empty() const { return length() == 0; } | |
345 | |
346 int index_of(const T& x) const { | |
347 int i = length(); | |
348 while (i-- > 0 && _data[i] != x) ; | |
349 | |
350 return i; | |
351 } | |
352 | |
353 // sort the array. | |
354 bool contains(const T& x) const { return index_of(x) >= 0; } | |
355 | |
356 T at(int i) const { return _data[i]; } | |
357 void at_put(const int i, const T& x) { _data[i] = x; } | |
358 T* adr_at(const int i) { return &_data[i]; } | |
359 int find(const T& x) { return index_of(x); } | |
360 | |
361 T at_acquire(const int which) { return OrderAccess::load_acquire(adr_at(which)); } | |
362 void release_at_put(int which, T contents) { OrderAccess::release_store(adr_at(which), contents); } | |
363 | |
364 static int size(int length) { | |
365 return align_size_up(byte_sizeof(length), BytesPerWord) / BytesPerWord; | |
366 } | |
367 | |
368 int size() { | |
369 return size(_length); | |
370 } | |
371 | |
372 static int length_offset_in_bytes() { return (int) (offset_of(Array<T>, _length)); } | |
373 // Note, this offset don't have to be wordSize aligned. | |
374 static int base_offset_in_bytes() { return (int) (offset_of(Array<T>, _data)); }; | |
375 | |
376 // FIXME: How to handle this? | |
377 void print_value_on(outputStream* st) const { | |
378 st->print("Array<T>(" INTPTR_FORMAT ")", this); | |
379 } | |
380 | |
381 #ifndef PRODUCT | |
382 void print(outputStream* st) { | |
383 for (int i = 0; i< _length; i++) { | |
384 st->print_cr("%d: " INTPTR_FORMAT, i, (intptr_t)at(i)); | |
385 } | |
386 } | |
387 void print() { print(tty); } | |
388 #endif // PRODUCT | |
389 }; | |
390 | |
391 | |
295 #endif // SHARE_VM_UTILITIES_ARRAY_HPP | 392 #endif // SHARE_VM_UTILITIES_ARRAY_HPP |