annotate src/share/vm/oops/methodDataKlass.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents d1605aabd0a1
children 4e6abf09f540
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_methodDataKlass.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 klassOop methodDataKlass::create_klass(TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
29 methodDataKlass o;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
a61af66fc99e Initial load
duke
parents:
diff changeset
31 KlassHandle k = base_create_klass(h_this_klass, header_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
32 o.vtbl_value(), CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // Make sure size calculation is right
a61af66fc99e Initial load
duke
parents:
diff changeset
34 assert(k()->size() == align_object_size(header_size()),
a61af66fc99e Initial load
duke
parents:
diff changeset
35 "wrong size for object");
a61af66fc99e Initial load
duke
parents:
diff changeset
36 return k();
a61af66fc99e Initial load
duke
parents:
diff changeset
37 }
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 int methodDataKlass::oop_size(oop obj) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 assert(obj->is_methodData(), "must be method data oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
42 return methodDataOop(obj)->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 }
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 bool methodDataKlass::oop_is_parsable(oop obj) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 assert(obj->is_methodData(), "must be method data oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 return methodDataOop(obj)->object_is_parsable();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 int size = methodDataOopDesc::compute_allocation_size_in_words(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
54 KlassHandle h_k(THREAD, as_klassOop());
a61af66fc99e Initial load
duke
parents:
diff changeset
55 methodDataOop mdo =
a61af66fc99e Initial load
duke
parents:
diff changeset
56 (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 assert(!mdo->is_parsable(), "not expecting parsability yet.");
a61af66fc99e Initial load
duke
parents:
diff changeset
58 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC
a61af66fc99e Initial load
duke
parents:
diff changeset
59 mdo->initialize(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 assert(mdo->is_parsable(), "should be parsable here.");
a61af66fc99e Initial load
duke
parents:
diff changeset
62 assert(size == mdo->object_size(), "wrong size for methodDataOop");
a61af66fc99e Initial load
duke
parents:
diff changeset
63 return mdo;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void methodDataKlass::oop_follow_contents(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
69 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 obj->follow_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
72 MarkSweep::mark_and_push(m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
73 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 for (ProfileData* data = m->first_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 m->is_valid(data);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 data->follow_contents();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
82 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm,
a61af66fc99e Initial load
duke
parents:
diff changeset
83 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 obj->follow_header(cm);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 PSParallelCompact::mark_and_push(cm, m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
89 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 for (ProfileData* data = m->first_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
91 m->is_valid(data);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 data->follow_contents(cm);
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
97
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
98
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Get size before changing pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Don't call size() or oop_size() since that is a virtual call.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 int size = m->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 obj->oop_iterate_header(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 blk->do_oop(m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
108 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 for (ProfileData* data = m->first_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
110 m->is_valid(data);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 data->oop_iterate(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
119 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // Get size before changing pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Don't call size() or oop_size() since that is a virtual call.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 int size = m->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 obj->oop_iterate_header(blk, mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 oop* adr = m->adr_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 if (mr.contains(adr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 blk->do_oop(m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 for (ProfileData* data = m->first_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
131 m->is_valid(data);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 data->oop_iterate_m(blk, mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 int methodDataKlass::oop_adjust_pointers(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(obj->is_methodData(), "should be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Get size before changing pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Don't call size() or oop_size() since that is a virtual call.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 int size = m->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 obj->adjust_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
146 MarkSweep::adjust_pointer(m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
147 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 ProfileData* data;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 data->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
157 void methodDataKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // This should never point into the young gen.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
161 assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 assert (obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
166 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // This should never point into the young gen.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
168 assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 assert(obj->is_methodData(), "should be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
173 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 PSParallelCompact::adjust_pointer(m->adr_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 ProfileData* data;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
180 data->update_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 return m->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 int
a61af66fc99e Initial load
duke
parents:
diff changeset
186 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
187 HeapWord* beg_addr, HeapWord* end_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 assert(obj->is_methodData(), "should be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 oop* p;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 p = m->adr_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 ProfileData* data;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 data->update_pointers(beg_addr, end_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return m->object_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
208 void methodDataKlass::oop_print_on(oop obj, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 assert(obj->is_methodData(), "should be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
210 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 st->print("method data for ");
a61af66fc99e Initial load
duke
parents:
diff changeset
212 m->method()->print_value_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
214 m->print_data_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 assert(obj->is_methodData(), "should be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
219 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 st->print("method data for ");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 m->method()->print_value_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 const char* methodDataKlass::internal_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 return "{method data}";
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // Verification
a61af66fc99e Initial load
duke
parents:
diff changeset
232 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 Klass::oop_verify_on(obj, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 guarantee(obj->is_methodData(), "object must be method data");
a61af66fc99e Initial load
duke
parents:
diff changeset
235 methodDataOop m = methodDataOop(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 guarantee(m->is_perm(), "should be in permspace");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 m->verify_data_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }