Skip to content

Commit

Permalink
8299089: Instrument global jni handles with tag to make them distingu…
Browse files Browse the repository at this point in the history
…ishable

Co-authored-by: Stefan Karlsson <stefank@openjdk.org>
Co-authored-by: Martin Doerr <mdoerr@openjdk.org>
Co-authored-by: Leslie Zhai <lzhai@openjdk.org>
Reviewed-by: eosterlund, stefank, ayang
  • Loading branch information
4 people committed Jan 18, 2023
1 parent 66f7387 commit c705673
Show file tree
Hide file tree
Showing 36 changed files with 465 additions and 222 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -122,8 +122,8 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath) {
// If mask changes we need to ensure that the inverse is still encodable as an immediate
STATIC_ASSERT(JNIHandles::weak_tag_mask == 1);
__ andr(obj, obj, ~JNIHandles::weak_tag_mask);
STATIC_ASSERT(JNIHandles::tag_mask == 0b11);
__ andr(obj, obj, ~JNIHandles::tag_mask);
__ ldr(obj, Address(obj, 0)); // *obj
}

Expand Down
54 changes: 44 additions & 10 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -2458,22 +2458,56 @@ void MacroAssembler::verify_heapbase(const char* msg) {
#endif

void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2) {
Label done, not_weak;
assert_different_registers(value, tmp1, tmp2);
Label done, tagged, weak_tagged;

cbz(value, done); // Use NULL as-is.
tst(value, JNIHandles::tag_mask); // Test for tag.
br(Assembler::NE, tagged);

// Resolve local handle
access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, value, Address(value, 0), tmp1, tmp2);
verify_oop(value);
b(done);

STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
tbz(value, 0, not_weak); // Test for jweak tag.
bind(tagged);
STATIC_ASSERT(JNIHandles::TypeTag::weak_global == 0b1);
tbnz(value, 0, weak_tagged); // Test for weak tag.

// Resolve jweak.
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, value,
Address(value, -JNIHandles::weak_tag_value), tmp1, tmp2);
// Resolve global handle
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp1, tmp2);
verify_oop(value);
b(done);

bind(not_weak);
// Resolve (untagged) jobject.
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp1, tmp2);
bind(weak_tagged);
// Resolve jweak.
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
value, Address(value, -JNIHandles::TypeTag::weak_global), tmp1, tmp2);
verify_oop(value);

bind(done);
}

void MacroAssembler::resolve_global_jobject(Register value, Register tmp1, Register tmp2) {
assert_different_registers(value, tmp1, tmp2);
Label done;

cbz(value, done); // Use NULL as-is.

#ifdef ASSERT
{
STATIC_ASSERT(JNIHandles::TypeTag::global == 0b10);
Label valid_global_tag;
tbnz(value, 1, valid_global_tag); // Test for global tag
stop("non global jobject using resolve_global_jobject");
bind(valid_global_tag);
}
#endif

// Resolve global handle
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp1, tmp2);
verify_oop(value);

bind(done);
}

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ class MacroAssembler: public Assembler {
void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)

void resolve_jobject(Register value, Register tmp1, Register tmp2);
void resolve_global_jobject(Register value, Register tmp1, Register tmp2);

// C 'boolean' to Java boolean: x == 0 ? 0 : 1
void c2bool(Register x);
Expand Down
9 changes: 2 additions & 7 deletions src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6923,12 +6923,7 @@ class StubGenerator: public StubCodeGenerator {
// The handle is dereferenced through a load barrier.
static void jfr_epilogue(MacroAssembler* _masm) {
__ reset_last_Java_frame(true);
Label null_jobject;
__ cbz(r0, null_jobject);
DecoratorSet decorators = ACCESS_READ | IN_NATIVE;
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->load_at(_masm, decorators, T_OBJECT, r0, Address(r0, 0), rscratch1, rscratch2);
__ bind(null_jobject);
__ resolve_global_jobject(r0, rscratch1, rscratch2);
}

// For c2: c_rarg0 is junk, call to runtime to write a checkpoint.
Expand All @@ -6943,7 +6938,7 @@ class StubGenerator: public StubCodeGenerator {
framesize // inclusive of return address
};

int insts_size = 512;
int insts_size = 1024;
int locs_size = 64;
CodeBuffer code("jfr_write_checkpoint", insts_size, locs_size);
OopMapSet* oop_maps = new OopMapSet();
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/arm/jniFastGetField_arm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -113,7 +113,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
__ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr));
__ tbnz(Rsafept_cnt, 0, slow_case);

__ bic(R1, R1, JNIHandles::weak_tag_mask);
__ bic(R1, R1, JNIHandles::tag_mask);

if (JvmtiExport::can_post_field_access()) {
// Using barrier to order wrt. JVMTI check and load of result.
Expand Down
59 changes: 48 additions & 11 deletions src/hotspot/cpu/arm/macroAssembler_arm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1284,20 +1284,57 @@ void MacroAssembler::resolve_jobject(Register value,
Register tmp1,
Register tmp2) {
assert_different_registers(value, tmp1, tmp2);
Label done, not_weak;
cbz(value, done); // Use NULL as-is.
STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
tbz(value, 0, not_weak); // Test for jweak tag.
Label done, tagged, weak_tagged;

cbz(value, done); // Use NULL as-is.
tst(value, JNIHandles::tag_mask); // Test for tag.
b(tagged, ne);

// Resolve local handle
access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, Address(value, 0), value, tmp1, tmp2, noreg);
verify_oop(value);
b(done);

bind(tagged);
tst(value, JNIHandles::TypeTag::weak_global); // Test for weak tag.
b(weak_tagged, ne);

// Resolve global handle
access_load_at(T_OBJECT, IN_NATIVE, Address(value, -JNIHandles::TypeTag::global), value, tmp1, tmp2, noreg);
verify_oop(value);
b(done);

bind(weak_tagged);
// Resolve jweak.
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
Address(value, -JNIHandles::weak_tag_value), value, tmp1, tmp2, noreg);
b(done);
bind(not_weak);
// Resolve (untagged) jobject.
access_load_at(T_OBJECT, IN_NATIVE,
Address(value, 0), value, tmp1, tmp2, noreg);
Address(value, -JNIHandles::TypeTag::weak_global), value, tmp1, tmp2, noreg);
verify_oop(value);

bind(done);
}

void MacroAssembler::resolve_global_jobject(Register value,
Register tmp1,
Register tmp2) {
assert_different_registers(value, tmp1, tmp2);
Label done;

cbz(value, done); // Use NULL as-is.

#ifdef ASSERT
{
Label valid_global_tag;
tst(value, JNIHandles::TypeTag::global); // Test for global tag.
b(valid_global_tag, ne);
stop("non global jobject using resolve_global_jobject");
bind(valid_global_tag);
}
#endif

// Resolve global handle
access_load_at(T_OBJECT, IN_NATIVE, Address(value, -JNIHandles::TypeTag::global), value, tmp1, tmp2, noreg);
verify_oop(value);

bind(done);
}

Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/arm/macroAssembler_arm.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -356,6 +356,7 @@ class MacroAssembler: public Assembler {
}

void resolve_jobject(Register value, Register tmp1, Register tmp2);
void resolve_global_jobject(Register value, Register tmp1, Register tmp2);

void nop() {
mov(R0, R0);
Expand Down
10 changes: 2 additions & 8 deletions src/hotspot/cpu/arm/stubGenerator_arm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -3053,13 +3053,7 @@ class StubGenerator: public StubCodeGenerator {
__ reset_last_Java_frame(Rtemp);

// R0 is jobject handle result, unpack and process it through a barrier.
Label L_null_jobject;
__ cbz(R0, L_null_jobject);

BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->load_at(masm, ACCESS_READ | IN_NATIVE, T_OBJECT, R0, Address(R0, 0), Rtemp, R1, R2);

__ bind(L_null_jobject);
__ resolve_global_jobject(R0, Rtemp, R1);

__ raw_pop(R1, R2, LR);
__ ret();
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -377,8 +377,8 @@ void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value
__ cmpdi(CCR0, value, 0);
__ beq(CCR0, done); // Use NULL as-is.

__ clrrdi(tmp1, value, JNIHandles::weak_tag_size);
__ andi_(tmp2, value, JNIHandles::weak_tag_mask);
__ clrrdi(tmp1, value, JNIHandles::tag_size);
__ andi_(tmp2, value, JNIHandles::TypeTag::weak_global);
__ ld(value, 0, tmp1); // Resolve (untagged) jobject.

__ beq(CCR0, not_weak); // Test for jweak tag.
Expand Down
58 changes: 46 additions & 12 deletions src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -115,31 +115,65 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value,
Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level) {
Label done, not_weak, verify;
Label done, tagged, weak_tagged, verify;
__ cmpdi(CCR0, value, 0);
__ beq(CCR0, done); // Use NULL as-is.

__ andi_(tmp1, value, JNIHandles::weak_tag_mask);
__ beq(CCR0, not_weak); // Test for jweak tag.
__ andi_(tmp1, value, JNIHandles::tag_mask);
__ bne(CCR0, tagged); // Test for tag.

// Resolve (untagged) jobject.
__ clrrdi(value, value, JNIHandles::weak_tag_size);
load_at(masm, IN_NATIVE | ON_PHANTOM_OOP_REF, T_OBJECT,
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
__ access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, // no uncoloring
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
__ b(verify);

__ bind(not_weak);
load_at(masm, IN_NATIVE, T_OBJECT,
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
__ bind(tagged);
__ andi_(tmp1, value, JNIHandles::TypeTag::weak_global);
__ clrrdi(value, value, JNIHandles::tag_size); // Untag.
__ bne(CCR0, weak_tagged); // Test for jweak tag.

__ access_load_at(T_OBJECT, IN_NATIVE,
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
__ b(verify);

__ bind(weak_tagged);
__ access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);

__ bind(verify);
__ verify_oop(value, FILE_AND_LINE);
__ bind(done);
}

// Generic implementation. GCs can provide an optimized one.
void BarrierSetAssembler::resolve_global_jobject(MacroAssembler* masm, Register value,
Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level) {
Label done;

__ cmpdi(CCR0, value, 0);
__ beq(CCR0, done); // Use NULL as-is.

#ifdef ASSERT
{
Label valid_global_tag;
__ andi_(tmp1, value, JNIHandles::TypeTag::global);
__ bne(CCR0, valid_global_tag); // Test for global tag.
__ stop("non global jobject using resolve_global_jobject");
__ bind(valid_global_tag);
}
#endif

__ clrrdi(value, value, JNIHandles::tag_size); // Untag.
__ access_load_at(T_OBJECT, IN_NATIVE,
value, (intptr_t)0, value, tmp1, tmp2, preservation_level);
__ verify_oop(value, FILE_AND_LINE);

__ bind(done);
}

void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
Register obj, Register tmp, Label& slowpath) {
__ clrrdi(dst, obj, JNIHandles::weak_tag_size);
__ clrrdi(dst, obj, JNIHandles::tag_size);
__ ld(dst, 0, dst); // Resolve (untagged) jobject.
}

Expand Down
5 changes: 4 additions & 1 deletion src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -56,6 +56,9 @@ class BarrierSetAssembler: public CHeapObj<mtGC> {
virtual void resolve_jobject(MacroAssembler* masm, Register value,
Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level);
virtual void resolve_global_jobject(MacroAssembler* masm, Register value,
Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level);

virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
Register obj, Register tmp, Label& slowpath);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -84,7 +84,7 @@ void ModRefBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register v
__ cmpdi(CCR0, value, 0);
__ beq(CCR0, done); // Use NULL as-is.

__ clrrdi(tmp1, value, JNIHandles::weak_tag_size);
__ clrrdi(tmp1, value, JNIHandles::tag_size);
__ ld(value, 0, tmp1); // Resolve (untagged) jobject.

__ verify_oop(value, FILE_AND_LINE);
Expand Down
Loading

1 comment on commit c705673

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.