/* * Copyright (C) 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WriteBarrierSupport_h #define WriteBarrierSupport_h #include "SamplingCounter.h" #include namespace JSC { // This allows the JIT to distinguish between uses of the barrier for different // kinds of writes. This is used by the JIT for profiling, and may be appropriate // for allowing the GC implementation to specialize the JIT's write barrier code // for different kinds of target objects. enum WriteBarrierUseKind { // This allows specialization for access to the property storage (either // array element or property), but not for any other kind of property // accesses (such as writes that are a consequence of setter execution). WriteBarrierForPropertyAccess, // This allows specialization for variable accesses (such as global or // scoped variables). WriteBarrierForVariableAccess, // This captures all other forms of write barriers. It should always be // correct to use a generic access write barrier, even when storing to // properties. Hence, if optimization is not necessary, it is preferable // to just use a generic access. WriteBarrierForGenericAccess }; class WriteBarrierCounters { private: WriteBarrierCounters() { } public: #if ENABLE(WRITE_BARRIER_PROFILING) static GlobalSamplingCounter usesWithBarrierFromCpp; static GlobalSamplingCounter usesWithoutBarrierFromCpp; static GlobalSamplingCounter usesWithBarrierFromJit; static GlobalSamplingCounter usesForPropertiesFromJit; static GlobalSamplingCounter usesForVariablesFromJit; static GlobalSamplingCounter usesWithoutBarrierFromJit; static void initialize(); static GlobalSamplingCounter& jitCounterFor(WriteBarrierUseKind useKind) { switch (useKind) { case WriteBarrierForPropertyAccess: return usesForPropertiesFromJit; case WriteBarrierForVariableAccess: return usesForVariablesFromJit; default: ASSERT(useKind == WriteBarrierForGenericAccess); return usesWithBarrierFromJit; } } #else // These are necessary to work around not having conditional exports. JS_EXPORTDATA static char usesWithBarrierFromCpp; JS_EXPORTDATA static char usesWithoutBarrierFromCpp; #endif // ENABLE(WRITE_BARRIER_PROFILING) static void countWriteBarrier() { #if ENABLE(WRITE_BARRIER_PROFILING) WriteBarrierCounters::usesWithBarrierFromCpp.count(); #endif } }; } // namespace JSC #endif // WriteBarrierSupport_h