[aarch64-port-dev ] Problem with C1 when running C2 build with -server -XX:+TieredCompilation
Andrew Haley
aph at redhat.com
Wed Jul 10 10:25:42 PDT 2013
On 07/10/2013 11:05 AM, Andrew Dinn wrote:
> When I run up the C2 build with tiered compilation I hit an Unimplemented
Done. I think this is OK, but I hit a C2 fail. I've pushed it to C2
branch.
Andrew.
# HG changeset patch
# User aph
# Date 1373476947 -3600
# Branch aarch64_c2
# Node ID 99ff1f99338e0c99c7647ec73d14ad600d331709
# Parent e4ac7d180652786e58abcb3fac5a453ca5dd839d
Enable profiling for C1
diff -r e4ac7d180652 -r 99ff1f99338e src/cpu/aarch64/vm/c1_CodeStubs_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_CodeStubs_aarch64.cpp Wed Jul 10 13:20:58 2013 +0100
+++ b/src/cpu/aarch64/vm/c1_CodeStubs_aarch64.cpp Wed Jul 10 18:22:27 2013 +0100
@@ -111,7 +111,15 @@
__ b(_continuation);
}
-void CounterOverflowStub::emit_code(LIR_Assembler* ce) { Unimplemented(); }
+void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
+ __ bind(_entry);
+ ce->store_parameter(_method->as_register(), 1);
+ ce->store_parameter(_bci, 0);
+ __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::counter_overflow_id)));
+ ce->add_call_info_here(_info);
+ ce->verify_oop_map(_info);
+ __ b(_continuation);
+}
RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
bool throw_index_out_of_bounds_exception)
diff -r e4ac7d180652 -r 99ff1f99338e src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Wed Jul 10 13:20:58 2013 +0100
+++ b/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Wed Jul 10 18:22:27 2013 +0100
@@ -2021,7 +2021,6 @@
void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) {
- ShouldNotReachHere();
assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");
int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;
assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
@@ -2405,7 +2404,86 @@
}
-void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { Unimplemented(); }
+void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
+ ciMethod* method = op->profiled_method();
+ int bci = op->profiled_bci();
+ ciMethod* callee = op->profiled_callee();
+
+ // Update counter for all call types
+ ciMethodData* md = method->method_data_or_null();
+ assert(md != NULL, "Sanity");
+ ciProfileData* data = md->bci_to_data(bci);
+ assert(data->is_CounterData(), "need CounterData for calls");
+ assert(op->mdo()->is_single_cpu(), "mdo must be allocated");
+ Register mdo = op->mdo()->as_register();
+ __ mov_metadata(mdo, md->constant_encoding());
+ Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
+ Bytecodes::Code bc = method->java_code_at_bci(bci);
+ const bool callee_is_static = callee->is_loaded() && callee->is_static();
+ // Perform additional virtual call profiling for invokevirtual and
+ // invokeinterface bytecodes
+ if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
+ !callee_is_static && // required for optimized MH invokes
+ C1ProfileVirtualCalls) {
+ assert(op->recv()->is_single_cpu(), "recv must be allocated");
+ Register recv = op->recv()->as_register();
+ assert_different_registers(mdo, recv);
+ assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
+ ciKlass* known_klass = op->known_holder();
+ if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
+ // We know the type that will be seen at this call site; we can
+ // statically update the MethodData* rather than needing to do
+ // dynamic tests on the receiver type
+
+ // NOTE: we should probably put a lock around this search to
+ // avoid collisions by concurrent compilations
+ ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
+ uint i;
+ for (i = 0; i < VirtualCallData::row_limit(); i++) {
+ ciKlass* receiver = vc_data->receiver(i);
+ if (known_klass->equals(receiver)) {
+ Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
+ __ addptr(data_addr, DataLayout::counter_increment);
+ return;
+ }
+ }
+
+ // Receiver type not found in profile data; select an empty slot
+
+ // Note that this is less efficient than it should be because it
+ // always does a write to the receiver part of the
+ // VirtualCallData rather than just the first time
+ for (i = 0; i < VirtualCallData::row_limit(); i++) {
+ ciKlass* receiver = vc_data->receiver(i);
+ if (receiver == NULL) {
+ Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
+ __ mov_metadata(rscratch1, known_klass->constant_encoding());
+ __ str(rscratch1, recv_addr);
+ Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
+ __ ldr(rscratch1, data_addr);
+ __ add(rscratch1, rscratch1, DataLayout::counter_increment);
+ __ str(rscratch1, data_addr);
+ return;
+ }
+ }
+ } else {
+ __ load_klass(recv, recv);
+ Label update_done;
+ type_profile_helper(mdo, md, data, recv, &update_done);
+ // Receiver did not match any saved receiver and there is no empty row for it.
+ // Increment total counter to indicate polymorphic case.
+ __ addptr(counter_addr, DataLayout::counter_increment);
+
+ __ bind(update_done);
+ }
+ } else {
+ // Static call
+ __ ldr(rscratch1, counter_addr);
+ __ add(rscratch1, rscratch1, DataLayout::counter_increment);
+ __ str(rscratch1, counter_addr);
+ }
+}
+
void LIR_Assembler::emit_delay(LIR_OpDelay*) {
Unimplemented();
diff -r e4ac7d180652 -r 99ff1f99338e src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Wed Jul 10 13:20:58 2013 +0100
+++ b/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Wed Jul 10 18:22:27 2013 +0100
@@ -224,7 +224,32 @@
}
}
-LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { Unimplemented(); return LIR_OprFact::illegalOpr; }
+LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {
+ LIR_Opr r;
+ if (type == T_LONG) {
+ r = LIR_OprFact::longConst(x);
+ if (!Assembler::operand_valid_for_logical_immediate(false, x)) {
+ LIR_Opr tmp = new_register(type);
+ __ move(r, tmp);
+ return tmp;
+ }
+ } else if (type == T_INT) {
+ r = LIR_OprFact::intConst(x);
+ if (!Assembler::operand_valid_for_logical_immediate(true, x)) {
+ // This is all rather nasty. We don't know whether our constant
+ // is required for a logical or an arithmetic operation, wo we
+ // don't know what the range of valid values is!!
+ LIR_Opr tmp = new_register(type);
+ __ move(r, tmp);
+ return tmp;
+ }
+ } else {
+ ShouldNotReachHere();
+ }
+ return r;
+}
+
+
void LIRGenerator::increment_counter(address counter, BasicType type, int step) {
LIR_Opr pointer = new_pointer_register();
diff -r e4ac7d180652 -r 99ff1f99338e src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp Wed Jul 10 13:20:58 2013 +0100
+++ b/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp Wed Jul 10 18:22:27 2013 +0100
@@ -783,6 +783,24 @@
break;
+ case counter_overflow_id:
+ {
+ Register bci = r0, method = r1;
+ __ enter();
+ OopMap* map = save_live_registers(sasm, 3);
+ // Retrieve bci
+ __ ldr(bci, Address(rfp, 2*BytesPerWord));
+ // And a pointer to the Method*
+ __ ldr(method, Address(rfp, 3*BytesPerWord));
+ int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
+ oop_maps = new OopMapSet();
+ oop_maps->add_gc_map(call_offset, map);
+ restore_live_registers(sasm);
+ __ leave();
+ __ ret(lr);
+ }
+ break;
+
case new_type_array_id:
case new_object_array_id:
{
More information about the aarch64-port-dev
mailing list