Mercurial > hg > truffle
comparison src/share/vm/code/oopRecorder.cpp @ 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 | f95d63e2154a |
children | 9928ad27a80e |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1998, 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. |
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "ci/ciEnv.hpp" | |
27 #include "ci/ciInstance.hpp" | |
28 #include "ci/ciMetadata.hpp" | |
26 #include "code/oopRecorder.hpp" | 29 #include "code/oopRecorder.hpp" |
27 #include "memory/allocation.inline.hpp" | 30 #include "memory/allocation.inline.hpp" |
28 #include "oops/oop.inline.hpp" | 31 #include "oops/oop.inline.hpp" |
29 | 32 |
30 #ifdef ASSERT | 33 #ifdef ASSERT |
31 int OopRecorder::_find_index_calls = 0; | 34 template <class T> int ValueRecorder<T>::_find_index_calls = 0; |
32 int OopRecorder::_hit_indexes = 0; | 35 template <class T> int ValueRecorder<T>::_hit_indexes = 0; |
33 int OopRecorder::_missed_indexes = 0; | 36 template <class T> int ValueRecorder<T>::_missed_indexes = 0; |
34 #endif //ASSERT | 37 #endif //ASSERT |
35 | 38 |
36 | 39 |
37 OopRecorder::OopRecorder(Arena* arena) { | 40 template <class T> ValueRecorder<T>::ValueRecorder(Arena* arena) { |
38 _handles = NULL; | 41 _handles = NULL; |
39 _indexes = NULL; | 42 _indexes = NULL; |
40 _arena = arena; | 43 _arena = arena; |
41 _complete = false; | 44 _complete = false; |
42 } | 45 } |
43 | 46 |
44 OopRecorder::IndexCache::IndexCache() { | 47 template <class T> template <class X> ValueRecorder<T>::IndexCache<X>::IndexCache() { |
45 assert(first_index > 0, "initial zero state of cache must be invalid index"); | 48 assert(first_index > 0, "initial zero state of cache must be invalid index"); |
46 Copy::zero_to_bytes(&_cache[0], sizeof(_cache)); | 49 Copy::zero_to_bytes(&_cache[0], sizeof(_cache)); |
47 } | 50 } |
48 | 51 |
49 int OopRecorder::oop_size() { | 52 template <class T> int ValueRecorder<T>::size() { |
50 _complete = true; | 53 _complete = true; |
51 if (_handles == NULL) return 0; | 54 if (_handles == NULL) return 0; |
52 return _handles->length() * sizeof(oop); | 55 return _handles->length() * sizeof(T); |
53 } | 56 } |
54 | 57 |
55 void OopRecorder::copy_to(nmethod* nm) { | 58 template <class T> void ValueRecorder<T>::copy_values_to(nmethod* nm) { |
56 assert(_complete, "must be frozen"); | 59 assert(_complete, "must be frozen"); |
57 maybe_initialize(); // get non-null handles, even if we have no oops | 60 maybe_initialize(); // get non-null handles, even if we have no oops |
58 nm->copy_oops(_handles); | 61 nm->copy_values(_handles); |
59 } | 62 } |
60 | 63 |
61 void OopRecorder::maybe_initialize() { | 64 template <class T> void ValueRecorder<T>::maybe_initialize() { |
62 if (_handles == NULL) { | 65 if (_handles == NULL) { |
63 if (_arena != NULL) { | 66 if (_arena != NULL) { |
64 _handles = new(_arena) GrowableArray<jobject>(_arena, 10, 0, 0); | 67 _handles = new(_arena) GrowableArray<T>(_arena, 10, 0, 0); |
65 _no_finds = new(_arena) GrowableArray<int>( _arena, 10, 0, 0); | 68 _no_finds = new(_arena) GrowableArray<int>( _arena, 10, 0, 0); |
66 } else { | 69 } else { |
67 _handles = new GrowableArray<jobject>(10, 0, 0); | 70 _handles = new GrowableArray<T>(10, 0, 0); |
68 _no_finds = new GrowableArray<int>( 10, 0, 0); | 71 _no_finds = new GrowableArray<int>( 10, 0, 0); |
69 } | 72 } |
70 } | 73 } |
71 } | 74 } |
72 | 75 |
73 | 76 |
74 jobject OopRecorder::handle_at(int index) { | 77 template <class T> T ValueRecorder<T>::at(int index) { |
75 // there is always a NULL virtually present as first object | 78 // there is always a NULL virtually present as first object |
76 if (index == null_index) return NULL; | 79 if (index == null_index) return NULL; |
77 return _handles->at(index - first_index); | 80 return _handles->at(index - first_index); |
78 } | 81 } |
79 | 82 |
80 | 83 |
81 // Local definition. Used only in this module. | 84 template <class T> int ValueRecorder<T>::add_handle(T h, bool make_findable) { |
82 inline bool OopRecorder::is_real_jobject(jobject h) { | |
83 return h != NULL && h != (jobject)Universe::non_oop_word(); | |
84 } | |
85 | |
86 | |
87 int OopRecorder::add_handle(jobject h, bool make_findable) { | |
88 assert(!_complete, "cannot allocate more elements after size query"); | 85 assert(!_complete, "cannot allocate more elements after size query"); |
89 maybe_initialize(); | 86 maybe_initialize(); |
90 // indexing uses 1 as an origin--0 means null | 87 // indexing uses 1 as an origin--0 means null |
91 int index = _handles->length() + first_index; | 88 int index = _handles->length() + first_index; |
92 _handles->append(h); | 89 _handles->append(h); |
93 | 90 |
94 // Support correct operation of find_index(). | 91 // Support correct operation of find_index(). |
95 assert(!(make_findable && !is_real_jobject(h)), "nulls are not findable"); | 92 assert(!(make_findable && !is_real(h)), "nulls are not findable"); |
96 if (make_findable) { | 93 if (make_findable) { |
97 // This index may be returned from find_index(). | 94 // This index may be returned from find_index(). |
98 if (_indexes != NULL) { | 95 if (_indexes != NULL) { |
99 int* cloc = _indexes->cache_location(h); | 96 int* cloc = _indexes->cache_location(h); |
100 _indexes->set_cache_location_index(cloc, index); | 97 _indexes->set_cache_location_index(cloc, index); |
101 } else if (index == index_cache_threshold && _arena != NULL) { | 98 } else if (index == index_cache_threshold && _arena != NULL) { |
102 _indexes = new(_arena) IndexCache(); | 99 _indexes = new(_arena) IndexCache<T>(); |
103 for (int i = 0; i < _handles->length(); i++) { | 100 for (int i = 0; i < _handles->length(); i++) { |
104 // Load the cache with pre-existing elements. | 101 // Load the cache with pre-existing elements. |
105 int index0 = i + first_index; | 102 int index0 = i + first_index; |
106 if (_no_finds->contains(index0)) continue; | 103 if (_no_finds->contains(index0)) continue; |
107 int* cloc = _indexes->cache_location(_handles->at(i)); | 104 int* cloc = _indexes->cache_location(_handles->at(i)); |
108 _indexes->set_cache_location_index(cloc, index0); | 105 _indexes->set_cache_location_index(cloc, index0); |
109 } | 106 } |
110 } | 107 } |
111 } else if (is_real_jobject(h)) { | 108 } else if (is_real(h)) { |
112 // Remember that this index is not to be returned from find_index(). | 109 // Remember that this index is not to be returned from find_index(). |
113 // This case is rare, because most or all uses of allocate_index pass | 110 // This case is rare, because most or all uses of allocate_index pass |
114 // a jobject argument of NULL or Universe::non_oop_word. | 111 // an argument of NULL or Universe::non_oop_word. |
115 // Thus, the expected length of _no_finds is zero. | 112 // Thus, the expected length of _no_finds is zero. |
116 _no_finds->append(index); | 113 _no_finds->append(index); |
117 } | 114 } |
118 | 115 |
119 return index; | 116 return index; |
120 } | 117 } |
121 | 118 |
122 | 119 |
123 int OopRecorder::maybe_find_index(jobject h) { | 120 template <class T> int ValueRecorder<T>::maybe_find_index(T h) { |
124 debug_only(_find_index_calls++); | 121 debug_only(_find_index_calls++); |
125 assert(!_complete, "cannot allocate more elements after size query"); | 122 assert(!_complete, "cannot allocate more elements after size query"); |
126 maybe_initialize(); | 123 maybe_initialize(); |
127 if (h == NULL) return null_index; | 124 if (h == NULL) return null_index; |
128 assert(is_real_jobject(h), "must be valid jobject"); | 125 assert(is_real(h), "must be valid"); |
129 int* cloc = (_indexes == NULL)? NULL: _indexes->cache_location(h); | 126 int* cloc = (_indexes == NULL)? NULL: _indexes->cache_location(h); |
130 if (cloc != NULL) { | 127 if (cloc != NULL) { |
131 int cindex = _indexes->cache_location_index(cloc); | 128 int cindex = _indexes->cache_location_index(cloc); |
132 if (cindex == 0) { | 129 if (cindex == 0) { |
133 return -1; // We know this handle is completely new. | 130 return -1; // We know this handle is completely new. |
154 return findex; | 151 return findex; |
155 } | 152 } |
156 } | 153 } |
157 return -1; | 154 return -1; |
158 } | 155 } |
156 | |
157 // Explicitly instantiate these types | |
158 template class ValueRecorder<Metadata*>; | |
159 template class ValueRecorder<jobject>; |