1 /*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
167 address data() const { return write_stream()->buffer(); }
168
169 // Check to avoid double insertion
170 debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
171
172 // Construction
173 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
174 // slots to hold 4-byte values like ints and floats in the LP64 build.
175 void set_oop ( VMReg local);
176 void set_value( VMReg local);
177 void set_narrowoop(VMReg local);
178 void set_dead ( VMReg local);
179 void set_callee_saved( VMReg local, VMReg caller_machine_register );
180 void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
181 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
182
183 int heap_size() const;
184 void copy_data_to(address addr) const;
185 OopMap* deep_copy();
186
187 bool legal_vm_reg_name(VMReg local) {
188 return OopMapValue::legal_vm_reg_name(local);
189 }
190
191 // Printing
192 void print_on(outputStream* st) const;
193 void print() const { print_on(tty); }
194 bool equals(const OopMap* other) const;
195 };
196
197
198 class OopMapSet : public ResourceObj {
199 friend class VMStructs;
200 private:
201 int _om_count;
202 int _om_size;
203 OopMap** _om_data;
204
205 int om_count() const { return _om_count; }
206 void set_om_count(int value) { _om_count = value; }
333 private:
334 CompressedReadStream* _stream;
335 int _mask;
336 int _size;
337 int _position;
338 bool _valid_omv;
339 OopMapValue _omv;
340 void find_next();
341
342 public:
343 OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
344 OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
345 bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; }
346 void next() { find_next(); }
347 OopMapValue current() { return _omv; }
348 #ifdef ASSERT
349 int stream_position() const { return _stream->position(); }
350 #endif
351 };
352
353
354 // Derived pointer support. This table keeps track of all derived points on a
355 // stack. It is cleared before each scavenge/GC. During the traversal of all
356 // oops, it is filled in with references to all locations that contains a
357 // derived oop (assumed to be very few). When the GC is complete, the derived
358 // pointers are updated based on their base pointers new value and an offset.
359 #ifdef COMPILER2
360 class DerivedPointerTable : public AllStatic {
361 friend class VMStructs;
362 private:
363 static GrowableArray<DerivedPointerEntry*>* _list;
364 static bool _active; // do not record pointers for verify pass etc.
365 public:
366 static void clear(); // Called before scavenge/GC
367 static void add(oop *derived, oop *base); // Called during scavenge/GC
368 static void update_pointers(); // Called after scavenge/GC
369 static bool is_empty() { return _list == NULL || _list->is_empty(); }
370 static bool is_active() { return _active; }
371 static void set_active(bool value) { _active = value; }
372 };
373
374 // A utility class to temporarily "deactivate" the DerivedPointerTable.
375 // (Note: clients are responsible for any MT-safety issues)
376 class DerivedPointerTableDeactivate: public StackObj {
377 private:
378 bool _active;
379 public:
380 DerivedPointerTableDeactivate() {
381 _active = DerivedPointerTable::is_active();
382 if (_active) {
383 DerivedPointerTable::set_active(false);
384 }
385 }
386
387 ~DerivedPointerTableDeactivate() {
388 assert(!DerivedPointerTable::is_active(),
389 "Inconsistency: not MT-safe");
390 if (_active) {
391 DerivedPointerTable::set_active(true);
392 }
393 }
394 };
395 #endif // COMPILER2
396
397 #endif // SHARE_VM_COMPILER_OOPMAP_HPP
|
1 /*
2 * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
167 address data() const { return write_stream()->buffer(); }
168
169 // Check to avoid double insertion
170 debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
171
172 // Construction
173 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
174 // slots to hold 4-byte values like ints and floats in the LP64 build.
175 void set_oop ( VMReg local);
176 void set_value( VMReg local);
177 void set_narrowoop(VMReg local);
178 void set_dead ( VMReg local);
179 void set_callee_saved( VMReg local, VMReg caller_machine_register );
180 void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
181 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
182
183 int heap_size() const;
184 void copy_data_to(address addr) const;
185 OopMap* deep_copy();
186
187 bool has_derived_pointer() const PRODUCT_RETURN0;
188
189 bool legal_vm_reg_name(VMReg local) {
190 return OopMapValue::legal_vm_reg_name(local);
191 }
192
193 // Printing
194 void print_on(outputStream* st) const;
195 void print() const { print_on(tty); }
196 bool equals(const OopMap* other) const;
197 };
198
199
200 class OopMapSet : public ResourceObj {
201 friend class VMStructs;
202 private:
203 int _om_count;
204 int _om_size;
205 OopMap** _om_data;
206
207 int om_count() const { return _om_count; }
208 void set_om_count(int value) { _om_count = value; }
335 private:
336 CompressedReadStream* _stream;
337 int _mask;
338 int _size;
339 int _position;
340 bool _valid_omv;
341 OopMapValue _omv;
342 void find_next();
343
344 public:
345 OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
346 OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
347 bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; }
348 void next() { find_next(); }
349 OopMapValue current() { return _omv; }
350 #ifdef ASSERT
351 int stream_position() const { return _stream->position(); }
352 #endif
353 };
354
355 class ImmutableOopMapBuilder {
356 private:
357 class Mapping;
358
359 private:
360 const OopMapSet* _set;
361 const OopMap* _empty;
362 const OopMap* _last;
363 int _empty_offset;
364 int _last_offset;
365 int _offset;
366 int _required;
367 Mapping* _mapping;
368 ImmutableOopMapSet* _new_set;
369
370 /* Used for bookkeeping when building ImmutableOopMaps */
371 class Mapping : public ResourceObj {
372 public:
373 enum kind_t { OOPMAP_UNKNOWN = 0, OOPMAP_NEW = 1, OOPMAP_EMPTY = 2, OOPMAP_DUPLICATE = 3 };
374
375 kind_t _kind;
376 int _offset;
377 int _size;
378 const OopMap* _map;
379 const OopMap* _other;
380
381 Mapping() : _kind(OOPMAP_UNKNOWN), _offset(-1), _size(-1), _map(NULL) {}
382
383 void set(kind_t kind, int offset, int size, const OopMap* map = 0, const OopMap* other = 0) {
384 _kind = kind;
385 _offset = offset;
386 _size = size;
387 _map = map;
388 _other = other;
389 }
390 };
391
392 public:
393 ImmutableOopMapBuilder(const OopMapSet* set);
394
395 int heap_size();
396 ImmutableOopMapSet* build();
397 ImmutableOopMapSet* generate_into(address buffer);
398 private:
399 bool is_empty(const OopMap* map) const {
400 return map->count() == 0;
401 }
402
403 bool is_last_duplicate(const OopMap* map) {
404 if (_last != NULL && _last->count() > 0 && _last->equals(map)) {
405 return true;
406 }
407 return false;
408 }
409
410 #ifdef ASSERT
411 void verify(address buffer, int size, const ImmutableOopMapSet* set);
412 #endif
413
414 bool has_empty() const {
415 return _empty_offset != -1;
416 }
417
418 int size_for(const OopMap* map) const;
419 void fill_pair(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
420 int fill_map(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
421 void fill(ImmutableOopMapSet* set, int size);
422 };
423
424
425 // Derived pointer support. This table keeps track of all derived points on a
426 // stack. It is cleared before each scavenge/GC. During the traversal of all
427 // oops, it is filled in with references to all locations that contains a
428 // derived oop (assumed to be very few). When the GC is complete, the derived
429 // pointers are updated based on their base pointers new value and an offset.
430 #if defined(COMPILER2) || INCLUDE_JVMCI
431 class DerivedPointerTable : public AllStatic {
432 friend class VMStructs;
433 private:
434 static GrowableArray<DerivedPointerEntry*>* _list;
435 static bool _active; // do not record pointers for verify pass etc.
436 public:
437 static void clear(); // Called before scavenge/GC
438 static void add(oop *derived, oop *base); // Called during scavenge/GC
439 static void update_pointers(); // Called after scavenge/GC
440 static bool is_empty() { return _list == NULL || _list->is_empty(); }
441 static bool is_active() { return _active; }
442 static void set_active(bool value) { _active = value; }
443 };
444
445 // A utility class to temporarily "deactivate" the DerivedPointerTable.
446 // (Note: clients are responsible for any MT-safety issues)
447 class DerivedPointerTableDeactivate: public StackObj {
448 private:
449 bool _active;
450 public:
451 DerivedPointerTableDeactivate() {
452 _active = DerivedPointerTable::is_active();
453 if (_active) {
454 DerivedPointerTable::set_active(false);
455 }
456 }
457
458 ~DerivedPointerTableDeactivate() {
459 assert(!DerivedPointerTable::is_active(),
460 "Inconsistency: not MT-safe");
461 if (_active) {
462 DerivedPointerTable::set_active(true);
463 }
464 }
465 };
466 #endif // COMPILER2 || INCLUDE_JVMCI
467
468 #endif // SHARE_VM_COMPILER_OOPMAP_HPP
|