Path: blob/master/src/hotspot/share/oops/accessDecorators.hpp
40951 views
/*1* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_OOPS_ACCESSDECORATORS_HPP25#define SHARE_OOPS_ACCESSDECORATORS_HPP2627#include "gc/shared/barrierSetConfig.hpp"28#include "memory/allocation.hpp"29#include "metaprogramming/integralConstant.hpp"30#include "utilities/globalDefinitions.hpp"3132// A decorator is an attribute or property that affects the way a memory access is performed in some way.33// There are different groups of decorators. Some have to do with memory ordering, others to do with,34// e.g. strength of references, strength of GC barriers, or whether compression should be applied or not.35// Some decorators are set at buildtime, such as whether primitives require GC barriers or not, others36// at callsites such as whether an access is in the heap or not, and others are resolved at runtime37// such as GC-specific barriers and encoding/decoding compressed oops.38typedef uint64_t DecoratorSet;3940// The HasDecorator trait can help at compile-time determining whether a decorator set41// has an intersection with a certain other decorator set42template <DecoratorSet decorators, DecoratorSet decorator>43struct HasDecorator: public IntegralConstant<bool, (decorators & decorator) != 0> {};4445// == General Decorators ==46// * DECORATORS_NONE: This is the name for the empty decorator set (in absence of other decorators).47const DecoratorSet DECORATORS_NONE = UCONST64(0);4849// == Internal Decorators - do not use ==50// * INTERNAL_CONVERT_COMPRESSED_OOPS: This is an oop access that will require converting an oop51// to a narrowOop or vice versa, if UseCompressedOops is known to be set.52// * INTERNAL_VALUE_IS_OOP: Remember that the involved access is on oop rather than primitive.53const DecoratorSet INTERNAL_CONVERT_COMPRESSED_OOP = UCONST64(1) << 1;54const DecoratorSet INTERNAL_VALUE_IS_OOP = UCONST64(1) << 2;5556// == Internal run-time Decorators ==57// * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved58// access backends iff UseCompressedOops is true.59const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS = UCONST64(1) << 5;6061const DecoratorSet INTERNAL_DECORATOR_MASK = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |62INTERNAL_RT_USE_COMPRESSED_OOPS;6364// == Memory Ordering Decorators ==65// The memory ordering decorators can be described in the following way:66// === Decorator Rules ===67// The different types of memory ordering guarantees have a strict order of strength.68// Explicitly specifying the stronger ordering implies that the guarantees of the weaker69// property holds too. The names come from the C++11 atomic operations, and typically70// have a JMM equivalent property.71// The equivalence may be viewed like this:72// MO_UNORDERED is equivalent to JMM plain.73// MO_RELAXED is equivalent to JMM opaque.74// MO_ACQUIRE is equivalent to JMM acquire.75// MO_RELEASE is equivalent to JMM release.76// MO_SEQ_CST is equivalent to JMM volatile.77//78// === Stores ===79// * MO_UNORDERED (Default): No guarantees.80// - The compiler and hardware are free to reorder aggressively. And they will.81// * MO_RELAXED: Relaxed atomic stores.82// - The stores are atomic.83// - The stores are not reordered by the compiler (but possibly the HW) w.r.t84// other ordered accesses in program order.85// - Also used for C++ volatile stores, since actual usage of volatile86// requires no word tearing.87// * MO_RELEASE: Releasing stores.88// - The releasing store will make its preceding memory accesses observable to memory accesses89// subsequent to an acquiring load observing this releasing store.90// - Guarantees from relaxed stores hold.91// * MO_SEQ_CST: Sequentially consistent stores.92// - The stores are observed in the same order by MO_SEQ_CST loads on other processors93// - Preceding loads and stores in program order are not reordered with subsequent loads and stores in program order.94// - Guarantees from releasing stores hold.95// === Loads ===96// * MO_UNORDERED (Default): No guarantees97// - The compiler and hardware are free to reorder aggressively. And they will.98// * MO_RELAXED: Relaxed atomic loads.99// - The loads are atomic.100// - The loads are not reordered by the compiler (but possibly the HW) w.r.t.101// other ordered accesses in program order.102// - Also used for C++ volatile loads, since actual usage of volatile103// requires no word tearing.104// * MO_ACQUIRE: Acquiring loads.105// - An acquiring load will make subsequent memory accesses observe the memory accesses106// preceding the releasing store that the acquiring load observed.107// - Guarantees from relaxed loads hold.108// * MO_SEQ_CST: Sequentially consistent loads.109// - These loads observe MO_SEQ_CST stores in the same order on other processors110// - Preceding loads and stores in program order are not reordered with subsequent loads and stores in program order.111// - Guarantees from acquiring loads hold.112// === Atomic Cmpxchg ===113// * MO_RELAXED: Atomic but relaxed cmpxchg.114// - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold unconditionally.115// * MO_SEQ_CST: Sequentially consistent cmpxchg.116// - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold unconditionally.117// === Atomic Xchg ===118// * MO_RELAXED: Atomic but relaxed atomic xchg.119// - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.120// * MO_SEQ_CST: Sequentially consistent xchg.121// - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.122const DecoratorSet MO_UNORDERED = UCONST64(1) << 6;123const DecoratorSet MO_RELAXED = UCONST64(1) << 7;124const DecoratorSet MO_ACQUIRE = UCONST64(1) << 8;125const DecoratorSet MO_RELEASE = UCONST64(1) << 9;126const DecoratorSet MO_SEQ_CST = UCONST64(1) << 10;127const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_RELAXED |128MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;129130// === Barrier Strength Decorators ===131// * AS_RAW: The access will translate into a raw memory access, hence ignoring all semantic concerns132// except memory ordering and compressed oops. This will bypass runtime function pointer dispatching133// in the pipeline and hardwire to raw accesses without going trough the GC access barriers.134// - Accesses on oop* translate to raw memory accesses without runtime checks135// - Accesses on narrowOop* translate to encoded/decoded memory accesses without runtime checks136// - Accesses on HeapWord* translate to a runtime check choosing one of the above137// - Accesses on other types translate to raw memory accesses without runtime checks138// * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects139// alive, regardless of the type of reference being accessed. It will however perform the memory access140// in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed,141// or maintain, e.g. intergenerational or interregional pointers if applicable. This should be used with142// extreme caution in isolated scopes.143// * AS_NORMAL: The accesses will be resolved to an accessor on the BarrierSet class, giving the144// responsibility of performing the access and what barriers to be performed to the GC. This is the default.145// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time146// decorator for enabling primitive barriers is enabled for the build.147const DecoratorSet AS_RAW = UCONST64(1) << 11;148const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 12;149const DecoratorSet AS_NORMAL = UCONST64(1) << 13;150const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMAL;151152// === Reference Strength Decorators ===153// These decorators only apply to accesses on oop-like types (oop/narrowOop).154// * ON_STRONG_OOP_REF: Memory access is performed on a strongly reachable reference.155// * ON_WEAK_OOP_REF: The memory access is performed on a weakly reachable reference.156// * ON_PHANTOM_OOP_REF: The memory access is performed on a phantomly reachable reference.157// This is the same ring of strength as jweak and weak oops in the VM.158// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.159// This could for example come from the unsafe API.160// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF161const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 14;162const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 15;163const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 16;164const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 17;165const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |166ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;167168// === Access Location ===169// Accesses can take place in, e.g. the heap, old or young generation, different native roots, or native memory off the heap.170// The location is important to the GC as it may imply different actions. The following decorators are used:171// * IN_HEAP: The access is performed in the heap. Many barriers such as card marking will172// be omitted if this decorator is not set.173// * IN_NATIVE: The access is performed in an off-heap data structure.174const DecoratorSet IN_HEAP = UCONST64(1) << 18;175const DecoratorSet IN_NATIVE = UCONST64(1) << 19;176const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE;177178// == Boolean Flag Decorators ==179// * IS_ARRAY: The access is performed on a heap allocated array. This is sometimes a special case180// for some GCs.181// * IS_DEST_UNINITIALIZED: This property can be important to e.g. SATB barriers by182// marking that the previous value is uninitialized nonsense rather than a real value.183// * IS_NOT_NULL: This property can make certain barriers faster such as compressing oops.184const DecoratorSet IS_ARRAY = UCONST64(1) << 20;185const DecoratorSet IS_DEST_UNINITIALIZED = UCONST64(1) << 21;186const DecoratorSet IS_NOT_NULL = UCONST64(1) << 22;187188// == Arraycopy Decorators ==189// * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source190// are not guaranteed to be subclasses of the class of the destination array. This requires191// a check-cast barrier during the copying operation. If this is not set, it is assumed192// that the array is covariant: (the source array type is-a destination array type)193// * ARRAYCOPY_DISJOINT: This property means that it is known that the two array ranges194// are disjoint.195// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.196// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.197// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.198const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 23;199const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 24;200const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 25;201const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 26;202const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 27;203const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |204ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |205ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;206207// == Resolve barrier decorators ==208// * ACCESS_READ: Indicate that the resolved object is accessed read-only. This allows the GC209// backend to use weaker and more efficient barriers.210// * ACCESS_WRITE: Indicate that the resolved object is used for write access.211const DecoratorSet ACCESS_READ = UCONST64(1) << 28;212const DecoratorSet ACCESS_WRITE = UCONST64(1) << 29;213214// Keep track of the last decorator.215const DecoratorSet DECORATOR_LAST = UCONST64(1) << 29;216217namespace AccessInternal {218// This class adds implied decorators that follow according to decorator rules.219// For example adding default reference strength and default memory ordering220// semantics.221template <DecoratorSet input_decorators>222struct DecoratorFixup: AllStatic {223// If no reference strength has been picked, then strong will be picked224static const DecoratorSet ref_strength_default = input_decorators |225(((ON_DECORATOR_MASK & input_decorators) == 0 && (INTERNAL_VALUE_IS_OOP & input_decorators) != 0) ?226ON_STRONG_OOP_REF : DECORATORS_NONE);227// If no memory ordering has been picked, unordered will be picked228static const DecoratorSet memory_ordering_default = ref_strength_default |229((MO_DECORATOR_MASK & ref_strength_default) == 0 ? MO_UNORDERED : DECORATORS_NONE);230// If no barrier strength has been picked, normal will be used231static const DecoratorSet barrier_strength_default = memory_ordering_default |232((AS_DECORATOR_MASK & memory_ordering_default) == 0 ? AS_NORMAL : DECORATORS_NONE);233static const DecoratorSet value = barrier_strength_default;234};235236// This function implements the above DecoratorFixup rules, but without meta237// programming for code generation that does not use templates.238inline DecoratorSet decorator_fixup(DecoratorSet input_decorators) {239// If no reference strength has been picked, then strong will be picked240DecoratorSet ref_strength_default = input_decorators |241(((ON_DECORATOR_MASK & input_decorators) == 0 && (INTERNAL_VALUE_IS_OOP & input_decorators) != 0) ?242ON_STRONG_OOP_REF : DECORATORS_NONE);243// If no memory ordering has been picked, unordered will be picked244DecoratorSet memory_ordering_default = ref_strength_default |245((MO_DECORATOR_MASK & ref_strength_default) == 0 ? MO_UNORDERED : DECORATORS_NONE);246// If no barrier strength has been picked, normal will be used247DecoratorSet barrier_strength_default = memory_ordering_default |248((AS_DECORATOR_MASK & memory_ordering_default) == 0 ? AS_NORMAL : DECORATORS_NONE);249return barrier_strength_default;250}251}252253#endif // SHARE_OOPS_ACCESSDECORATORS_HPP254255256