51 void set_value(int value) { _value = value; } |
51 void set_value(int value) { _value = value; } |
52 short _content_reg; |
52 short _content_reg; |
53 |
53 |
54 public: |
54 public: |
55 // Constants |
55 // Constants |
56 enum { type_bits = 4, |
56 enum { type_bits = 2, |
57 register_bits = BitsPerShort - type_bits }; |
57 register_bits = BitsPerShort - type_bits }; |
58 |
58 |
59 enum { type_shift = 0, |
59 enum { type_shift = 0, |
60 register_shift = type_bits }; |
60 register_shift = type_bits }; |
61 |
61 |
62 enum { type_mask = right_n_bits(type_bits), |
62 enum { type_mask = right_n_bits(type_bits), |
63 type_mask_in_place = type_mask << type_shift, |
63 type_mask_in_place = type_mask << type_shift, |
64 register_mask = right_n_bits(register_bits), |
64 register_mask = right_n_bits(register_bits), |
65 register_mask_in_place = register_mask << register_shift }; |
65 register_mask_in_place = register_mask << register_shift }; |
66 |
66 |
67 enum oop_types { // must fit in type_bits |
67 enum oop_types { |
68 unused_value =0, // powers of 2, for masking OopMapStream |
68 oop_value, |
69 oop_value = 1, |
69 narrowoop_value, |
70 narrowoop_value = 2, |
70 callee_saved_value, |
71 callee_saved_value = 4, |
71 derived_oop_value, |
72 derived_oop_value= 8 }; |
72 unused_value = -1 // Only used as a sentinel value |
|
73 }; |
73 |
74 |
74 // Constructors |
75 // Constructors |
75 OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } |
76 OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } |
76 OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); } |
77 OopMapValue (VMReg reg, oop_types t, VMReg reg2) { |
77 OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); } |
78 set_reg_type(reg, t); |
78 OopMapValue (CompressedReadStream* stream) { read_from(stream); } |
79 set_content_reg(reg2); |
79 |
80 } |
|
81 |
|
82 private: |
|
83 void set_reg_type(VMReg p, oop_types t) { |
|
84 set_value((p->value() << register_shift) | t); |
|
85 assert(reg() == p, "sanity check" ); |
|
86 assert(type() == t, "sanity check" ); |
|
87 } |
|
88 |
|
89 void set_content_reg(VMReg r) { |
|
90 if (is_callee_saved()) { |
|
91 // This can never be a stack location, so we don't need to transform it. |
|
92 assert(r->is_reg(), "Trying to callee save a stack location"); |
|
93 } else if (is_derived_oop()) { |
|
94 assert (r->is_valid(), "must have a valid VMReg"); |
|
95 } else { |
|
96 assert (!r->is_valid(), "valid VMReg not allowed"); |
|
97 } |
|
98 _content_reg = r->value(); |
|
99 } |
|
100 |
|
101 public: |
80 // Archiving |
102 // Archiving |
81 void write_on(CompressedWriteStream* stream) { |
103 void write_on(CompressedWriteStream* stream) { |
82 stream->write_int(value()); |
104 stream->write_int(value()); |
83 if(is_callee_saved() || is_derived_oop()) { |
105 if(is_callee_saved() || is_derived_oop()) { |
84 stream->write_int(content_reg()->value()); |
106 stream->write_int(content_reg()->value()); |
92 } |
114 } |
93 } |
115 } |
94 |
116 |
95 // Querying |
117 // Querying |
96 bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; } |
118 bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; } |
97 bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; } |
119 bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; } |
98 bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } |
120 bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } |
99 bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } |
121 bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } |
100 |
122 |
101 void set_oop() { set_value((value() & register_mask_in_place) | oop_value); } |
|
102 void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); } |
|
103 void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); } |
|
104 void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); } |
|
105 |
|
106 VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } |
123 VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } |
107 oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } |
124 oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } |
108 |
125 |
109 static bool legal_vm_reg_name(VMReg p) { |
126 static bool legal_vm_reg_name(VMReg p) { |
110 return (p->value() == (p->value() & register_mask)); |
127 return (p->value() == (p->value() & register_mask)); |
111 } |
128 } |
112 |
129 |
113 void set_reg_type(VMReg p, oop_types t) { |
|
114 set_value((p->value() << register_shift) | t); |
|
115 assert(reg() == p, "sanity check" ); |
|
116 assert(type() == t, "sanity check" ); |
|
117 } |
|
118 |
|
119 |
|
120 VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); } |
130 VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); } |
121 void set_content_reg(VMReg r) { _content_reg = r->value(); } |
|
122 |
131 |
123 // Physical location queries |
132 // Physical location queries |
124 bool is_register_loc() { return reg()->is_reg(); } |
133 bool is_register_loc() { return reg()->is_reg(); } |
125 bool is_stack_loc() { return reg()->is_stack(); } |
134 bool is_stack_loc() { return reg()->is_stack(); } |
126 |
135 |
154 |
163 |
155 private: |
164 private: |
156 enum DeepCopyToken { _deep_copy_token }; |
165 enum DeepCopyToken { _deep_copy_token }; |
157 OopMap(DeepCopyToken, OopMap* source); // used only by deep_copy |
166 OopMap(DeepCopyToken, OopMap* source); // used only by deep_copy |
158 |
167 |
|
168 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); |
|
169 |
159 public: |
170 public: |
160 OopMap(int frame_size, int arg_count); |
171 OopMap(int frame_size, int arg_count); |
161 |
172 |
162 // pc-offset handling |
173 // pc-offset handling |
163 int offset() const { return _pc_offset; } |
174 int offset() const { return _pc_offset; } |
171 |
182 |
172 // Construction |
183 // Construction |
173 // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd |
184 // 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. |
185 // slots to hold 4-byte values like ints and floats in the LP64 build. |
175 void set_oop ( VMReg local); |
186 void set_oop ( VMReg local); |
176 void set_value( VMReg local); |
|
177 void set_narrowoop(VMReg local); |
187 void set_narrowoop(VMReg local); |
178 void set_dead ( VMReg local); |
|
179 void set_callee_saved( VMReg local, VMReg caller_machine_register ); |
188 void set_callee_saved( VMReg local, VMReg caller_machine_register ); |
180 void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); |
189 void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); |
181 void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); |
|
182 |
190 |
183 int heap_size() const; |
191 int heap_size() const; |
184 void copy_data_to(address addr) const; |
192 void copy_data_to(address addr) const; |
185 OopMap* deep_copy(); |
193 OopMap* deep_copy(); |
186 |
|
187 bool has_derived_pointer() const PRODUCT_RETURN0; |
|
188 |
194 |
189 bool legal_vm_reg_name(VMReg local) { |
195 bool legal_vm_reg_name(VMReg local) { |
190 return OopMapValue::legal_vm_reg_name(local); |
196 return OopMapValue::legal_vm_reg_name(local); |
191 } |
197 } |
192 |
198 |
332 }; |
337 }; |
333 |
338 |
334 class OopMapStream : public StackObj { |
339 class OopMapStream : public StackObj { |
335 private: |
340 private: |
336 CompressedReadStream* _stream; |
341 CompressedReadStream* _stream; |
337 int _mask; |
|
338 int _size; |
342 int _size; |
339 int _position; |
343 int _position; |
340 bool _valid_omv; |
344 bool _valid_omv; |
341 OopMapValue _omv; |
345 OopMapValue _omv; |
342 void find_next(); |
346 void find_next(); |
343 |
347 |
344 public: |
348 public: |
345 OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place); |
349 OopMapStream(OopMap* oop_map); |
346 OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place); |
350 OopMapStream(const ImmutableOopMap* oop_map); |
347 bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; } |
351 bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; } |
348 void next() { find_next(); } |
352 void next() { find_next(); } |
349 OopMapValue current() { return _omv; } |
353 OopMapValue current() { return _omv; } |
350 #ifdef ASSERT |
354 #ifdef ASSERT |
351 int stream_position() const { return _stream->position(); } |
355 int stream_position() const { return _stream->position(); } |