29 // Dead - Dead; can be Zapped for debugging
30 // CalleeXX - Callee saved; also describes which caller register is saved
31 // DerivedXX - A derived oop; original oop is described.
32 //
33 // OopMapValue describes a single OopMap entry
34
35 class frame;
36 class RegisterMap;
37 class DerivedPointerEntry;
38
39 class OopMapValue: public StackObj {
40 friend class VMStructs;
41 private:
42 short _value;
43 int value() const { return _value; }
44 void set_value(int value) { _value = value; }
45 short _content_reg;
46
47 public:
48 // Constants
49 enum { type_bits = 6,
50 register_bits = BitsPerShort - type_bits };
51
52 enum { type_shift = 0,
53 register_shift = type_bits };
54
55 enum { type_mask = right_n_bits(type_bits),
56 type_mask_in_place = type_mask << type_shift,
57 register_mask = right_n_bits(register_bits),
58 register_mask_in_place = register_mask << register_shift };
59
60 enum oop_types { // must fit in type_bits
61 unused_value =0, // powers of 2, for masking OopMapStream
62 oop_value = 1,
63 value_value = 2,
64 narrowoop_value = 4,
65 callee_saved_value = 8,
66 derived_oop_value= 16,
67 stack_obj = 32 };
68
69 // Constructors
70 OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
71 OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); }
72 OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); }
73 OopMapValue (CompressedReadStream* stream) { read_from(stream); }
74
75 // Archiving
76 void write_on(CompressedWriteStream* stream) {
77 stream->write_int(value());
78 if(is_callee_saved() || is_derived_oop()) {
79 stream->write_int(content_reg()->value());
80 }
81 }
82
83 void read_from(CompressedReadStream* stream) {
84 set_value(stream->read_int());
85 if(is_callee_saved() || is_derived_oop()) {
86 set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true));
87 }
88 }
89
90 // Querying
91 bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; }
92 bool is_value() { return mask_bits(value(), type_mask_in_place) == value_value; }
93 bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
94 bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
95 bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
96 bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; }
97
98 void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
99 void set_value() { set_value((value() & register_mask_in_place) | value_value); }
100 void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
101 void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
102 void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
103 void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); }
104
105 VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
106 oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
107
108 static bool legal_vm_reg_name(VMReg p) {
109 return (p->value() == (p->value() & register_mask));
110 }
111
112 void set_reg_type(VMReg p, oop_types t) {
113 set_value((p->value() << register_shift) | t);
114 assert(reg() == p, "sanity check" );
115 assert(type() == t, "sanity check" );
116 }
117
118
119 VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); }
120 void set_content_reg(VMReg r) { _content_reg = r->value(); }
121
122 // Physical location queries
123 bool is_register_loc() { return reg()->is_reg(); }
163
164 public:
165 OopMap(int frame_size, int arg_count);
166
167 // pc-offset handling
168 int offset() const { return _pc_offset; }
169 void set_offset(int o) { _pc_offset = o; }
170
171 // Check to avoid double insertion
172 debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
173
174 // Construction
175 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
176 // slots to hold 4-byte values like ints and floats in the LP64 build.
177 void set_oop ( VMReg local);
178 void set_value( VMReg local);
179 void set_narrowoop(VMReg local);
180 void set_dead ( VMReg local);
181 void set_callee_saved( VMReg local, VMReg caller_machine_register );
182 void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
183 void set_stack_obj( VMReg local);
184 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
185
186 int heap_size() const;
187 void copy_to(address addr);
188 OopMap* deep_copy();
189
190 bool has_derived_pointer() const PRODUCT_RETURN0;
191
192 bool legal_vm_reg_name(VMReg local) {
193 return OopMapValue::legal_vm_reg_name(local);
194 }
195
196 // Printing
197 void print_on(outputStream* st) const;
198 void print() const { print_on(tty); }
199 };
200
201
202 class OopMapSet : public ResourceObj {
203 friend class VMStructs;
|
29 // Dead - Dead; can be Zapped for debugging
30 // CalleeXX - Callee saved; also describes which caller register is saved
31 // DerivedXX - A derived oop; original oop is described.
32 //
33 // OopMapValue describes a single OopMap entry
34
35 class frame;
36 class RegisterMap;
37 class DerivedPointerEntry;
38
39 class OopMapValue: public StackObj {
40 friend class VMStructs;
41 private:
42 short _value;
43 int value() const { return _value; }
44 void set_value(int value) { _value = value; }
45 short _content_reg;
46
47 public:
48 // Constants
49 enum { type_bits = 5,
50 register_bits = BitsPerShort - type_bits };
51
52 enum { type_shift = 0,
53 register_shift = type_bits };
54
55 enum { type_mask = right_n_bits(type_bits),
56 type_mask_in_place = type_mask << type_shift,
57 register_mask = right_n_bits(register_bits),
58 register_mask_in_place = register_mask << register_shift };
59
60 enum oop_types { // must fit in type_bits
61 unused_value =0, // powers of 2, for masking OopMapStream
62 oop_value = 1,
63 value_value = 2,
64 narrowoop_value = 4,
65 callee_saved_value = 8,
66 derived_oop_value= 16 };
67
68 // Constructors
69 OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
70 OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); }
71 OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); }
72 OopMapValue (CompressedReadStream* stream) { read_from(stream); }
73
74 // Archiving
75 void write_on(CompressedWriteStream* stream) {
76 stream->write_int(value());
77 if(is_callee_saved() || is_derived_oop()) {
78 stream->write_int(content_reg()->value());
79 }
80 }
81
82 void read_from(CompressedReadStream* stream) {
83 set_value(stream->read_int());
84 if(is_callee_saved() || is_derived_oop()) {
85 set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true));
86 }
87 }
88
89 // Querying
90 bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; }
91 bool is_value() { return mask_bits(value(), type_mask_in_place) == value_value; }
92 bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
93 bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
94 bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
95
96 void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
97 void set_value() { set_value((value() & register_mask_in_place) | value_value); }
98 void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
99 void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
100 void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
101
102 VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
103 oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
104
105 static bool legal_vm_reg_name(VMReg p) {
106 return (p->value() == (p->value() & register_mask));
107 }
108
109 void set_reg_type(VMReg p, oop_types t) {
110 set_value((p->value() << register_shift) | t);
111 assert(reg() == p, "sanity check" );
112 assert(type() == t, "sanity check" );
113 }
114
115
116 VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); }
117 void set_content_reg(VMReg r) { _content_reg = r->value(); }
118
119 // Physical location queries
120 bool is_register_loc() { return reg()->is_reg(); }
160
161 public:
162 OopMap(int frame_size, int arg_count);
163
164 // pc-offset handling
165 int offset() const { return _pc_offset; }
166 void set_offset(int o) { _pc_offset = o; }
167
168 // Check to avoid double insertion
169 debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
170
171 // Construction
172 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
173 // slots to hold 4-byte values like ints and floats in the LP64 build.
174 void set_oop ( VMReg local);
175 void set_value( VMReg local);
176 void set_narrowoop(VMReg local);
177 void set_dead ( VMReg local);
178 void set_callee_saved( VMReg local, VMReg caller_machine_register );
179 void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
180 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
181
182 int heap_size() const;
183 void copy_to(address addr);
184 OopMap* deep_copy();
185
186 bool has_derived_pointer() const PRODUCT_RETURN0;
187
188 bool legal_vm_reg_name(VMReg local) {
189 return OopMapValue::legal_vm_reg_name(local);
190 }
191
192 // Printing
193 void print_on(outputStream* st) const;
194 void print() const { print_on(tty); }
195 };
196
197
198 class OopMapSet : public ResourceObj {
199 friend class VMStructs;
|