--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -316,6 +316,17 @@
return start_offset;
}
+void LIR_Assembler::clinit_barrier(ciMethod* method) {
+ assert(VM_Version::supports_fast_class_init_checks(), "sanity");
+ assert(!method->holder()->is_not_initialized(), "initialization should have been started");
+
+ Label L_skip_barrier;
+
+ __ mov_metadata(rscratch2, method->holder()->constant_encoding());
+ __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier /*L_fast_path*/);
+ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+ __ bind(L_skip_barrier);
+}
void LIR_Assembler::jobject2reg(jobject o, Register reg) {
if (o == NULL) {
@@ -717,7 +728,7 @@
move_regs(src->as_register(), dest->as_register());
} else if (dest->is_double_cpu()) {
- if (src->type() == T_OBJECT || src->type() == T_ARRAY) {
+ if (is_reference_type(src->type())) {
// Surprising to me but we can see move of a long to t_object
__ verify_oop(src->as_register());
move_regs(src->as_register(), dest->as_register_lo());
@@ -745,7 +756,7 @@
void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {
if (src->is_single_cpu()) {
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
__ str(src->as_register(), frame_map()->address_for_slot(dest->single_stack_ix()));
__ verify_oop(src->as_register());
} else if (type == T_METADATA || type == T_DOUBLE) {
@@ -783,7 +794,7 @@
return;
}
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
__ verify_oop(src->as_register());
if (UseCompressedOops && !wide) {
@@ -858,7 +869,7 @@
assert(dest->is_register(), "should not call otherwise");
if (dest->is_single_cpu()) {
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
__ ldr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));
__ verify_oop(dest->as_register());
} else if (type == T_METADATA) {
@@ -1008,11 +1019,15 @@
ShouldNotReachHere();
}
- if (type == T_ARRAY || type == T_OBJECT) {
+ if (is_reference_type(type)) {
if (UseCompressedOops && !wide) {
__ decode_heap_oop(dest->as_register());
}
- __ verify_oop(dest->as_register());
+
+ if (!UseZGC) {
+ // Load barrier has not yet been applied, so ZGC can't verify the oop here
+ __ verify_oop(dest->as_register());
+ }
} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
if (UseCompressedClassPointers) {
__ decode_klass_not_null(dest->as_register());
@@ -1071,8 +1086,8 @@
// Assembler::EQ does not permit unordered branches, so we add
// another branch here. Likewise, Assembler::NE does not permit
// ordered branches.
- if (is_unordered && op->cond() == lir_cond_equal
- || !is_unordered && op->cond() == lir_cond_notEqual)
+ if ((is_unordered && op->cond() == lir_cond_equal)
+ || (!is_unordered && op->cond() == lir_cond_notEqual))
__ br(Assembler::VS, *(op->ublock()->label()));
switch(op->cond()) {
case lir_cond_equal: acond = Assembler::EQ; break;
@@ -1212,8 +1227,8 @@
__ uxtw(len, len);
if (UseSlowPath ||
- (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
- (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
+ (!UseFastNewObjectArray && is_reference_type(op->type())) ||
+ (!UseFastNewTypeArray && !is_reference_type(op->type()))) {
__ b(*op->stub()->entry());
} else {
Register tmp1 = op->tmp1()->as_register();
@@ -1782,18 +1797,22 @@
switch (code) {
case lir_add: __ fadds (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
case lir_sub: __ fsubs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
+ case lir_mul_strictfp: // fall through
case lir_mul: __ fmuls (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
+ case lir_div_strictfp: // fall through
case lir_div: __ fdivs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
default:
ShouldNotReachHere();
}
} else if (left->is_double_fpu()) {
if (right->is_double_fpu()) {
- // cpu register - cpu register
+ // fpu register - fpu register
switch (code) {
case lir_add: __ faddd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
case lir_sub: __ fsubd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
+ case lir_mul_strictfp: // fall through
case lir_mul: __ fmuld (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
+ case lir_div_strictfp: // fall through
case lir_div: __ fdivd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
default:
ShouldNotReachHere();
@@ -1929,10 +1948,10 @@
if (opr2->is_single_cpu()) {
// cpu register - cpu register
Register reg2 = opr2->as_register();
- if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+ if (is_reference_type(opr1->type())) {
__ cmpoop(reg1, reg2);
} else {
- assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
+ assert(!is_reference_type(opr2->type()), "cmp int, oop?");
__ cmpw(reg1, reg2);
}
return;
@@ -2224,7 +2243,7 @@
CodeStub* stub = op->stub();
int flags = op->flags();
BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
- if (basic_type == T_ARRAY) basic_type = T_OBJECT;
+ if (is_reference_type(basic_type)) basic_type = T_OBJECT;
// if we don't know anything, just go through the generic arraycopy
if (default_type == NULL // || basic_type == T_OBJECT
@@ -2866,7 +2885,11 @@
void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
- assert(patch_code == lir_patch_none, "Patch code not supported");
+ if (patch_code != lir_patch_none) {
+ deoptimize_trap(info);
+ return;
+ }
+
__ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr()));
}
@@ -2879,40 +2902,7 @@
__ far_call(RuntimeAddress(dest));
} else {
__ mov(rscratch1, RuntimeAddress(dest));
- int len = args->length();
- int type = 0;
- if (! result->is_illegal()) {
- switch (result->type()) {
- case T_VOID:
- type = 0;
- break;
- case T_INT:
- case T_LONG:
- case T_OBJECT:
- type = 1;
- break;
- case T_FLOAT:
- type = 2;
- break;
- case T_DOUBLE:
- type = 3;
- break;
- default:
- ShouldNotReachHere();
- break;
- }
- }
- int num_gpargs = 0;
- int num_fpargs = 0;
- for (int i = 0; i < args->length(); i++) {
- LIR_Opr arg = args->at(i);
- if (arg->type() == T_FLOAT || arg->type() == T_DOUBLE) {
- num_fpargs++;
- } else {
- num_gpargs++;
- }
- }
- __ blrt(rscratch1, num_gpargs, num_fpargs, type);
+ __ blr(rscratch1);
}
if (info != NULL) {
@@ -3141,7 +3131,7 @@
void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp_op) {
Address addr = as_Address(src->as_address_ptr());
BasicType type = src->type();
- bool is_oop = type == T_OBJECT || type == T_ARRAY;
+ bool is_oop = is_reference_type(type);
void (MacroAssembler::* add)(Register prev, RegisterOrConstant incr, Register addr);
void (MacroAssembler::* xchg)(Register prev, Register newv, Register addr);