8197454: Need Access decorator for storing oop into uninitialized location

Repurpose ARRAYCOPY_DEST_NOT_INITIALIZED to AS_DEST_NOT_INITIALIZED.

Reviewed-by: eosterlund, coleenp
This commit is contained in:
Kim Barrett 2018-02-13 17:36:22 -05:00
parent eb3ec99500
commit 023fc4b866
5 changed files with 28 additions and 27 deletions

View file

@ -30,7 +30,7 @@
template <DecoratorSet decorators, typename T> template <DecoratorSet decorators, typename T>
inline void G1SATBCardTableModRefBS::write_ref_field_pre(T* field) { inline void G1SATBCardTableModRefBS::write_ref_field_pre(T* field) {
if (HasDecorator<decorators, ARRAYCOPY_DEST_NOT_INITIALIZED>::value || if (HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value ||
HasDecorator<decorators, AS_NO_KEEPALIVE>::value) { HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
return; return;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -73,7 +73,7 @@ oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t
if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) { if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
// Optimized covariant case // Optimized covariant case
bs->write_ref_array_pre(dst, (int)length, bs->write_ref_array_pre(dst, (int)length,
HasDecorator<decorators, ARRAYCOPY_DEST_NOT_INITIALIZED>::value); HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value);
Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
bs->write_ref_array((HeapWord*)dst, length); bs->write_ref_array((HeapWord*)dst, length);
} else { } else {

View file

@ -155,6 +155,8 @@ const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
// - Accesses on narrowOop* translate to encoded/decoded memory accesses without runtime checks // - Accesses on narrowOop* translate to encoded/decoded memory accesses without runtime checks
// - Accesses on HeapWord* translate to a runtime check choosing one of the above // - Accesses on HeapWord* translate to a runtime check choosing one of the above
// - Accesses on other types translate to raw memory accesses without runtime checks // - Accesses on other types translate to raw memory accesses without runtime checks
// * AS_DEST_NOT_INITIALIZED: This property can be important to e.g. SATB barriers by
// marking that the previous value is uninitialized nonsense rather than a real value.
// * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects // * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects
// alive, regardless of the type of reference being accessed. It will however perform the memory access // alive, regardless of the type of reference being accessed. It will however perform the memory access
// in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed, // in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed,
@ -165,9 +167,11 @@ const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time // Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
// decorator for enabling primitive barriers is enabled for the build. // decorator for enabling primitive barriers is enabled for the build.
const DecoratorSet AS_RAW = UCONST64(1) << 11; const DecoratorSet AS_RAW = UCONST64(1) << 11;
const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 12; const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
const DecoratorSet AS_NORMAL = UCONST64(1) << 13; const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 13;
const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMAL; const DecoratorSet AS_NORMAL = UCONST64(1) << 14;
const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_DEST_NOT_INITIALIZED |
AS_NO_KEEPALIVE | AS_NORMAL;
// === Reference Strength Decorators === // === Reference Strength Decorators ===
// These decorators only apply to accesses on oop-like types (oop/narrowOop). // These decorators only apply to accesses on oop-like types (oop/narrowOop).
@ -178,10 +182,10 @@ const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMAL;
// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength. // * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
// This could for example come from the unsafe API. // This could for example come from the unsafe API.
// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF // * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 14; const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 15;
const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 15; const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 16;
const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 16; const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 17; const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF | const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF; ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
@ -196,23 +200,21 @@ const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
// * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap, // * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
// but is notably not scanned during safepoints. This is sometimes a special case for some GCs and // but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
// implies that it is also an IN_ROOT. // implies that it is also an IN_ROOT.
const DecoratorSet IN_HEAP = UCONST64(1) << 18; const DecoratorSet IN_HEAP = UCONST64(1) << 19;
const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 19; const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 20;
const DecoratorSet IN_ROOT = UCONST64(1) << 20; const DecoratorSet IN_ROOT = UCONST64(1) << 21;
const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 21; const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 22; const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 23;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY | const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
IN_ROOT | IN_CONCURRENT_ROOT | IN_ROOT | IN_CONCURRENT_ROOT |
IN_ARCHIVE_ROOT; IN_ARCHIVE_ROOT;
// == Value Decorators == // == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops. // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 23; const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 24;
const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL; const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// == Arraycopy Decorators == // == Arraycopy Decorators ==
// * ARRAYCOPY_DEST_NOT_INITIALIZED: This property can be important to e.g. SATB barriers by
// marking that the previous value uninitialized nonsense rather than a real value.
// * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source // * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source
// are not guaranteed to be subclasses of the class of the destination array. This requires // are not guaranteed to be subclasses of the class of the destination array. This requires
// a check-cast barrier during the copying operation. If this is not set, it is assumed // a check-cast barrier during the copying operation. If this is not set, it is assumed
@ -222,14 +224,12 @@ const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form. // * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements. // * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord. // * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
const DecoratorSet ARRAYCOPY_DEST_NOT_INITIALIZED = UCONST64(1) << 24;
const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 25; const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 25;
const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 26; const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 26;
const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 27; const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 27;
const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 28; const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 28;
const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 29; const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 29;
const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_DEST_NOT_INITIALIZED | const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF | ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED; ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@ -343,8 +343,8 @@ class Access: public AllStatic {
template <DecoratorSet expected_mo_decorators> template <DecoratorSet expected_mo_decorators>
static void verify_primitive_decorators() { static void verify_primitive_decorators() {
const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE) | IN_HEAP | const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |
IN_HEAP_ARRAY; IN_HEAP | IN_HEAP_ARRAY;
verify_decorators<expected_mo_decorators | primitive_decorators>(); verify_decorators<expected_mo_decorators | primitive_decorators>();
} }

View file

@ -1060,6 +1060,7 @@ void Access<decorators>::verify_decorators() {
const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK; const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;
STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set
(barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 || (barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||
(barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||
(barrier_strength_decorators ^ AS_RAW) == 0 || (barrier_strength_decorators ^ AS_RAW) == 0 ||
(barrier_strength_decorators ^ AS_NORMAL) == 0 (barrier_strength_decorators ^ AS_NORMAL) == 0
)); ));

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -418,7 +418,7 @@ JRT_LEAF(void, StubRoutines::oop_copy_uninit(oop* src, oop* dest, size_t count))
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT #endif // !PRODUCT
assert(count != 0, "count should be non-zero"); assert(count != 0, "count should be non-zero");
HeapAccess<ARRAYCOPY_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count); HeapAccess<AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count);
JRT_END JRT_END
JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count)) JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count))
@ -462,7 +462,7 @@ JRT_LEAF(void, StubRoutines::arrayof_oop_copy_uninit(HeapWord* src, HeapWord* de
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT #endif // !PRODUCT
assert(count != 0, "count should be non-zero"); assert(count != 0, "count should be non-zero");
HeapAccess<ARRAYCOPY_ARRAYOF | ARRAYCOPY_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, src, dest, count); HeapAccess<ARRAYCOPY_ARRAYOF | AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, src, dest, count);
JRT_END JRT_END
address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) { address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) {