33 // A ValueKlass is a specialized InstanceKlass for value types.
34
35
36 class ValueKlass: public InstanceKlass {
37 friend class VMStructs;
38 friend class InstanceKlass;
39
40 private:
41
42 // Constructor
43 ValueKlass(const ClassFileParser& parser)
44 : InstanceKlass(parser, InstanceKlass::_misc_kind_value_type, InstanceKlass::ID) {
45 _adr_valueklass_fixed_block = valueklass_static_block();
46 // Addresses used for value type calling convention
47 *((Array<SigEntry>**)adr_extended_sig()) = NULL;
48 *((Array<VMRegPair>**)adr_return_regs()) = NULL;
49 *((address*)adr_pack_handler()) = NULL;
50 *((address*)adr_unpack_handler()) = NULL;
51 assert(pack_handler() == NULL, "pack handler not null");
52 *((int*)adr_default_value_offset()) = 0;
53 set_prototype_header(markOopDesc::always_locked_prototype());
54 }
55
56 ValueKlassFixedBlock* valueklass_static_block() const {
57 address adr_jf = adr_value_fields_klasses();
58 if (adr_jf != NULL) {
59 return (ValueKlassFixedBlock*)(adr_jf + this->java_fields_count() * sizeof(Klass*));
60 }
61
62 address adr_fing = adr_fingerprint();
63 if (adr_fing != NULL) {
64 return (ValueKlassFixedBlock*)(adr_fingerprint() + sizeof(u8));
65 }
66
67 InstanceKlass** adr_host = adr_unsafe_anonymous_host();
68 if (adr_host != NULL) {
69 return (ValueKlassFixedBlock*)(adr_host + 1);
70 }
71
72 Klass* volatile* adr_impl = adr_implementor();
94 }
95
96 address adr_unpack_handler() const {
97 assert(_adr_valueklass_fixed_block != NULL, "Should have been initialized");
98 return ((address)_adr_valueklass_fixed_block) + in_bytes(byte_offset_of(ValueKlassFixedBlock, _unpack_handler));
99 }
100
101 address pack_handler() const {
102 return *(address*)adr_pack_handler();
103 }
104
105 address unpack_handler() const {
106 return *(address*)adr_unpack_handler();
107 }
108
109 address adr_default_value_offset() const {
110 assert(_adr_valueklass_fixed_block != NULL, "Should have been initialized");
111 return ((address)_adr_valueklass_fixed_block) + in_bytes(default_value_offset_offset());
112 }
113
114 int collect_fields(GrowableArray<SigEntry>* sig, int base_off = 0) const;
115
116 void cleanup_blobs();
117
118 protected:
119 // Returns the array class for the n'th dimension
120 Klass* array_klass_impl(bool or_null, int n, TRAPS);
121
122 // Returns the array class with this class as element type
123 Klass* array_klass_impl(bool or_null, TRAPS);
124
125 public:
126 // Type testing
127 bool is_value_slow() const { return true; }
128
129 oop value_mirror() const {
130 return java_lang_Class::value_mirror(java_mirror());
131 }
132
133 // Casting from Klass*
134 static ValueKlass* cast(Klass* k) {
135 assert(k->is_value(), "cast to ValueKlass");
136 return (ValueKlass*) k;
137 }
138
139 // Use this to return the size of an instance in heap words
140 // Implementation is currently simple because all value types are allocated
141 // in Java heap like Java objects.
142 virtual int size_helper() const {
143 return layout_helper_to_size_helper(layout_helper());
144 }
145
146 // allocate_instance() allocates a stand alone value in the Java heap
147 instanceOop allocate_instance(TRAPS);
148
149 // minimum number of bytes occupied by nonstatic fields, HeapWord aligned or pow2
150 int raw_value_byte_size() const;
151
152 int first_field_offset() const;
153
154 address data_for_oop(oop o) const {
155 return ((address) (void*) o) + first_field_offset();
156 }
157
158 oop oop_for_data(address data) const {
159 oop o = (oop) (data - first_field_offset());
160 assert(oopDesc::is_oop(o, false), "Not an oop");
161 return o;
162 }
163
164 // Query if h/w provides atomic load/store
165 bool is_atomic();
166
167 bool flatten_array();
168
169 bool contains_oops() const { return nonstatic_oop_map_count() > 0; }
170 int nonstatic_oop_count();
171
172 // Prototype general store methods...
173
174 // copy the fields, with no concern for GC barriers
175 void raw_field_copy(void* src, void* dst, size_t raw_byte_size);
176
177 void value_store(void* src, void* dst, bool dst_is_heap, bool dst_uninitialized) {
178 value_store(src, dst, nonstatic_field_size() << LogBytesPerHeapOop, dst_is_heap, dst_uninitialized);
179 }
180
181 // store the value of this klass contained with src into dst, raw data ptr
182 void value_store(void* src, void* dst, size_t raw_byte_size, bool dst_is_heap, bool dst_uninitialized);
183
184 // GC support...
185
186 void iterate_over_inside_oops(OopClosure* f, oop value);
187
188 // oop iterate raw value type data pointer (where oop_addr may not be an oop, but backing/array-element)
189 template <typename T, class OopClosureType>
190 inline void oop_iterate_specialized(const address oop_addr, OopClosureType* closure);
191
192 template <typename T, class OopClosureType>
193 inline void oop_iterate_specialized_bounded(const address oop_addr, OopClosureType* closure, void* lo, void* hi);
194
195 // calling convention support
196 void initialize_calling_convention(TRAPS);
197 Array<SigEntry>* extended_sig() const {
198 return *((Array<SigEntry>**)adr_extended_sig());
199 }
200 Array<VMRegPair>* return_regs() const {
201 return *((Array<VMRegPair>**)adr_return_regs());
202 }
203 bool can_be_returned_as_fields() const;
204 void save_oop_fields(const RegisterMap& map, GrowableArray<Handle>& handles) const;
205 void restore_oop_results(RegisterMap& map, GrowableArray<Handle>& handles) const;
|
33 // A ValueKlass is a specialized InstanceKlass for value types.
34
35
36 class ValueKlass: public InstanceKlass {
37 friend class VMStructs;
38 friend class InstanceKlass;
39
40 private:
41
42 // Constructor
43 ValueKlass(const ClassFileParser& parser)
44 : InstanceKlass(parser, InstanceKlass::_misc_kind_value_type, InstanceKlass::ID) {
45 _adr_valueklass_fixed_block = valueklass_static_block();
46 // Addresses used for value type calling convention
47 *((Array<SigEntry>**)adr_extended_sig()) = NULL;
48 *((Array<VMRegPair>**)adr_return_regs()) = NULL;
49 *((address*)adr_pack_handler()) = NULL;
50 *((address*)adr_unpack_handler()) = NULL;
51 assert(pack_handler() == NULL, "pack handler not null");
52 *((int*)adr_default_value_offset()) = 0;
53 *((Klass**)adr_value_array_klass()) = NULL;
54 set_prototype_header(markOopDesc::always_locked_prototype());
55 }
56
57 ValueKlassFixedBlock* valueklass_static_block() const {
58 address adr_jf = adr_value_fields_klasses();
59 if (adr_jf != NULL) {
60 return (ValueKlassFixedBlock*)(adr_jf + this->java_fields_count() * sizeof(Klass*));
61 }
62
63 address adr_fing = adr_fingerprint();
64 if (adr_fing != NULL) {
65 return (ValueKlassFixedBlock*)(adr_fingerprint() + sizeof(u8));
66 }
67
68 InstanceKlass** adr_host = adr_unsafe_anonymous_host();
69 if (adr_host != NULL) {
70 return (ValueKlassFixedBlock*)(adr_host + 1);
71 }
72
73 Klass* volatile* adr_impl = adr_implementor();
95 }
96
97 address adr_unpack_handler() const {
98 assert(_adr_valueklass_fixed_block != NULL, "Should have been initialized");
99 return ((address)_adr_valueklass_fixed_block) + in_bytes(byte_offset_of(ValueKlassFixedBlock, _unpack_handler));
100 }
101
102 address pack_handler() const {
103 return *(address*)adr_pack_handler();
104 }
105
106 address unpack_handler() const {
107 return *(address*)adr_unpack_handler();
108 }
109
110 address adr_default_value_offset() const {
111 assert(_adr_valueklass_fixed_block != NULL, "Should have been initialized");
112 return ((address)_adr_valueklass_fixed_block) + in_bytes(default_value_offset_offset());
113 }
114
115 address adr_value_array_klass() const {
116 assert(_adr_valueklass_fixed_block != NULL, "Should have been initialized");
117 return ((address)_adr_valueklass_fixed_block) + in_bytes(byte_offset_of(ValueKlassFixedBlock, _value_array_klass));
118 }
119
120 Klass* get_value_array_klass() const {
121 return *(Klass**)adr_value_array_klass();
122 }
123
124 Klass* acquire_value_array_klass() const {
125 return OrderAccess::load_acquire((Klass**)adr_value_array_klass());
126 }
127
128 Klass* allocate_value_array_klass(TRAPS);
129
130 int collect_fields(GrowableArray<SigEntry>* sig, int base_off = 0) const;
131
132 void cleanup_blobs();
133
134 protected:
135 // Returns the array class for the n'th dimension
136 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS);
137
138 // Returns the array class with this class as element type
139 Klass* array_klass_impl(ArrayStorageProperties storage_props, bool or_null, TRAPS);
140
141 // Specifically flat array klass
142 Klass* value_array_klass(ArrayStorageProperties storage_props, bool or_null, int rank, TRAPS);
143
144 public:
145 // Type testing
146 bool is_value_slow() const { return true; }
147
148 oop value_mirror() const {
149 return java_lang_Class::value_mirror(java_mirror());
150 }
151
152 // Casting from Klass*
153 static ValueKlass* cast(Klass* k) {
154 assert(k->is_value(), "cast to ValueKlass");
155 return (ValueKlass*) k;
156 }
157
158 // Use this to return the size of an instance in heap words
159 // Implementation is currently simple because all value types are allocated
160 // in Java heap like Java objects.
161 virtual int size_helper() const {
162 return layout_helper_to_size_helper(layout_helper());
163 }
164
165 // Metadata iterators
166 void array_klasses_do(void f(Klass* k));
167
168 // allocate_instance() allocates a stand alone value in the Java heap
169 instanceOop allocate_instance(TRAPS);
170
171 // minimum number of bytes occupied by nonstatic fields, HeapWord aligned or pow2
172 int raw_value_byte_size() const;
173
174 int first_field_offset() const;
175
176 address data_for_oop(oop o) const {
177 return ((address) (void*) o) + first_field_offset();
178 }
179
180 oop oop_for_data(address data) const {
181 oop o = (oop) (data - first_field_offset());
182 assert(oopDesc::is_oop(o, false), "Not an oop");
183 return o;
184 }
185
186 // Query if h/w provides atomic load/store
187 bool is_atomic();
188
189 bool flatten_array();
190
191 bool contains_oops() const { return nonstatic_oop_map_count() > 0; }
192 int nonstatic_oop_count();
193
194 // Prototype general store methods...
195
196 // copy the fields, with no concern for GC barriers
197 void raw_field_copy(void* src, void* dst, size_t raw_byte_size);
198
199 void value_store(void* src, void* dst, bool dst_is_heap, bool dst_uninitialized) {
200 value_store(src, dst, nonstatic_field_size() << LogBytesPerHeapOop, dst_is_heap, dst_uninitialized);
201 }
202
203 // store the value of this klass contained with src into dst, raw data ptr
204 void value_store(void* src, void* dst, size_t raw_byte_size, bool dst_is_heap, bool dst_uninitialized);
205
206 // GC support...
207 void iterate_over_inside_oops(OopClosure* f, oop value);
208
209 // oop iterate raw value type data pointer (where oop_addr may not be an oop, but backing/array-element)
210 template <typename T, class OopClosureType>
211 inline void oop_iterate_specialized(const address oop_addr, OopClosureType* closure);
212
213 template <typename T, class OopClosureType>
214 inline void oop_iterate_specialized_bounded(const address oop_addr, OopClosureType* closure, void* lo, void* hi);
215
216 // calling convention support
217 void initialize_calling_convention(TRAPS);
218 Array<SigEntry>* extended_sig() const {
219 return *((Array<SigEntry>**)adr_extended_sig());
220 }
221 Array<VMRegPair>* return_regs() const {
222 return *((Array<VMRegPair>**)adr_return_regs());
223 }
224 bool can_be_returned_as_fields() const;
225 void save_oop_fields(const RegisterMap& map, GrowableArray<Handle>& handles) const;
226 void restore_oop_results(RegisterMap& map, GrowableArray<Handle>& handles) const;
|