// Copyright 2019 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include 'src/builtins/builtins-regexp-gen.h' namespace internal_coverage { const kHasCoverageInfo: constexpr int31 generates 'DebugInfo::kHasCoverageInfo'; const kFirstSlotIndex: constexpr int31 generates 'CoverageInfo::kFirstSlotIndex'; const kSlotBlockCountIndex: constexpr int31 generates 'CoverageInfo::kSlotBlockCountIndex'; const kSlotIndexCountLog2: constexpr int31 generates 'CoverageInfo::kSlotIndexCountLog2'; const kSlotIndexCountMask: constexpr int31 generates 'CoverageInfo::kSlotIndexCountMask'; macro GetCoverageInfo(implicit context: Context)(function: JSFunction): CoverageInfo labels IfNoCoverageInfo { const shared: SharedFunctionInfo = function.shared_function_info; const debugInfo = Cast(shared.script_or_debug_info) otherwise goto IfNoCoverageInfo; if ((debugInfo.flags & kHasCoverageInfo) == 0) goto IfNoCoverageInfo; return UnsafeCast(debugInfo.coverage_info); } @export // Silence unused warning on release builds. SlotCount is only used // in an assert. TODO(szuend): Remove once macros and asserts work. macro SlotCount(coverageInfo: CoverageInfo): Smi { assert(kFirstSlotIndex == 0); // Otherwise we'd have to consider it below. assert(kFirstSlotIndex == (coverageInfo.length & kSlotIndexCountMask)); return coverageInfo.length >> kSlotIndexCountLog2; } macro FirstIndexForSlot(implicit context: Context)(slot: Smi): Smi { assert(kFirstSlotIndex == 0); // Otherwise we'd have to consider it below. return slot << kSlotIndexCountLog2; } macro IncrementBlockCount(implicit context: Context)( coverageInfo: CoverageInfo, slot: Smi) { assert(slot < SlotCount(coverageInfo)); const slotStart: Smi = FirstIndexForSlot(slot); const index: Smi = slotStart + kSlotBlockCountIndex; coverageInfo.objects[index] = UnsafeCast(coverageInfo.objects[index]) + 1; } builtin IncBlockCounter(implicit context: Context)( function: JSFunction, coverageArraySlotIndex: Smi): Object { // It's quite possible that a function contains IncBlockCounter bytecodes, // but no coverage info exists. This happens e.g. by selecting the // best-effort coverage collection mode, which triggers deletion of all // coverage infos in order to avoid memory leaks. const coverageInfo: CoverageInfo = GetCoverageInfo(function) otherwise return Undefined; IncrementBlockCount(coverageInfo, coverageArraySlotIndex); return Undefined; } } // namespace internal_coverage