@@ -83,126 +83,94 @@ jint VectorSupport::klass2length(InstanceKlass* ik) {
83
83
return vlen;
84
84
}
85
85
86
- void VectorSupport::init_vector_array (typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr) {
87
- int elem_size = type2aelembytes (elem_bt);
88
- for (int i = 0 ; i < num_elem; i++) {
86
+ void VectorSupport::init_payload_element (typeArrayOop arr, bool is_mask, BasicType elem_bt, int index, address addr) {
87
+ if (is_mask) {
88
+ // Masks require special handling: when boxed they are packed and stored in boolean
89
+ // arrays, but in scalarized form they have the same size as corresponding vectors.
90
+ // For example, Int512Mask is represented in memory as boolean[16], but
91
+ // occupies the whole 512-bit vector register when scalarized.
92
+ // (In generated code, the conversion is performed by VectorStoreMask.)
93
+ //
94
+ // TODO: revisit when predicate registers are fully supported.
89
95
switch (elem_bt) {
90
- case T_BYTE: {
91
- jbyte elem_value = *(jbyte*) (value_addr + i * elem_size);
92
- arr->byte_at_put (i, elem_value);
93
- break ;
94
- }
95
- case T_SHORT: {
96
- jshort elem_value = *(jshort*) (value_addr + i * elem_size);
97
- arr->short_at_put (i, elem_value);
98
- break ;
99
- }
100
- case T_INT: {
101
- jint elem_value = *(jint*) (value_addr + i * elem_size);
102
- arr->int_at_put (i, elem_value);
103
- break ;
104
- }
105
- case T_LONG: {
106
- jlong elem_value = *(jlong*) (value_addr + i * elem_size);
107
- arr->long_at_put (i, elem_value);
108
- break ;
109
- }
110
- case T_FLOAT: {
111
- jfloat elem_value = *(jfloat*) (value_addr + i * elem_size);
112
- arr->float_at_put (i, elem_value);
113
- break ;
114
- }
115
- case T_DOUBLE: {
116
- jdouble elem_value = *(jdouble*) (value_addr + i * elem_size);
117
- arr->double_at_put (i, elem_value);
118
- break ;
119
- }
120
- default :
121
- fatal (" unsupported: %s" , type2name (elem_bt));
96
+ case T_BYTE: arr->bool_at_put (index, (*(jbyte*)addr) != 0 ); break ;
97
+ case T_SHORT: arr->bool_at_put (index, (*(jshort*)addr) != 0 ); break ;
98
+ case T_INT: // fall-through
99
+ case T_FLOAT: arr->bool_at_put (index, (*(jint*)addr) != 0 ); break ;
100
+ case T_LONG: // fall-through
101
+ case T_DOUBLE: arr->bool_at_put (index, (*(jlong*)addr) != 0 ); break ;
102
+
103
+ default : fatal (" unsupported: %s" , type2name (elem_bt));
122
104
}
123
- }
124
- }
125
-
126
- void VectorSupport::init_mask_array (typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr) {
127
- int elem_size = type2aelembytes (elem_bt);
128
-
129
- for (int i = 0 ; i < num_elem; i++) {
105
+ } else {
130
106
switch (elem_bt) {
131
- case T_BYTE: {
132
- jbyte elem_value = *(jbyte*) (value_addr + i * elem_size);
133
- arr->bool_at_put (i, elem_value != 0 );
134
- break ;
135
- }
136
- case T_SHORT: {
137
- jshort elem_value = *(jshort*) (value_addr + i * elem_size);
138
- arr->bool_at_put (i, elem_value != 0 );
139
- break ;
140
- }
141
- case T_INT: // fall-through
142
- case T_FLOAT: {
143
- jint elem_value = *(jint*) (value_addr + i * elem_size);
144
- arr->bool_at_put (i, elem_value != 0 );
145
- break ;
146
- }
147
- case T_LONG: // fall-through
148
- case T_DOUBLE: {
149
- jlong elem_value = *(jlong*) (value_addr + i * elem_size);
150
- arr->bool_at_put (i, elem_value != 0 );
151
- break ;
152
- }
153
- default :
154
- fatal (" unsupported: %s" , type2name (elem_bt));
107
+ case T_BYTE: arr-> byte_at_put (index, *(jbyte*)addr); break ;
108
+ case T_SHORT: arr-> short_at_put (index, *(jshort*)addr); break ;
109
+ case T_INT: arr-> int_at_put (index, *(jint*)addr); break ;
110
+ case T_FLOAT: arr-> float_at_put (index, *(jfloat*)addr); break ;
111
+ case T_LONG: arr-> long_at_put (index, *(jlong*)addr); break ;
112
+ case T_DOUBLE: arr->double_at_put (index, *(jdouble*)addr); break ;
113
+
114
+ default : fatal (" unsupported: %s" , type2name (elem_bt));
155
115
}
156
116
}
157
117
}
158
118
159
- oop VectorSupport::allocate_vector_payload_helper (InstanceKlass* ik, BasicType elem_bt, int num_elem, address value_addr, TRAPS) {
160
-
119
+ Handle VectorSupport::allocate_vector_payload_helper (InstanceKlass* ik, frame* fr, RegisterMap* reg_map, Location location, TRAPS) {
161
120
bool is_mask = is_vector_mask (ik);
162
121
122
+ int num_elem = klass2length (ik);
123
+ BasicType elem_bt = klass2bt (ik);
124
+ int elem_size = type2aelembytes (elem_bt);
125
+
163
126
// On-heap vector values are represented as primitive arrays.
164
127
TypeArrayKlass* tak = TypeArrayKlass::cast (Universe::typeArrayKlassObj (is_mask ? T_BOOLEAN : elem_bt));
165
128
166
- typeArrayOop arr = tak->allocate (num_elem, CHECK_NULL ); // safepoint
129
+ typeArrayOop arr = tak->allocate (num_elem, CHECK_NH ); // safepoint
167
130
168
- if (is_mask) {
169
- init_mask_array (arr, elem_bt, num_elem, value_addr);
131
+ if (location.is_register ()) {
132
+ // Value was in a callee-saved register.
133
+ VMReg vreg = VMRegImpl::as_VMReg (location.register_number ());
134
+
135
+ for (int i = 0 ; i < num_elem; i++) {
136
+ int vslot = (i * elem_size) / VMRegImpl::stack_slot_size;
137
+ int off = (i * elem_size) % VMRegImpl::stack_slot_size;
138
+
139
+ address elem_addr = reg_map->location (vreg->next (vslot)) + off;
140
+ init_payload_element (arr, is_mask, elem_bt, i, elem_addr);
141
+ }
142
+ } else {
143
+ // Value was directly saved on the stack.
144
+ address base_addr = ((address)fr->unextended_sp ()) + location.stack_offset ();
145
+ for (int i = 0 ; i < num_elem; i++) {
146
+ init_payload_element (arr, is_mask, elem_bt, i, base_addr + i * elem_size);
147
+ }
148
+ }
149
+ return Handle (THREAD, arr);
150
+ }
151
+
152
+ Handle VectorSupport::allocate_vector_payload (InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ScopeValue* payload, TRAPS) {
153
+ if (payload->is_location () &&
154
+ payload->as_LocationValue ()->location ().type () == Location::vector) {
155
+ // Vector value in an aligned adjacent tuple (1, 2, 4, 8, or 16 slots).
156
+ Location location = payload->as_LocationValue ()->location ();
157
+ return allocate_vector_payload_helper (ik, fr, reg_map, location, THREAD); // safepoint
170
158
} else {
171
- init_vector_array (arr, elem_bt, num_elem, value_addr);
159
+ // Scalar-replaced boxed vector representation.
160
+ StackValue* value = StackValue::create_stack_value (fr, reg_map, payload);
161
+ return value->get_obj ();
172
162
}
173
- return arr;
174
163
}
175
164
176
- oop VectorSupport::allocate_vector (InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ObjectValue* ov, TRAPS) {
165
+ instanceOop VectorSupport::allocate_vector (InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ObjectValue* ov, TRAPS) {
177
166
assert (is_vector (ik), " %s not a vector" , ik->name ()->as_C_string ());
178
167
assert (ov->field_size () == 1 , " %s not a vector" , ik->name ()->as_C_string ());
179
168
180
- // Vector value in an aligned adjacent tuple (1, 2, 4, 8, or 16 slots).
181
- LocationValue* loc_value = ov->field_at (0 )->as_LocationValue ();
182
-
183
- BasicType elem_bt = klass2bt (ik);
184
- int num_elem = klass2length (ik);
185
-
186
- Handle vbox = ik->allocate_instance_handle (CHECK_NULL);
187
-
188
- Location loc = loc_value->location ();
189
-
190
- oop payload = NULL ;
191
- if (loc.type () == Location::vector) {
192
- address value_addr = loc.is_register ()
193
- // Value was in a callee-save register
194
- ? reg_map->location (VMRegImpl::as_VMReg (loc.register_number ()))
195
- // Else value was directly saved on the stack. The frame's original stack pointer,
196
- // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used.
197
- : ((address)fr->unextended_sp ()) + loc.stack_offset ();
198
- payload = allocate_vector_payload_helper (ik, elem_bt, num_elem, value_addr, CHECK_NULL); // safepoint
199
- } else {
200
- // assert(false, "interesting");
201
- StackValue* value = StackValue::create_stack_value (fr, reg_map, loc_value);
202
- payload = value->get_obj ()();
203
- }
204
- vector_VectorPayload::set_payload (vbox (), payload);
205
- return vbox ();
169
+ ScopeValue* payload_value = ov->field_at (0 );
170
+ Handle payload_instance = VectorSupport::allocate_vector_payload (ik, fr, reg_map, payload_value, CHECK_NULL);
171
+ instanceOop vbox = ik->allocate_instance (CHECK_NULL);
172
+ vector_VectorPayload::set_payload (vbox, payload_instance ());
173
+ return vbox;
206
174
}
207
175
208
176
#ifdef COMPILER2
0 commit comments