1553 // FIXME -- I can't find any other way to pass an address to access_load_at(). 1554 class TempResolvedAddress: public Instruction { 1555 public: 1556 TempResolvedAddress(ValueType* type, LIR_Opr addr) : Instruction(type) { 1557 set_operand(addr); 1558 } 1559 virtual void input_values_do(ValueVisitor*) {} 1560 virtual void visit(InstructionVisitor* v) {} 1561 virtual const char* name() const { return "TempResolvedAddress"; } 1562 }; 1563 1564 void LIRGenerator::access_flattened_array(bool is_load, LIRItem& array, LIRItem& index, LIRItem& obj_item) { 1565 // Find the starting address of the source (inside the array) 1566 ciType* array_type = array.value()->declared_type(); 1567 ciValueArrayKlass* value_array_klass = array_type->as_value_array_klass(); 1568 ciValueKlass* elem_klass = value_array_klass->element_klass()->as_value_klass(); 1569 int array_header_size = value_array_klass->array_header_in_bytes(); 1570 1571 #ifndef _LP64 1572 LIR_Opr index_op = index.result(); 1573 #else 1574 LIR_Opr index_op = new_register(T_LONG); 1575 __ convert(Bytecodes::_i2l, index.result(), index_op); 1576 #endif 1577 // Need to shift manually, as LIR_Address can scale only up to 3. 1578 __ shift_left(index_op, value_array_klass->log2_element_size(), index_op); 1579 1580 LIR_Opr elm_op = new_pointer_register(); 1581 LIR_Address* elm_address = new LIR_Address(array.result(), index_op, array_header_size, T_ADDRESS); 1582 __ leal(LIR_OprFact::address(elm_address), elm_op); 1583 1584 for (int i = 0; i < elem_klass->nof_nonstatic_fields(); i++) { 1585 ciField* inner_field = elem_klass->nonstatic_field_at(i); 1586 assert(!inner_field->is_flattened(), "flattened fields must have been expanded"); 1587 int obj_offset = inner_field->offset(); 1588 int elm_offset = obj_offset - elem_klass->first_field_offset(); // object header is not stored in array. 1589 1590 BasicType field_type = inner_field->type()->basic_type(); 1591 switch (field_type) { 1592 case T_BYTE: 1593 case T_BOOLEAN: 1594 case T_SHORT: 1595 case T_CHAR: | 1553 // FIXME -- I can't find any other way to pass an address to access_load_at(). 1554 class TempResolvedAddress: public Instruction { 1555 public: 1556 TempResolvedAddress(ValueType* type, LIR_Opr addr) : Instruction(type) { 1557 set_operand(addr); 1558 } 1559 virtual void input_values_do(ValueVisitor*) {} 1560 virtual void visit(InstructionVisitor* v) {} 1561 virtual const char* name() const { return "TempResolvedAddress"; } 1562 }; 1563 1564 void LIRGenerator::access_flattened_array(bool is_load, LIRItem& array, LIRItem& index, LIRItem& obj_item) { 1565 // Find the starting address of the source (inside the array) 1566 ciType* array_type = array.value()->declared_type(); 1567 ciValueArrayKlass* value_array_klass = array_type->as_value_array_klass(); 1568 ciValueKlass* elem_klass = value_array_klass->element_klass()->as_value_klass(); 1569 int array_header_size = value_array_klass->array_header_in_bytes(); 1570 1571 #ifndef _LP64 1572 LIR_Opr index_op = index.result(); 1573 // FIXME -- on 32-bit, the shift below can overflow, so we need to check that 1574 // the top (value_array_klass->log2_element_size()+1) bits of index_op must be zero, or 1575 // else throw ArrayIndexOutOfBoundsException 1576 #else 1577 LIR_Opr index_op = new_register(T_LONG); 1578 if (index.result()->is_constant()) { 1579 jint const_index = index.result()->as_jint(); 1580 __ move(LIR_OprFact::longConst(const_index), index_op); 1581 } else { 1582 __ convert(Bytecodes::_i2l, index.result(), index_op); 1583 } 1584 #endif 1585 // Need to shift manually, as LIR_Address can scale only up to 3. 1586 __ shift_left(index_op, value_array_klass->log2_element_size(), index_op); 1587 1588 LIR_Opr elm_op = new_pointer_register(); 1589 LIR_Address* elm_address = new LIR_Address(array.result(), index_op, array_header_size, T_ADDRESS); 1590 __ leal(LIR_OprFact::address(elm_address), elm_op); 1591 1592 for (int i = 0; i < elem_klass->nof_nonstatic_fields(); i++) { 1593 ciField* inner_field = elem_klass->nonstatic_field_at(i); 1594 assert(!inner_field->is_flattened(), "flattened fields must have been expanded"); 1595 int obj_offset = inner_field->offset(); 1596 int elm_offset = obj_offset - elem_klass->first_field_offset(); // object header is not stored in array. 1597 1598 BasicType field_type = inner_field->type()->basic_type(); 1599 switch (field_type) { 1600 case T_BYTE: 1601 case T_BOOLEAN: 1602 case T_SHORT: 1603 case T_CHAR: |