Skip to content

Commit 57025e6

Browse files
author
Vladimir Ivanov
committed
8256073: Improve vector rematerialization support
Reviewed-by: thartmann, kvn
1 parent 41c0587 commit 57025e6

File tree

2 files changed

+73
-104
lines changed

2 files changed

+73
-104
lines changed

src/hotspot/share/prims/vectorSupport.cpp

Lines changed: 68 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -83,126 +83,94 @@ jint VectorSupport::klass2length(InstanceKlass* ik) {
8383
return vlen;
8484
}
8585

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.
8995
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));
122104
}
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 {
130106
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));
155115
}
156116
}
157117
}
158118

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) {
161120
bool is_mask = is_vector_mask(ik);
162121

122+
int num_elem = klass2length(ik);
123+
BasicType elem_bt = klass2bt(ik);
124+
int elem_size = type2aelembytes(elem_bt);
125+
163126
// On-heap vector values are represented as primitive arrays.
164127
TypeArrayKlass* tak = TypeArrayKlass::cast(Universe::typeArrayKlassObj(is_mask ? T_BOOLEAN : elem_bt));
165128

166-
typeArrayOop arr = tak->allocate(num_elem, CHECK_NULL); // safepoint
129+
typeArrayOop arr = tak->allocate(num_elem, CHECK_NH); // safepoint
167130

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
170158
} 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();
172162
}
173-
return arr;
174163
}
175164

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) {
177166
assert(is_vector(ik), "%s not a vector", ik->name()->as_C_string());
178167
assert(ov->field_size() == 1, "%s not a vector", ik->name()->as_C_string());
179168

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;
206174
}
207175

208176
#ifdef COMPILER2

src/hotspot/share/prims/vectorSupport.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ extern "C" {
3939

4040
class VectorSupport : AllStatic {
4141
private:
42-
static void init_mask_array(typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr);
43-
static void init_vector_array(typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr);
44-
static oop allocate_vector_payload_helper(InstanceKlass* ik, BasicType elem_bt, int num_elem, address value_addr, TRAPS);
42+
static Handle allocate_vector_payload(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ScopeValue* payload, TRAPS);
43+
static Handle allocate_vector_payload_helper(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, Location location, TRAPS);
44+
45+
static void init_payload_element(typeArrayOop arr, bool is_mask, BasicType elem_bt, int index, address addr);
4546

4647
static BasicType klass2bt(InstanceKlass* ik);
4748
static jint klass2length(InstanceKlass* ik);
@@ -81,7 +82,7 @@ class VectorSupport : AllStatic {
8182

8283
static int vop2ideal(jint vop, BasicType bt);
8384

84-
static oop allocate_vector(InstanceKlass* holder, frame* fr, RegisterMap* reg_map, ObjectValue* sv, TRAPS);
85+
static instanceOop allocate_vector(InstanceKlass* holder, frame* fr, RegisterMap* reg_map, ObjectValue* sv, TRAPS);
8586

8687
static bool is_vector(Klass* klass);
8788
static bool is_vector_mask(Klass* klass);

0 commit comments

Comments
 (0)